Skip to content

Commit 8614f88

Browse files
committed
chore: copy memebrs from stdlibPatches to Predef and language
1 parent ae11597 commit 8614f88

File tree

2 files changed

+410
-29
lines changed

2 files changed

+410
-29
lines changed

library/src/scala/Predef.scala

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ package scala
1515
import scala.language.implicitConversions
1616

1717
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
1919
import scala.annotation.meta.{ companionClass, companionMethod }
20+
import scala.annotation.internal.RuntimeChecked
21+
import scala.compiletime.summonFrom
2022

2123
/** The `Predef` object provides definitions that are accessible in all Scala
2224
* compilation units without explicit qualification.
@@ -250,34 +252,11 @@ object Predef extends LowPriorityImplicits {
250252

251253
// assertions ---------------------------------------------------------
252254

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)
266257

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()
281260

282261
/** Tests an expression, throwing an `AssertionError` if false.
283262
* This method differs from assert only in the intent expressed:
@@ -370,7 +349,7 @@ object Predef extends LowPriorityImplicits {
370349
@inline def formatted(fmtstr: String): String = fmtstr format self
371350
}
372351

373-
/** Injects String concatenation operator `+` to any classes.
352+
/** Injects String concatenation operator `+` to any classes.
374353
* @group implicit-classes-any
375354
*/
376355
@(deprecated @companionMethod)("Implicit injection of + is deprecated. Convert to String to call +", "2.13.0")
@@ -508,6 +487,91 @@ object Predef extends LowPriorityImplicits {
508487
*/
509488
// $ to avoid accidental shadowing (e.g. scala/bug#7788)
510489
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+
511575
}
512576

513577
/** The `LowPriorityImplicits` class provides implicit values that

0 commit comments

Comments
 (0)