@@ -16,7 +16,7 @@ import scala.language.`2.13`
1616import scala .language .implicitConversions
1717
1818import scala .collection .{mutable , immutable , ArrayOps , StringOps }, immutable .WrappedString
19- import scala .annotation .{elidable , experimental , implicitNotFound }, elidable .ASSERTION
19+ import scala .annotation .{elidable , experimental , implicitNotFound , publicInBinary , targetName }, elidable .ASSERTION
2020import scala .annotation .meta .{ companionClass , companionMethod }
2121import scala .annotation .internal .{ RuntimeChecked }
2222import scala .compiletime .summonFrom
@@ -275,7 +275,26 @@ object Predef extends LowPriorityImplicits {
275275 */
276276 @ inline def locally [T ](@ deprecatedName(" x" ) x : T ): T = x
277277
278- // assertions ---------------------------------------------------------
278+ // ==============================================================================================
279+ // ========================================= ASSERTIONS =========================================
280+ // ==============================================================================================
281+
282+ /* In Scala 3, `assert` are methods that are `transparent` and `inline`.
283+ In Scala 2, `assert` are methods that are elidable, inlinable by the optimizer
284+ For scala 2 code to be able to run with the scala 3 library in the classpath
285+ (following our own compatibility policies), we will need the `assert` methods
286+ to be available at runtime.
287+ To achieve this, we keep the Scala 3 signature publicly available.
288+ We rely on the fact that it is `inline` and will not be visible in the bytecode.
289+ To add the required Scala 2 ones, we define the `scala2Assert`, we use:
290+ - `@targetName` to swap the name in the generated code to `assert`
291+ - `@publicInBinary` to make it available during runtime.
292+ As such, we would successfully hijack the definitions of `assert` such as:
293+ - At compile time, we would have the definitions of `assert`
294+ - At runtime, the definitions of `scala2Assert` as `assert`
295+ NOTE: Tasty-Reader in Scala 2 will have to learn about this swapping if we are to
296+ allow loading the full Scala 3 library by it.
297+ */
279298
280299 /** Tests an expression, throwing an `AssertionError` if false.
281300 * Calls to this method will not be generated if `-Xelide-below`
@@ -285,8 +304,8 @@ object Predef extends LowPriorityImplicits {
285304 * @param assertion the expression to test
286305 * @group assertions
287306 */
288- @ elidable(ASSERTION )
289- def assert (assertion : Boolean ): Unit = {
307+ @ elidable(ASSERTION ) @ publicInBinary
308+ @ targetName( " assert " ) private [scala] def scala2Assert (assertion : Boolean ): Unit = {
290309 if (! assertion)
291310 throw new java.lang.AssertionError (" assertion failed" )
292311 }
@@ -300,12 +319,22 @@ object Predef extends LowPriorityImplicits {
300319 * @param message a String to include in the failure message
301320 * @group assertions
302321 */
303- @ elidable(ASSERTION ) @ inline
304- final def assert (assertion : Boolean , message : => Any ): Unit = {
322+ @ elidable(ASSERTION ) @ inline @ publicInBinary
323+ @ targetName( " assert " ) private [scala] final def scala2Assert (assertion : Boolean , message : => Any ): Unit = {
305324 if (! assertion)
306325 throw new java.lang.AssertionError (" assertion failed: " + message)
307326 }
308327
328+ transparent inline def assert (inline assertion : Boolean , inline message : => Any ): Unit =
329+ if ! assertion then scala.runtime.Scala3RunTime .assertFailed(message)
330+
331+ transparent inline def assert (inline assertion : Boolean ): Unit =
332+ if ! assertion then scala.runtime.Scala3RunTime .assertFailed()
333+
334+ // ==============================================================================================
335+ // ======================================== ASSUMPTIONS =========================================
336+ // ==============================================================================================
337+
309338 /** Tests an expression, throwing an `AssertionError` if false.
310339 * This method differs from assert only in the intent expressed:
311340 * assert contains a predicate which needs to be proven, while
0 commit comments