@@ -15,8 +15,9 @@ 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 , publicInBinary , targetName , experimental }, elidable .ASSERTION
19
19
import scala .annotation .meta .{ companionClass , companionMethod }
20
+ import scala .annotation .internal .RuntimeChecked
20
21
21
22
/** The `Predef` object provides definitions that are accessible in all Scala
22
23
* compilation units without explicit qualification.
@@ -136,6 +137,24 @@ object Predef extends LowPriorityImplicits {
136
137
*/
137
138
@ inline def valueOf [T ](implicit vt : ValueOf [T ]): T = vt.value
138
139
140
+ /**
141
+ * Retrieve the single value of a type with a unique inhabitant.
142
+ *
143
+ * @example {{{
144
+ * object Foo
145
+ * val foo = valueOf[Foo.type]
146
+ * // foo is Foo.type = Foo
147
+ *
148
+ * val bar = valueOf[23]
149
+ * // bar is 23.type = 23
150
+ * }}}
151
+ * @group utilities
152
+ */
153
+ inline def valueOf [T ]: T = compiletime.summonFrom {
154
+ case ev : ValueOf [T ] => ev.value
155
+ }
156
+
157
+
139
158
/** The `String` type in Scala has all the methods of the underlying
140
159
* [[java.lang.String ]], of which it is just an alias.
141
160
*
@@ -217,6 +236,13 @@ object Predef extends LowPriorityImplicits {
217
236
*/
218
237
@ inline def implicitly [T ](implicit e : T ): T = e // TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero`
219
238
239
+ /** Summon a given value of type `T`. Usually, the argument is not passed explicitly.
240
+ *
241
+ * @tparam T the type of the value to be summoned
242
+ * @return the given value typed: the provided type parameter
243
+ */
244
+ transparent inline def summon [T ](using x : T ): x.type = x
245
+
220
246
/** Used to mark code blocks as being expressions, instead of being taken as part of anonymous classes and the like.
221
247
* This is just a different name for [[identity ]].
222
248
*
@@ -248,7 +274,9 @@ object Predef extends LowPriorityImplicits {
248
274
*/
249
275
@ inline def locally [T ](@ deprecatedName(" x" ) x : T ): T = x
250
276
251
- // assertions ---------------------------------------------------------
277
+ // ==============================================================================================
278
+ // ========================================= ASSERTIONS =========================================
279
+ // ==============================================================================================
252
280
253
281
/** Tests an expression, throwing an `AssertionError` if false.
254
282
* Calls to this method will not be generated if `-Xelide-below`
@@ -259,7 +287,8 @@ object Predef extends LowPriorityImplicits {
259
287
* @group assertions
260
288
*/
261
289
@ elidable(ASSERTION )
262
- def assert (assertion : Boolean ): Unit = {
290
+ @ targetName(" assert" ) @ publicInBinary
291
+ protected def oldAssert (assertion : Boolean ): Unit = {
263
292
if (! assertion)
264
293
throw new java.lang.AssertionError (" assertion failed" )
265
294
}
@@ -274,11 +303,22 @@ object Predef extends LowPriorityImplicits {
274
303
* @group assertions
275
304
*/
276
305
@ elidable(ASSERTION ) @ inline
277
- final def assert (assertion : Boolean , message : => Any ): Unit = {
306
+ @ targetName(" assert" ) @ publicInBinary
307
+ protected def oldAssert (assertion : Boolean , message : => Any ): Unit = {
278
308
if (! assertion)
279
309
throw new java.lang.AssertionError (" assertion failed: " + message)
280
310
}
281
311
312
+ transparent inline def assert (inline assertion : Boolean , inline message : => Any ): Unit =
313
+ if ! assertion then scala.runtime.Scala3RunTime .assertFailed(message)
314
+
315
+ transparent inline def assert (inline assertion : Boolean ): Unit =
316
+ if ! assertion then scala.runtime.Scala3RunTime .assertFailed()
317
+
318
+ // ==============================================================================================
319
+ // ========================================= ASSUMPTIONS ========================================
320
+ // ==============================================================================================
321
+
282
322
/** Tests an expression, throwing an `AssertionError` if false.
283
323
* This method differs from assert only in the intent expressed:
284
324
* assert contains a predicate which needs to be proven, while
@@ -370,7 +410,7 @@ object Predef extends LowPriorityImplicits {
370
410
@ inline def formatted (fmtstr : String ): String = fmtstr format self
371
411
}
372
412
373
- /** Injects String concatenation operator `+` to any classes.
413
+ /** Injects String concatenation operator `+` to any classes.
374
414
* @group implicit-classes-any
375
415
*/
376
416
@ (deprecated @ companionMethod)(" Implicit injection of + is deprecated. Convert to String to call +" , " 2.13.0" )
@@ -508,6 +548,67 @@ object Predef extends LowPriorityImplicits {
508
548
*/
509
549
// $ to avoid accidental shadowing (e.g. scala/bug#7788)
510
550
implicit def $conforms [A ]: A => A = <:< .refl
551
+
552
+ // Extension methods for working with explicit nulls
553
+
554
+ /** Strips away the nullability from a value. Note that `.nn` performs a checked cast,
555
+ * so if invoked on a `null` value it will throw an `NullPointerException`.
556
+ * @example {{{
557
+ * val s1: String | Null = "hello"
558
+ * val s2: String = s1.nn
559
+ *
560
+ * val s3: String | Null = null
561
+ * val s4: String = s3.nn // throw NullPointerException
562
+ * }}}
563
+ */
564
+ extension [T ](x : T | Null ) inline def nn : x.type & T =
565
+ if x.asInstanceOf [Any ] == null then scala.runtime.Scala3RunTime .nnFail()
566
+ x.asInstanceOf [x.type & T ]
567
+
568
+ extension (inline x : AnyRef | Null )
569
+ /** Enables an expression of type `T|Null`, where `T` is a subtype of `AnyRef`, to be checked for `null`
570
+ * using `eq` rather than only `==`. This is needed because `Null` no longer has
571
+ * `eq` or `ne` methods, only `==` and `!=` inherited from `Any`. */
572
+ inline def eq (inline y : AnyRef | Null ): Boolean =
573
+ x.asInstanceOf [AnyRef ] eq y.asInstanceOf [AnyRef ]
574
+ /** Enables an expression of type `T|Null`, where `T` is a subtype of `AnyRef`, to be checked for `null`
575
+ * using `ne` rather than only `!=`. This is needed because `Null` no longer has
576
+ * `eq` or `ne` methods, only `==` and `!=` inherited from `Any`. */
577
+ inline def ne (inline y : AnyRef | Null ): Boolean =
578
+ ! (x eq y)
579
+
580
+ extension (opt : Option .type )
581
+ @ experimental
582
+ inline def fromNullable [T ](t : T | Null ): Option [T ] = Option (t).asInstanceOf [Option [T ]]
583
+
584
+ /** A type supporting Self-based type classes.
585
+ *
586
+ * A is TC
587
+ *
588
+ * expands to
589
+ *
590
+ * TC { type Self = A }
591
+ *
592
+ * which is what is needed for a context bound `[A: TC]`.
593
+ */
594
+ @ experimental
595
+ infix type is [A <: AnyKind , B <: Any {type Self <: AnyKind }] = B { type Self = A }
596
+
597
+ extension [T ](x : T )
598
+ /** Asserts that a term should be exempt from static checks that can be reliably checked at runtime.
599
+ * @example {{{
600
+ * val xs: Option[Int] = Option(1)
601
+ * xs.runtimeChecked match
602
+ * case Some(x) => x // `Some(_)` can be checked at runtime, so no warning
603
+ * }}}
604
+ * @example {{{
605
+ * val xs: List[Int] = List(1,2,3)
606
+ * val y :: ys = xs.runtimeChecked // `_ :: _` can be checked at runtime, so no warning
607
+ * }}}
608
+ */
609
+ @ experimental
610
+ inline def runtimeChecked : x.type @ RuntimeChecked = x : @ RuntimeChecked
611
+
511
612
}
512
613
513
614
/** The `LowPriorityImplicits` class provides implicit values that
0 commit comments