@@ -15,8 +15,9 @@ package scala
1515import scala .language .implicitConversions
1616
1717import 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
1919import scala .annotation .meta .{ companionClass , companionMethod }
20+ import scala .annotation .internal .RuntimeChecked
2021
2122/** The `Predef` object provides definitions that are accessible in all Scala
2223 * compilation units without explicit qualification.
@@ -136,6 +137,24 @@ object Predef extends LowPriorityImplicits {
136137 */
137138 @ inline def valueOf [T ](implicit vt : ValueOf [T ]): T = vt.value
138139
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+
139158 /** The `String` type in Scala has all the methods of the underlying
140159 * [[java.lang.String ]], of which it is just an alias.
141160 *
@@ -217,6 +236,13 @@ object Predef extends LowPriorityImplicits {
217236 */
218237 @ 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`
219238
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+
220246 /** Used to mark code blocks as being expressions, instead of being taken as part of anonymous classes and the like.
221247 * This is just a different name for [[identity ]].
222248 *
@@ -248,7 +274,9 @@ object Predef extends LowPriorityImplicits {
248274 */
249275 @ inline def locally [T ](@ deprecatedName(" x" ) x : T ): T = x
250276
251- // assertions ---------------------------------------------------------
277+ // ==============================================================================================
278+ // ========================================= ASSERTIONS =========================================
279+ // ==============================================================================================
252280
253281 /** Tests an expression, throwing an `AssertionError` if false.
254282 * Calls to this method will not be generated if `-Xelide-below`
@@ -259,7 +287,8 @@ object Predef extends LowPriorityImplicits {
259287 * @group assertions
260288 */
261289 @ elidable(ASSERTION )
262- def assert (assertion : Boolean ): Unit = {
290+ @ targetName(" assert" ) @ publicInBinary
291+ protected def oldAssert (assertion : Boolean ): Unit = {
263292 if (! assertion)
264293 throw new java.lang.AssertionError (" assertion failed" )
265294 }
@@ -274,11 +303,22 @@ object Predef extends LowPriorityImplicits {
274303 * @group assertions
275304 */
276305 @ 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 = {
278308 if (! assertion)
279309 throw new java.lang.AssertionError (" assertion failed: " + message)
280310 }
281311
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+
282322 /** Tests an expression, throwing an `AssertionError` if false.
283323 * This method differs from assert only in the intent expressed:
284324 * assert contains a predicate which needs to be proven, while
@@ -370,7 +410,7 @@ object Predef extends LowPriorityImplicits {
370410 @ inline def formatted (fmtstr : String ): String = fmtstr format self
371411 }
372412
373- /** Injects String concatenation operator `+` to any classes.
413+ /** Injects String concatenation operator `+` to any classes.
374414 * @group implicit-classes-any
375415 */
376416 @ (deprecated @ companionMethod)(" Implicit injection of + is deprecated. Convert to String to call +" , " 2.13.0" )
@@ -508,6 +548,67 @@ object Predef extends LowPriorityImplicits {
508548 */
509549 // $ to avoid accidental shadowing (e.g. scala/bug#7788)
510550 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+
511612}
512613
513614/** The `LowPriorityImplicits` class provides implicit values that
0 commit comments