@@ -16,7 +16,7 @@ import scala.language.`2.13`
16
16
import scala .language .implicitConversions
17
17
18
18
import 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
20
20
import scala .annotation .meta .{ companionClass , companionMethod }
21
21
import scala .annotation .internal .{ RuntimeChecked }
22
22
import scala .compiletime .summonFrom
@@ -275,7 +275,26 @@ object Predef extends LowPriorityImplicits {
275
275
*/
276
276
@ inline def locally [T ](@ deprecatedName(" x" ) x : T ): T = x
277
277
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
+ */
279
298
280
299
/** Tests an expression, throwing an `AssertionError` if false.
281
300
* Calls to this method will not be generated if `-Xelide-below`
@@ -285,8 +304,8 @@ object Predef extends LowPriorityImplicits {
285
304
* @param assertion the expression to test
286
305
* @group assertions
287
306
*/
288
- @ elidable(ASSERTION )
289
- def assert (assertion : Boolean ): Unit = {
307
+ @ elidable(ASSERTION ) @ publicInBinary
308
+ @ targetName( " assert " ) private [scala] def scala2Assert (assertion : Boolean ): Unit = {
290
309
if (! assertion)
291
310
throw new java.lang.AssertionError (" assertion failed" )
292
311
}
@@ -300,12 +319,22 @@ object Predef extends LowPriorityImplicits {
300
319
* @param message a String to include in the failure message
301
320
* @group assertions
302
321
*/
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 = {
305
324
if (! assertion)
306
325
throw new java.lang.AssertionError (" assertion failed: " + message)
307
326
}
308
327
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
+
309
338
/** Tests an expression, throwing an `AssertionError` if false.
310
339
* This method differs from assert only in the intent expressed:
311
340
* assert contains a predicate which needs to be proven, while
0 commit comments