Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions library/src/scala/Enumeration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
private val vmap: mutable.Map[Int, Value] = new mutable.HashMap

/** The cache listing all values of this enumeration. */
@transient private var vset: ValueSet = null
@transient @annotation.stableNull private var vset: ValueSet | Null = null
@transient @volatile private var vsetDefined = false

/** The mapping from the integer used to identify values to their
Expand All @@ -121,7 +121,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
vset = (ValueSet.newBuilder ++= vmap.values).result()
vsetDefined = true
}
vset
vset.nn
}

/** The integer to use to identify the next created value. */
Expand All @@ -130,7 +130,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
/** The string to use to name the next created value. */
protected var nextName: Iterator[String] = _

private def nextNameOrNull =
private def nextNameOrNull: String | Null =
if (nextName != null && nextName.hasNext) nextName.next() else null

/** The highest integer amongst those used to identify values in this
Expand Down Expand Up @@ -177,7 +177,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
* @param name A human-readable name for that value.
* @return Fresh value called `name`.
*/
protected final def Value(name: String): Value = Value(nextId, name)
protected final def Value(name: String | Null): Value = Value(nextId, name)

/** Creates a fresh value, part of this enumeration, called `name`
* and identified by the integer `i`.
Expand All @@ -187,7 +187,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
* @param name A human-readable name for that value.
* @return Fresh value with the provided identifier `i` and name `name`.
*/
protected final def Value(i: Int, name: String): Value = new Val(i, name)
protected final def Value(i: Int, name: String | Null): Value = new Val(i, name)

private def populateNameMap(): Unit = {
@tailrec def getFields(clazz: Class[_], acc: Array[JField]): Array[JField] = {
Expand Down Expand Up @@ -248,7 +248,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
* identification behaviour.
*/
@SerialVersionUID(0 - 3501153230598116017L)
protected class Val(i: Int, name: String) extends Value with Serializable {
protected class Val(i: Int, name: String | Null) extends Value with Serializable {
def this(i: Int) = this(i, nextNameOrNull)
def this(name: String) = this(nextId, name)
def this() = this(nextId)
Expand Down
36 changes: 18 additions & 18 deletions library/src/scala/Predef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ object Predef extends LowPriorityImplicits {
* @return The runtime [[Class]] representation of type `T`.
* @group utilities
*/
def classOf[T]: Class[T] = null // This is a stub method. The actual implementation is filled in by the compiler.
def classOf[T]: Class[T] = null.asInstanceOf[Class[T]] // This is a stub method. The actual implementation is filled in by the compiler.

/**
* Retrieve the single value of a type with a unique inhabitant.
Expand Down Expand Up @@ -286,12 +286,12 @@ object Predef extends LowPriorityImplicits {
to be available at runtime.
To achieve this, we keep the Scala 3 signature publicly available.
We rely on the fact that it is `inline` and will not be visible in the bytecode.
To add the required Scala 2 ones, we define the `scala2Assert`, we use:
- `@targetName` to swap the name in the generated code to `assert`
To add the required Scala 2 ones, we define the `scala2Assert`, we use:
- `@targetName` to swap the name in the generated code to `assert`
- `@publicInBinary` to make it available during runtime.
As such, we would successfully hijack the definitions of `assert` such as:
- At compile time, we would have the definitions of `assert`
- At runtime, the definitions of `scala2Assert` as `assert`
- At runtime, the definitions of `scala2Assert` as `assert`
NOTE: Tasty-Reader in Scala 2 will have to learn about this swapping if we are to
allow loading the full Scala 3 library by it.
*/
Expand Down Expand Up @@ -426,7 +426,7 @@ object Predef extends LowPriorityImplicits {
@inline def formatted(fmtstr: String): String = fmtstr format self
}

/** Injects String concatenation operator `+` to any classes.
/** Injects String concatenation operator `+` to any classes.
* @group implicit-classes-any
*/
@(deprecated @companionMethod)("Implicit injection of + is deprecated. Convert to String to call +", "2.13.0")
Expand Down Expand Up @@ -658,46 +658,46 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2
@inline implicit def booleanWrapper(x: Boolean): runtime.RichBoolean = new runtime.RichBoolean(x)

/** @group conversions-array-to-wrapped-array */
implicit def genericWrapArray[T](xs: Array[T]): ArraySeq[T] =
implicit def genericWrapArray[T](xs: Array[T] | Null): ArraySeq[T] | Null =
if (xs eq null) null
else ArraySeq.make(xs)

// Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef]
// is as good as another for all T <: AnyRef. Instead of creating 100,000,000
// unique ones by way of this implicit, let's share one.
/** @group conversions-array-to-wrapped-array */
implicit def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq.ofRef[T] = {
implicit def wrapRefArray[T <: AnyRef](xs: Array[T] | Null): ArraySeq.ofRef[T] | Null = {
if (xs eq null) null
else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]]
else new ArraySeq.ofRef[T](xs)
}

/** @group conversions-array-to-wrapped-array */
implicit def wrapIntArray(xs: Array[Int]): ArraySeq.ofInt = if (xs ne null) new ArraySeq.ofInt(xs) else null
implicit def wrapIntArray(xs: Array[Int] | Null): ArraySeq.ofInt | Null = if (xs ne null) new ArraySeq.ofInt(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapDoubleArray(xs: Array[Double]): ArraySeq.ofDouble = if (xs ne null) new ArraySeq.ofDouble(xs) else null
implicit def wrapDoubleArray(xs: Array[Double] | Null): ArraySeq.ofDouble | Null = if (xs ne null) new ArraySeq.ofDouble(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapLongArray(xs: Array[Long]): ArraySeq.ofLong = if (xs ne null) new ArraySeq.ofLong(xs) else null
implicit def wrapLongArray(xs: Array[Long] | Null): ArraySeq.ofLong | Null = if (xs ne null) new ArraySeq.ofLong(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapFloatArray(xs: Array[Float]): ArraySeq.ofFloat = if (xs ne null) new ArraySeq.ofFloat(xs) else null
implicit def wrapFloatArray(xs: Array[Float] | Null): ArraySeq.ofFloat | Null = if (xs ne null) new ArraySeq.ofFloat(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapCharArray(xs: Array[Char]): ArraySeq.ofChar = if (xs ne null) new ArraySeq.ofChar(xs) else null
implicit def wrapCharArray(xs: Array[Char] | Null): ArraySeq.ofChar | Null = if (xs ne null) new ArraySeq.ofChar(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapByteArray(xs: Array[Byte]): ArraySeq.ofByte = if (xs ne null) new ArraySeq.ofByte(xs) else null
implicit def wrapByteArray(xs: Array[Byte] | Null): ArraySeq.ofByte | Null = if (xs ne null) new ArraySeq.ofByte(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapShortArray(xs: Array[Short]): ArraySeq.ofShort = if (xs ne null) new ArraySeq.ofShort(xs) else null
implicit def wrapShortArray(xs: Array[Short] | Null): ArraySeq.ofShort | Null = if (xs ne null) new ArraySeq.ofShort(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapBooleanArray(xs: Array[Boolean]): ArraySeq.ofBoolean = if (xs ne null) new ArraySeq.ofBoolean(xs) else null
implicit def wrapBooleanArray(xs: Array[Boolean] | Null): ArraySeq.ofBoolean | Null = if (xs ne null) new ArraySeq.ofBoolean(xs) else null
/** @group conversions-array-to-wrapped-array */
implicit def wrapUnitArray(xs: Array[Unit]): ArraySeq.ofUnit = if (xs ne null) new ArraySeq.ofUnit(xs) else null
implicit def wrapUnitArray(xs: Array[Unit] | Null): ArraySeq.ofUnit | Null = if (xs ne null) new ArraySeq.ofUnit(xs) else null

/** @group conversions-string */
implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null
implicit def wrapString(s: String | Null): WrappedString | Null = if (s ne null) new WrappedString(s) else null
}

private[scala] abstract class LowPriorityImplicits2 {
@deprecated("implicit conversions from Array to immutable.IndexedSeq are implemented by copying; use `toIndexedSeq` explicitly if you want to copy, or use the more efficient non-copying ArraySeq.unsafeWrapArray", since="2.13.0")
implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T]): IndexedSeq[T] =
implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T] | Null): IndexedSeq[T] | Null =
if (xs eq null) null
else new ArrayOps(xs).toIndexedSeq
}
22 changes: 11 additions & 11 deletions library/src/scala/Specializable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ object Specializable {
trait SpecializedGroup

// Smuggle a list of types by way of a tuple upon which Group is parameterized.
class Group[T >: Null](value: T) extends SpecializedGroup
class Group[T](value: T) extends SpecializedGroup

final val Primitives: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit)] = null
final val Everything: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef)] = null
final val Bits32AndUp: Group[(Int, Long, Float, Double)] = null
final val Integral: Group[(Byte, Short, Int, Long, Char)] = null
final val AllNumeric: Group[(Byte, Short, Int, Long, Char, Float, Double)] = null
final val BestOfBreed: Group[(Int, Double, Boolean, Unit, AnyRef)] = null
final val Unit: Group[Tuple1[Unit]] = null
final val Primitives: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit)] = null.asInstanceOf
final val Everything: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef)] = null.asInstanceOf
final val Bits32AndUp: Group[(Int, Long, Float, Double)] = null.asInstanceOf
final val Integral: Group[(Byte, Short, Int, Long, Char)] = null.asInstanceOf
final val AllNumeric: Group[(Byte, Short, Int, Long, Char, Float, Double)] = null.asInstanceOf
final val BestOfBreed: Group[(Int, Double, Boolean, Unit, AnyRef)] = null.asInstanceOf
final val Unit: Group[Tuple1[Unit]] = null.asInstanceOf

final val Arg: Group[(Int, Long, Float, Double)] = null
final val Args: Group[(Int, Long, Double)] = null
final val Return: Group[(Int, Long, Float, Double, Boolean, Unit)] = null
final val Arg: Group[(Int, Long, Float, Double)] = null.asInstanceOf
final val Args: Group[(Int, Long, Double)] = null.asInstanceOf
final val Return: Group[(Int, Long, Float, Double, Boolean, Unit)] = null.asInstanceOf
}
Loading
Loading