@@ -15,8 +15,10 @@ package scala
15
15
import scala .language .implicitConversions
16
16
17
17
import scala .collection .{mutable , immutable , ArrayOps , StringOps }, immutable .WrappedString
18
- import scala .annotation .{elidable , implicitNotFound }, elidable .ASSERTION
18
+ import scala .annotation .{elidable , implicitNotFound , experimental }, elidable .ASSERTION
19
19
import scala .annotation .meta .{ companionClass , companionMethod }
20
+ import scala .annotation .internal .RuntimeChecked
21
+ import scala .compiletime .summonFrom
20
22
21
23
/** The `Predef` object provides definitions that are accessible in all Scala
22
24
* compilation units without explicit qualification.
@@ -250,34 +252,11 @@ object Predef extends LowPriorityImplicits {
250
252
251
253
// assertions ---------------------------------------------------------
252
254
253
- /** Tests an expression, throwing an `AssertionError` if false.
254
- * Calls to this method will not be generated if `-Xelide-below`
255
- * is greater than `ASSERTION`.
256
- *
257
- * @see [[scala.annotation.elidable elidable ]]
258
- * @param assertion the expression to test
259
- * @group assertions
260
- */
261
- @ elidable(ASSERTION )
262
- def assert (assertion : Boolean ): Unit = {
263
- if (! assertion)
264
- throw new java.lang.AssertionError (" assertion failed" )
265
- }
255
+ transparent inline def assert (inline assertion : Boolean , inline message : => Any ): Unit =
256
+ if ! assertion then scala.runtime.Scala3RunTime .assertFailed(message)
266
257
267
- /** Tests an expression, throwing an `AssertionError` if false.
268
- * Calls to this method will not be generated if `-Xelide-below`
269
- * is greater than `ASSERTION`.
270
- *
271
- * @see [[scala.annotation.elidable elidable ]]
272
- * @param assertion the expression to test
273
- * @param message a String to include in the failure message
274
- * @group assertions
275
- */
276
- @ elidable(ASSERTION ) @ inline
277
- final def assert (assertion : Boolean , message : => Any ): Unit = {
278
- if (! assertion)
279
- throw new java.lang.AssertionError (" assertion failed: " + message)
280
- }
258
+ transparent inline def assert (inline assertion : Boolean ): Unit =
259
+ if ! assertion then scala.runtime.Scala3RunTime .assertFailed()
281
260
282
261
/** Tests an expression, throwing an `AssertionError` if false.
283
262
* This method differs from assert only in the intent expressed:
@@ -370,7 +349,7 @@ object Predef extends LowPriorityImplicits {
370
349
@ inline def formatted (fmtstr : String ): String = fmtstr format self
371
350
}
372
351
373
- /** Injects String concatenation operator `+` to any classes.
352
+ /** Injects String concatenation operator `+` to any classes.
374
353
* @group implicit-classes-any
375
354
*/
376
355
@ (deprecated @ companionMethod)(" Implicit injection of + is deprecated. Convert to String to call +" , " 2.13.0" )
@@ -508,6 +487,91 @@ object Predef extends LowPriorityImplicits {
508
487
*/
509
488
// $ to avoid accidental shadowing (e.g. scala/bug#7788)
510
489
implicit def $conforms [A ]: A => A = <:< .refl
490
+
491
+ /**
492
+ * Retrieve the single value of a type with a unique inhabitant.
493
+ *
494
+ * @example {{{
495
+ * object Foo
496
+ * val foo = valueOf[Foo.type]
497
+ * // foo is Foo.type = Foo
498
+ *
499
+ * val bar = valueOf[23]
500
+ * // bar is 23.type = 23
501
+ * }}}
502
+ * @group utilities
503
+ */
504
+ inline def valueOf [T ]: T = summonFrom {
505
+ case ev : ValueOf [T ] => ev.value
506
+ }
507
+
508
+ /** Summon a given value of type `T`. Usually, the argument is not passed explicitly.
509
+ *
510
+ * @tparam T the type of the value to be summoned
511
+ * @return the given value typed: the provided type parameter
512
+ */
513
+ transparent inline def summon [T ](using x : T ): x.type = x
514
+
515
+ // Extension methods for working with explicit nulls
516
+
517
+ /** Strips away the nullability from a value. Note that `.nn` performs a checked cast,
518
+ * so if invoked on a `null` value it will throw an `NullPointerException`.
519
+ * @example {{{
520
+ * val s1: String | Null = "hello"
521
+ * val s2: String = s1.nn
522
+ *
523
+ * val s3: String | Null = null
524
+ * val s4: String = s3.nn // throw NullPointerException
525
+ * }}}
526
+ */
527
+ extension [T ](x : T | Null ) inline def nn : x.type & T =
528
+ if x.asInstanceOf [Any ] == null then scala.runtime.Scala3RunTime .nnFail()
529
+ x.asInstanceOf [x.type & T ]
530
+
531
+ extension (inline x : AnyRef | Null )
532
+ /** Enables an expression of type `T|Null`, where `T` is a subtype of `AnyRef`, to be checked for `null`
533
+ * using `eq` rather than only `==`. This is needed because `Null` no longer has
534
+ * `eq` or `ne` methods, only `==` and `!=` inherited from `Any`. */
535
+ inline def eq (inline y : AnyRef | Null ): Boolean =
536
+ x.asInstanceOf [AnyRef ] eq y.asInstanceOf [AnyRef ]
537
+ /** Enables an expression of type `T|Null`, where `T` is a subtype of `AnyRef`, to be checked for `null`
538
+ * using `ne` rather than only `!=`. This is needed because `Null` no longer has
539
+ * `eq` or `ne` methods, only `==` and `!=` inherited from `Any`. */
540
+ inline def ne (inline y : AnyRef | Null ): Boolean =
541
+ ! (x eq y)
542
+
543
+ extension (opt : Option .type )
544
+ @ experimental
545
+ inline def fromNullable [T ](t : T | Null ): Option [T ] = Option (t).asInstanceOf [Option [T ]]
546
+
547
+ /** A type supporting Self-based type classes.
548
+ *
549
+ * A is TC
550
+ *
551
+ * expands to
552
+ *
553
+ * TC { type Self = A }
554
+ *
555
+ * which is what is needed for a context bound `[A: TC]`.
556
+ */
557
+ @ experimental
558
+ infix type is [A <: AnyKind , B <: Any {type Self <: AnyKind }] = B { type Self = A }
559
+
560
+ extension [T ](x : T )
561
+ /** Asserts that a term should be exempt from static checks that can be reliably checked at runtime.
562
+ * @example {{{
563
+ * val xs: Option[Int] = Option(1)
564
+ * xs.runtimeChecked match
565
+ * case Some(x) => x // `Some(_)` can be checked at runtime, so no warning
566
+ * }}}
567
+ * @example {{{
568
+ * val xs: List[Int] = List(1,2,3)
569
+ * val y :: ys = xs.runtimeChecked // `_ :: _` can be checked at runtime, so no warning
570
+ * }}}
571
+ */
572
+ @ experimental
573
+ inline def runtimeChecked : x.type @ RuntimeChecked = x : @ RuntimeChecked
574
+
511
575
}
512
576
513
577
/** The `LowPriorityImplicits` class provides implicit values that
0 commit comments