diff --git a/library/src/scala/Array.scala b/library/src/scala/Array.scala index bb23b79eb1a4..e712da22f123 100644 --- a/library/src/scala/Array.scala +++ b/library/src/scala/Array.scala @@ -586,7 +586,7 @@ object Array { def get: UnapplySeqWrapper[T] = this def lengthCompare(len: Int): Int = a.lengthCompare(len) def apply(i: Int): T = a(i) - def drop(n: Int): scala.Seq[T] = ArraySeq.unsafeWrapArray(a.drop(n)) // clones the array, also if n == 0 + def drop(n: Int): scala.Seq[T] = ArraySeq.unsafeWrapArray(a.drop(n)).nn // clones the array, also if n == 0 def toSeq: scala.Seq[T] = a.toSeq // clones the array } } diff --git a/library/src/scala/Enumeration.scala b/library/src/scala/Enumeration.scala index b527fd3fc2fb..f4fdd1716862 100644 --- a/library/src/scala/Enumeration.scala +++ b/library/src/scala/Enumeration.scala @@ -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 @@ -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. */ @@ -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 @@ -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`. @@ -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] = { @@ -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) diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 281d1ef78a89..128f2732772e 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -332,19 +332,19 @@ object IArray: // For backwards compatibility with code compiled without -Yexplicit-nulls private inline def mapNull[A, B](a: A, inline f: B): B = - if((a: A|Null) == null) null.asInstanceOf[B] else f + if((a: A | Null) == null) null.asInstanceOf[B] else f /** Conversion from IArray to immutable.ArraySeq */ implicit def genericWrapArray[T](arr: IArray[T]): ArraySeq[T] = - mapNull(arr, ArraySeq.unsafeWrapArray(arr)) + mapNull(arr, ArraySeq.unsafeWrapArray(arr)).asInstanceOf[ArraySeq[T]] /** Conversion from IArray to immutable.ArraySeq */ - implicit def wrapRefArray[T <: AnyRef](arr: IArray[T]): ArraySeq.ofRef[T] = - // 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 + implicit def wrapRefArray[T <: AnyRef | Null](arr: IArray[T]): ArraySeq.ofRef[T] = + // Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef | Null] + // is as good as another for all T <: AnyRef | Null. Instead of creating 100,000,000 // unique ones by way of this implicit, let's share one. mapNull(arr, - if (arr.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]] + if (arr.length == 0) ArraySeq.empty[AnyRef | Null].asInstanceOf[ArraySeq.ofRef[T]] else ArraySeq.ofRef(arr.asInstanceOf[Array[T]]) ) diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index 7e2c2f09666b..8c38399a319b 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -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. @@ -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. */ @@ -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") @@ -657,47 +657,49 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2 @inline implicit def doubleWrapper(x: Double): runtime.RichDouble = new runtime.RichDouble(x) @inline implicit def booleanWrapper(x: Boolean): runtime.RichBoolean = new runtime.RichBoolean(x) + // For backwards compatibility with code compiled without -Yexplicit-nulls + private inline def mapNull[A, B](a: A, inline f: B): B = + if((a: A | Null) == null) null.asInstanceOf[B] else f + /** @group conversions-array-to-wrapped-array */ implicit def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = - if (xs eq null) null - else ArraySeq.make(xs) + mapNull(xs, 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] = { - if (xs eq null) null - else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]] - else new ArraySeq.ofRef[T](xs) - } + implicit def wrapRefArray[T <: AnyRef | Null](xs: Array[T]): ArraySeq.ofRef[T] = + mapNull(xs, + 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]): ArraySeq.ofInt = mapNull(xs, new ArraySeq.ofInt(xs)) /** @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]): ArraySeq.ofDouble = mapNull(xs, new ArraySeq.ofDouble(xs)) /** @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]): ArraySeq.ofLong = mapNull(xs, new ArraySeq.ofLong(xs)) /** @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]): ArraySeq.ofFloat = mapNull(xs, new ArraySeq.ofFloat(xs)) /** @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]): ArraySeq.ofChar = mapNull(xs, new ArraySeq.ofChar(xs)) /** @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]): ArraySeq.ofByte = mapNull(xs, new ArraySeq.ofByte(xs)) /** @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]): ArraySeq.ofShort = mapNull(xs, new ArraySeq.ofShort(xs)) /** @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]): ArraySeq.ofBoolean = mapNull(xs, new ArraySeq.ofBoolean(xs)) /** @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]): ArraySeq.ofUnit = mapNull(xs, new ArraySeq.ofUnit(xs)) /** @group conversions-string */ - implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null + implicit def wrapString(s: String): WrappedString = mapNull(s, new WrappedString(s)) } 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] = - if (xs eq null) null + if (xs eq null) null.asInstanceOf[IndexedSeq[T]] else new ArrayOps(xs).toIndexedSeq } diff --git a/library/src/scala/Specializable.scala b/library/src/scala/Specializable.scala index 51822f9f6446..1d885ff50bb6 100644 --- a/library/src/scala/Specializable.scala +++ b/library/src/scala/Specializable.scala @@ -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 } diff --git a/library/src/scala/StringContext.scala b/library/src/scala/StringContext.scala index ab07a50d6e01..992c8fc3f639 100644 --- a/library/src/scala/StringContext.scala +++ b/library/src/scala/StringContext.scala @@ -293,7 +293,7 @@ object StringContext { // Matched all of pattern to all of name. Success. Some(collection.immutable.ArraySeq.unsafeWrapArray( Array.tabulate(patternChunks.length - 1)(n => input.slice(matchStarts(n), matchEnds(n))) - )) + ).nn) } /** An exception that is thrown if a string contains a backslash (`\`) character @@ -475,3 +475,4 @@ object StringContext { +") for interpolated string with "+ parts.length +" parts") } + diff --git a/library/src/scala/Symbol.scala b/library/src/scala/Symbol.scala index f865f2ce4262..922082cc0f62 100644 --- a/library/src/scala/Symbol.scala +++ b/library/src/scala/Symbol.scala @@ -36,7 +36,7 @@ object Symbol extends UniquenessCache[String, Symbol] { /** This is private so it won't appear in the library API, but * abstracted to offer some hope of reusability. */ -private[scala] abstract class UniquenessCache[K, V >: Null] { +private[scala] abstract class UniquenessCache[K, V] { import java.lang.ref.WeakReference import java.util.WeakHashMap import java.util.concurrent.locks.ReentrantReadWriteLock @@ -50,7 +50,7 @@ private[scala] abstract class UniquenessCache[K, V >: Null] { protected def keyFromValue(v: V): Option[K] def apply(name: K): V = { - def cached(): V = { + def cached(): V | Null = { rlock.lock try { val reference = map get name diff --git a/library/src/scala/collection/ArrayOps.scala b/library/src/scala/collection/ArrayOps.scala index 40570e5c261b..91a663443647 100644 --- a/library/src/scala/collection/ArrayOps.scala +++ b/library/src/scala/collection/ArrayOps.scala @@ -60,7 +60,7 @@ object ArrayOps { private class ArrayView[A](xs: Array[A]) extends AbstractIndexedSeqView[A] { def length = xs.length def apply(n: Int) = xs(n) - override def toString: String = immutable.ArraySeq.unsafeWrapArray(xs).mkString("ArrayView(", ", ", ")") + override def toString: String = immutable.ArraySeq.unsafeWrapArray(xs).nn.mkString("ArrayView(", ", ", ")") } /** A lazy filtered array. No filtering is applied until one of `foreach`, `map` or `flatMap` is called. */ @@ -429,7 +429,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { val s = (shape.shape: @unchecked) match { case StepperShape.ReferenceShape => (xs: Any) match { case bs: Array[Boolean] => new BoxedBooleanArrayStepper(bs, 0, xs.length) - case _ => new ObjectArrayStepper[AnyRef](xs.asInstanceOf[Array[AnyRef ]], 0, xs.length) + case _ => new ObjectArrayStepper[AnyRef](xs.asInstanceOf[Array[AnyRef]], 0, xs.length) } case StepperShape.IntShape => new IntArrayStepper (xs.asInstanceOf[Array[Int ]], 0, xs.length) case StepperShape.LongShape => new LongArrayStepper (xs.asInstanceOf[Array[Long ]], 0, xs.length) @@ -1084,7 +1084,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * @return a decorator `LazyZip2` that allows strict operations to be performed on the lazily evaluated pairs * or chained calls to `lazyZip`. Implicit conversion to `Iterable[(A, B)]` is also supported. */ - def lazyZip[B](that: Iterable[B]^): LazyZip2[A, B, Array[A]]^{that} = new LazyZip2(xs, immutable.ArraySeq.unsafeWrapArray(xs), that) + def lazyZip[B](that: Iterable[B]^): LazyZip2[A, B, Array[A]]^{that} = new LazyZip2(xs, immutable.ArraySeq.unsafeWrapArray(xs).nn, that) /** Returns an array formed from this array and another iterable collection * by combining corresponding elements in pairs. @@ -1438,7 +1438,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { @`inline` final def toSeq: immutable.Seq[A] = toIndexedSeq def toIndexedSeq: immutable.IndexedSeq[A] = - immutable.ArraySeq.unsafeWrapArray(Array.copyOf(xs, xs.length)) + immutable.ArraySeq.unsafeWrapArray(Array.copyOf(xs, xs.length)).nn /** Copy elements of this array to another array. * Fills the given array `xs` starting at index 0. diff --git a/library/src/scala/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 6a6132990f76..173f7554dec4 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -125,7 +125,6 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite private[this] var hd: A = _ private[this] var hdDefined: Boolean = false - def head: A = { if (!hdDefined) { hd = next() @@ -162,12 +161,12 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite require(size >= 1 && step >= 1, f"size=$size%d and step=$step%d, but both must be positive") - private[this] var buffer: Array[B] = null // current result - private[this] var prev: Array[B] = null // if sliding, overlap from previous result + private[this] var buffer: Array[B] | Null = null // current result + private[this] var prev: Array[B] | Null = null // if sliding, overlap from previous result private[this] var first = true // if !first, advancing may skip ahead private[this] var filled = false // whether the buffer is "hot" private[this] var partial = true // whether to emit partial sequence - private[this] var padding: () -> B = null // what to pad short sequences with + private[this] var padding: (() -> B) | Null = null // what to pad short sequences with private[this] def pad = padding != null // irrespective of partial flag private[this] def newBuilder = { val b = ArrayBuilder.make[Any] @@ -190,7 +189,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite * @note This method is mutually exclusive with `withPartial`. * @group Configuration */ - def withPadding(x: -> B): this.type = { + def withPadding(x: => B): this.type = { padding = () => x partial = true // redundant, as padding always results in complete segment this @@ -231,7 +230,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite val builder = newBuilder var done = false // keep prefix of previous buffer if stepping - if (prev != null) builder.addAll(prev) + if (prev != null) builder.addAll(prev.nn) // skip ahead if (!first && step > size) { var dropping = step - size @@ -252,7 +251,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite if (index < size && pad) { builder.sizeHint(size) while (index < size) { - builder.addOne(padding()) + builder.addOne(padding.nn()) index += 1 } } @@ -276,11 +275,11 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite filled = false // if stepping, retain overlap in prev if (step < size) { - if (first) prev = buffer.drop(step) - else if (buffer.length == size) Array.copy(src = buffer, srcPos = step, dest = prev, destPos = 0, length = size - step) + if (first) prev = buffer.nn.drop(step) + else if (buffer.nn.length == size) Array.copy(src = buffer.nn, srcPos = step, dest = prev.nn, destPos = 0, length = size - step) else prev = null } - val res = immutable.ArraySeq.unsafeWrapArray(buffer).asInstanceOf[immutable.ArraySeq[B]] + val res = immutable.ArraySeq.unsafeWrapArray(buffer.nn).asInstanceOf[immutable.ArraySeq[B]] buffer = null first = false res @@ -418,7 +417,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite @deprecated("Call scanRight on an Iterable instead.", "2.13.0") def scanRight[B](z: B)(op: (A, B) => B): Iterator[B]^{this, op} = ArrayBuffer.from(this).scanRight(z)(op).iterator - + /** Finds index of the first element satisfying some predicate after or at some start index. * * $mayNotTerminateInf @@ -494,9 +493,9 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite while (p(hd) == isFlipped) { if (!self.hasNext) return false hd = self.next() - } + } hdDefined = true - true + true } def next() = @@ -703,7 +702,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite * handling of structural calls. It's not what's intended here. */ final class Leading extends AbstractIterator[A] { - private[this] var lookahead: mutable.Queue[A] = null + private[this] var lookahead: mutable.Queue[A] | Null = null private[this] var hd: A = _ /* Status is kept with magic numbers * 1 means next element is in hd and we're still reading into this iterator @@ -714,10 +713,10 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite private[this] var status = 0 private def store(a: A): Unit = { if (lookahead == null) lookahead = new mutable.Queue[A] - lookahead += a + lookahead.nn += a } def hasNext = { - if (status < 0) (lookahead ne null) && lookahead.nonEmpty + if (status < 0) (lookahead ne null) && lookahead.nn.nonEmpty else if (status > 0) true else { if (self.hasNext) { @@ -731,7 +730,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite def next() = { if (hasNext) { if (status == 1) { status = 0; hd } - else lookahead.dequeue() + else lookahead.nn.dequeue() } else Iterator.empty.next() } @@ -758,7 +757,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite val leading = new Leading val trailing = new AbstractIterator[A] { - private[this] var myLeading = leading + private[this] var myLeading: Leading | Null = leading /* Status flag meanings: * -1 not yet accessed * 0 single element waiting in leading @@ -773,13 +772,13 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite case 1 => if (self.hasNext) { status = 2 ; true } else { status = 3 ; false } case 0 => true case _ => - if (myLeading.finish()) { status = 0 ; true } else { status = 1 ; myLeading = null ; hasNext } + if (myLeading.nn.finish()) { status = 0 ; true } else { status = 1 ; myLeading = null ; hasNext } } def next() = { if (hasNext) { if (status == 0) { status = 1 - val res = myLeading.trailer + val res = myLeading.nn.trailer myLeading = null res } else { @@ -874,7 +873,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite */ def duplicate: (Iterator[A]^{this}, Iterator[A]^{this}) = { val gap = new scala.collection.mutable.Queue[A] - var ahead: Iterator[A] = null + var ahead: Iterator[A] | Null = null class Partner extends AbstractIterator[A] { override def knownSize: Int = self.synchronized { val thisSize = self.knownSize @@ -1150,10 +1149,13 @@ object Iterator extends IterableFactory[Iterator] { /** Creates an iterator to which other iterators can be appended efficiently. * Nested ConcatIterators are merged to avoid blowing the stack. */ - private final class ConcatIterator[+A](val from: Iterator[A @uncheckedVariance]^) extends AbstractIterator[A] { - private var current: Iterator[A]^{from} = from - private var tail: ConcatIteratorCell[A @uncheckedVariance] = null - private var last: ConcatIteratorCell[A @uncheckedVariance] = null + private final class ConcatIterator[+A](val from: (Iterator[A @uncheckedVariance]^) | Null) extends AbstractIterator[A] { + @annotation.stableNull + private var current: Iterator[A]^{from} | Null = from + @annotation.stableNull + private var tail: ConcatIteratorCell[A @uncheckedVariance] | Null = null + @annotation.stableNull + private var last: ConcatIteratorCell[A @uncheckedVariance] | Null = null private var currentHasNextChecked = false def hasNext = @@ -1172,7 +1174,7 @@ object Iterator extends IterableFactory[Iterator] { currentHasNextChecked = c.currentHasNextChecked if (c.tail != null) { if (last == null) last = c.last - c.last.tail = tail + c.last.nn.tail = tail tail = c.tail } merge() @@ -1187,9 +1189,9 @@ object Iterator extends IterableFactory[Iterator] { false } else { - current = tail.headIterator - if (last eq tail) last = last.tail - tail = tail.tail + current = tail.nn.headIterator + if (last eq tail) last = last.nn.tail + tail = tail.nn.tail merge() if (currentHasNextChecked) true else if (current != null && current.hasNext) { @@ -1204,7 +1206,7 @@ object Iterator extends IterableFactory[Iterator] { def next() = if (hasNext) { currentHasNextChecked = false - current.next() + current.nn.next() } else Iterator.empty.next() override def concat[B >: A](that: => IterableOnce[B]^): Iterator[B]^{this, that} = { @@ -1214,7 +1216,7 @@ object Iterator extends IterableFactory[Iterator] { last = c } else { - last.tail = c + last.nn.tail = c last = c } if (current == null) current = Iterator.empty @@ -1222,7 +1224,7 @@ object Iterator extends IterableFactory[Iterator] { } } - private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^, var tail: ConcatIteratorCell[A]^) { + private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^, var tail: (ConcatIteratorCell[A]^) | Null) { def headIterator: Iterator[A]^{this} = head.iterator } @@ -1290,7 +1292,7 @@ object Iterator extends IterableFactory[Iterator] { */ private final class UnfoldIterator[A, S](init: S)(f: S => Option[(A, S)]) extends AbstractIterator[A] { private[this] var state: S = init - private[this] var nextResult: Option[(A, S)] = null + private[this] var nextResult: Option[(A, S)] | Null = null override def hasNext: Boolean = { if (nextResult eq null) { @@ -1301,12 +1303,12 @@ object Iterator extends IterableFactory[Iterator] { } state = null.asInstanceOf[S] // allow GC } - nextResult.isDefined + nextResult.nn.isDefined } override def next(): A = { if (hasNext) { - val (value, newState) = nextResult.get + val (value, newState) = nextResult.nn.get state = newState nextResult = null value diff --git a/library/src/scala/collection/JavaConverters.scala b/library/src/scala/collection/JavaConverters.scala index 8d1503200188..ede74707f250 100644 --- a/library/src/scala/collection/JavaConverters.scala +++ b/library/src/scala/collection/JavaConverters.scala @@ -81,65 +81,64 @@ import scala.language.implicitConversions @deprecated("Use `scala.jdk.CollectionConverters` instead", "2.13.0") object JavaConverters extends AsJavaConverters with AsScalaConverters { @deprecated("Use `asJava` instead", "2.13.0") - def asJavaIterator[A](i: Iterator[A]): ju.Iterator[A] = asJava(i) + def asJavaIterator[A](i: Iterator[A] | Null): ju.Iterator[A] | Null = asJava(i) @deprecated("Use `asJava` instead", "2.13.0") - def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = asJava(i) + def asJavaIterable[A](i: Iterable[A] | Null): jl.Iterable[A] | Null = asJava(i) @deprecated("Use `asJava` instead", "2.13.0") - def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = asJava(b) + def bufferAsJavaList[A](b: mutable.Buffer[A] | Null): ju.List[A] | Null = asJava(b) @deprecated("Use `asJava` instead", "2.13.0") - def mutableSeqAsJavaList[A](s: mutable.Seq[A]): ju.List[A] = asJava(s) + def mutableSeqAsJavaList[A](s: mutable.Seq[A] | Null): ju.List[A] | Null = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def seqAsJavaList[A](s: Seq[A]): ju.List[A] = asJava(s) + def seqAsJavaList[A](s: Seq[A] | Null): ju.List[A] | Null = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = asJava(s) + def mutableSetAsJavaSet[A](s: mutable.Set[A] | Null): ju.Set[A] | Null = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def setAsJavaSet[A](s: Set[A]): ju.Set[A] = asJava(s) + def setAsJavaSet[A](s: Set[A] | Null): ju.Set[A] | Null = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def mutableMapAsJavaMap[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = asJava(m) + def mutableMapAsJavaMap[K, V](m: mutable.Map[K, V] | Null): ju.Map[K, V] | Null = asJava(m) @deprecated("Use `asJava` instead", "2.13.0") - def mapAsJavaMap[K, V](m: Map[K, V]): ju.Map[K, V] = asJava(m) + def mapAsJavaMap[K, V](m: Map[K, V] | Null): ju.Map[K, V] | Null = asJava(m) @deprecated("Use `asJava` instead", "2.13.0") - def mapAsJavaConcurrentMap[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = asJava(m) - + def mapAsJavaConcurrentMap[K, V](m: concurrent.Map[K, V] | Null): juc.ConcurrentMap[K, V] | Null = asJava(m) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaIterator[A](i: ju.Iterator[A]): Iterator[A] = asScala(i) + def asScalaIterator[A](i: ju.Iterator[A] | Null): Iterator[A] | Null = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = asScala(i) + def enumerationAsScalaIterator[A](i: ju.Enumeration[A] | Null): Iterator[A] | Null = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = asScala(i) + def iterableAsScalaIterable[A](i: jl.Iterable[A] | Null): Iterable[A] | Null = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = asScala(i) + def collectionAsScalaIterable[A](i: ju.Collection[A] | Null): Iterable[A] | Null = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = asScala(l) + def asScalaBuffer[A](s: ju.List[A] | Null): mutable.Buffer[A] | Null = asScala(s) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = asScala(s) + def asScalaSet[A](s: ju.Set[A] | Null): mutable.Set[A] | Null = asScala(s) @deprecated("Use `asScala` instead", "2.13.0") - def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = asScala(m) + def mapAsScalaMap[A, B](m: ju.Map[A, B] | Null): mutable.Map[A, B] | Null = asScala(m) @deprecated("Use `asScala` instead", "2.13.0") - def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = asScala(m) + def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B] | Null): concurrent.Map[A, B] | Null = asScala(m) @deprecated("Use `asScala` instead", "2.13.0") - def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = asScala(p) + def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B] | Null): mutable.Map[A, B] | Null = asScala(p) @deprecated("Use `asScala` instead", "2.13.0") - def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = asScala(p) + def propertiesAsScalaMap(p: ju.Properties | Null): mutable.Map[String, String] | Null = asScala(p) // Deprecated implicit conversions for code that directly imports them @@ -147,91 +146,91 @@ object JavaConverters extends AsJavaConverters with AsScalaConverters { * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a Java `Iterator`. * @see [[asJavaIterator]] */ - implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] = + implicit def asJavaIteratorConverter[A](i : Iterator[A] | Null): AsJava[ju.Iterator[A]] = new AsJava(asJavaIterator(i)) /** * Adds an `asJavaEnumeration` method that implicitly converts a Scala `Iterator` to a Java `Enumeration`. * @see [[asJavaEnumeration]] */ - implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] = + implicit def asJavaEnumerationConverter[A](i : Iterator[A] | Null): AsJavaEnumeration[A] = new AsJavaEnumeration(i) /** * Adds an `asJava` method that implicitly converts a Scala `Iterable` to a Java `Iterable`. * @see [[asJavaIterable]] */ - implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] = + implicit def asJavaIterableConverter[A](i : Iterable[A] | Null): AsJava[jl.Iterable[A]] = new AsJava(asJavaIterable(i)) /** * Adds an `asJavaCollection` method that implicitly converts a Scala `Iterable` to an immutable Java `Collection`. * @see [[asJavaCollection]] */ - implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] = + implicit def asJavaCollectionConverter[A](i : Iterable[A] | Null): AsJavaCollection[A] = new AsJavaCollection(i) /** * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer` to a Java `List`. * @see [[bufferAsJavaList]] */ - implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] = + implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A] | Null): AsJava[ju.List[A]] = new AsJava(bufferAsJavaList(b)) /** * Adds an `asJava` method that implicitly converts a Scala mutable `Seq` to a Java `List`. * @see [[mutableSeqAsJavaList]] */ - implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] = + implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A] | Null): AsJava[ju.List[A]] = new AsJava(mutableSeqAsJavaList(b)) /** * Adds an `asJava` method that implicitly converts a Scala `Seq` to a Java `List`. * @see [[seqAsJavaList]] */ - implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] = + implicit def seqAsJavaListConverter[A](b : Seq[A] | Null): AsJava[ju.List[A]] = new AsJava(seqAsJavaList(b)) /** * Adds an `asJava` method that implicitly converts a Scala mutable `Set` to a Java `Set`. * @see [[mutableSetAsJavaSet]] */ - implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] = + implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A] | Null): AsJava[ju.Set[A]] = new AsJava(mutableSetAsJavaSet(s)) /** * Adds an `asJava` method that implicitly converts a Scala `Set` to a Java `Set`. * @see [[setAsJavaSet]] */ - implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] = + implicit def setAsJavaSetConverter[A](s : Set[A] | Null): AsJava[ju.Set[A]] = new AsJava(setAsJavaSet(s)) /** * Adds an `asJava` method that implicitly converts a Scala mutable `Map` to a Java `Map`. * @see [[mutableMapAsJavaMap]] */ - implicit def mutableMapAsJavaMapConverter[K, V](m : mutable.Map[K, V]): AsJava[ju.Map[K, V]] = + implicit def mutableMapAsJavaMapConverter[K, V](m : mutable.Map[K, V] | Null): AsJava[ju.Map[K, V]] = new AsJava(mutableMapAsJavaMap(m)) /** * Adds an `asJavaDictionary` method that implicitly converts a Scala mutable `Map` to a Java `Dictionary`. * @see [[asJavaDictionary]] */ - implicit def asJavaDictionaryConverter[K, V](m : mutable.Map[K, V]): AsJavaDictionary[K, V] = + implicit def asJavaDictionaryConverter[K, V](m : mutable.Map[K, V] | Null): AsJavaDictionary[K, V] = new AsJavaDictionary(m) /** * Adds an `asJava` method that implicitly converts a Scala `Map` to a Java `Map`. * @see [[mapAsJavaMap]] */ - implicit def mapAsJavaMapConverter[K, V](m : Map[K, V]): AsJava[ju.Map[K, V]] = + implicit def mapAsJavaMapConverter[K, V](m : Map[K, V] | Null): AsJava[ju.Map[K, V]] = new AsJava(mapAsJavaMap(m)) /** * Adds an `asJava` method that implicitly converts a Scala mutable `concurrent.Map` to a Java `ConcurrentMap`. * @see [[mapAsJavaConcurrentMap]]. */ - implicit def mapAsJavaConcurrentMapConverter[K, V](m: concurrent.Map[K, V]): AsJava[juc.ConcurrentMap[K, V]] = + implicit def mapAsJavaConcurrentMapConverter[K, V](m: concurrent.Map[K, V] | Null): AsJava[juc.ConcurrentMap[K, V]] = new AsJava(mapAsJavaConcurrentMap(m)) @@ -239,100 +238,100 @@ object JavaConverters extends AsJavaConverters with AsScalaConverters { * Adds an `asScala` method that implicitly converts a Java `Iterator` to a Scala `Iterator`. * @see [[asScalaIterator]] */ - implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] = + implicit def asScalaIteratorConverter[A](i : ju.Iterator[A] | Null): AsScala[Iterator[A]] = new AsScala(asScalaIterator(i)) /** * Adds an `asScala` method that implicitly converts a Java `Enumeration` to a Scala `Iterator`. * @see [[enumerationAsScalaIterator]] */ - implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] = + implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A] | Null): AsScala[Iterator[A]] = new AsScala(enumerationAsScalaIterator(i)) /** * Adds an `asScala` method that implicitly converts a Java `Iterable` to a Scala `Iterable`. * @see [[iterableAsScalaIterable]] */ - implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] = + implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A] | Null): AsScala[Iterable[A]] = new AsScala(iterableAsScalaIterable(i)) /** * Adds an `asScala` method that implicitly converts a Java `Collection` to an Scala `Iterable`. * @see [[collectionAsScalaIterable]] */ - implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] = + implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A] | Null): AsScala[Iterable[A]] = new AsScala(collectionAsScalaIterable(i)) /** * Adds an `asScala` method that implicitly converts a Java `List` to a Scala mutable `Buffer`. * @see [[asScalaBuffer]] */ - implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] = + implicit def asScalaBufferConverter[A](l : ju.List[A] | Null): AsScala[mutable.Buffer[A]] = new AsScala(asScalaBuffer(l)) /** * Adds an `asScala` method that implicitly converts a Java `Set` to a Scala mutable `Set`. * @see [[asScalaSet]] */ - implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] = + implicit def asScalaSetConverter[A](s : ju.Set[A] | Null): AsScala[mutable.Set[A]] = new AsScala(asScalaSet(s)) /** * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala mutable `Map`. * @see [[mapAsScalaMap]] */ - implicit def mapAsScalaMapConverter[K, V](m : ju.Map[K, V]): AsScala[mutable.Map[K, V]] = + implicit def mapAsScalaMapConverter[K, V](m : ju.Map[K, V] | Null): AsScala[mutable.Map[K, V]] = new AsScala(mapAsScalaMap(m)) /** * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` to a Scala mutable `concurrent.Map`. * @see [[mapAsScalaConcurrentMap]] */ - implicit def mapAsScalaConcurrentMapConverter[K, V](m: juc.ConcurrentMap[K, V]): AsScala[concurrent.Map[K, V]] = + implicit def mapAsScalaConcurrentMapConverter[K, V](m: juc.ConcurrentMap[K, V] | Null): AsScala[concurrent.Map[K, V]] = new AsScala(mapAsScalaConcurrentMap(m)) /** * Adds an `asScala` method that implicitly converts a Java `Dictionary` to a Scala mutable `Map`. * @see [[dictionaryAsScalaMap]] */ - implicit def dictionaryAsScalaMapConverter[K, V](p: ju.Dictionary[K, V]): AsScala[mutable.Map[K, V]] = + implicit def dictionaryAsScalaMapConverter[K, V](p: ju.Dictionary[K, V] | Null): AsScala[mutable.Map[K, V]] = new AsScala(dictionaryAsScalaMap(p)) /** * Adds an `asScala` method that implicitly converts a Java `Properties` to a Scala mutable `Map[String, String]`. * @see [[propertiesAsScalaMap]] */ - implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = + implicit def propertiesAsScalaMapConverter(p: ju.Properties | Null): AsScala[mutable.Map[String, String]] = new AsScala(propertiesAsScalaMap(p)) /** Generic class containing the `asJava` converter method */ - class AsJava[A](op: => A) { + class AsJava[A](op: => A | Null) { /** Converts a Scala collection to the corresponding Java collection */ - def asJava: A = op + def asJava: A | Null = op } /** Generic class containing the `asScala` converter method */ - class AsScala[A](op: => A) { + class AsScala[A](op: => A | Null) { /** Converts a Java collection to the corresponding Scala collection */ - def asScala: A = op + def asScala: A | Null = op } /** Generic class containing the `asJavaCollection` converter method */ - class AsJavaCollection[A](i: Iterable[A]) { + class AsJavaCollection[A](i: Iterable[A] | Null) { /** Converts a Scala `Iterable` to a Java `Collection` */ - def asJavaCollection: ju.Collection[A] = JavaConverters.asJavaCollection(i) + def asJavaCollection: ju.Collection[A] | Null = JavaConverters.asJavaCollection(i) } /** Generic class containing the `asJavaEnumeration` converter method */ - class AsJavaEnumeration[A](i: Iterator[A]) { + class AsJavaEnumeration[A](i: Iterator[A] | Null) { /** Converts a Scala `Iterator` to a Java `Enumeration` */ - def asJavaEnumeration: ju.Enumeration[A] = JavaConverters.asJavaEnumeration(i) + def asJavaEnumeration: ju.Enumeration[A] | Null = JavaConverters.asJavaEnumeration(i) } /** Generic class containing the `asJavaDictionary` converter method */ - class AsJavaDictionary[K, V](m : mutable.Map[K, V]) { + class AsJavaDictionary[K, V](m : mutable.Map[K, V] | Null) { /** Converts a Scala `Map` to a Java `Dictionary` */ - def asJavaDictionary: ju.Dictionary[K, V] = JavaConverters.asJavaDictionary(m) + def asJavaDictionary: ju.Dictionary[K, V] | Null = JavaConverters.asJavaDictionary(m) } } diff --git a/library/src/scala/collection/LazyZipOps.scala b/library/src/scala/collection/LazyZipOps.scala index 9a7dc3173926..df5ff03014ec 100644 --- a/library/src/scala/collection/LazyZipOps.scala +++ b/library/src/scala/collection/LazyZipOps.scala @@ -72,7 +72,7 @@ final class LazyZip2[+El1, +El2, C1] private[collection](src: C1, coll1: Iterabl def iterator: AbstractIterator[(El1, El2)]^{this, p} = new AbstractIterator[(El1, El2)] { private[this] val elems1 = coll1.iterator private[this] val elems2 = coll2.iterator - private[this] var _current: (El1, El2) = _ + private[this] var _current: (El1, El2) | Null = _ private def current = { while ((_current eq null) && elems1.hasNext && elems2.hasNext) { val e1 = elems1.next() @@ -203,7 +203,7 @@ final class LazyZip3[+El1, +El2, +El3, C1] private[collection](src: C1, private[this] val elems1 = coll1.iterator private[this] val elems2 = coll2.iterator private[this] val elems3 = coll3.iterator - private[this] var _current: (El1, El2, El3) = _ + private[this] var _current: (El1, El2, El3) | Null = _ private def current = { while ((_current eq null) && elems1.hasNext && elems2.hasNext && elems3.hasNext) { val e1 = elems1.next() @@ -338,7 +338,7 @@ final class LazyZip4[+El1, +El2, +El3, +El4, C1] private[collection](src: C1, private[this] val elems2 = coll2.iterator private[this] val elems3 = coll3.iterator private[this] val elems4 = coll4.iterator - private[this] var _current: (El1, El2, El3, El4) = _ + private[this] var _current: (El1, El2, El3, El4) | Null = _ private def current = { while ((_current eq null) && elems1.hasNext && elems2.hasNext && elems3.hasNext && elems4.hasNext) { val e1 = elems1.next() diff --git a/library/src/scala/collection/SeqView.scala b/library/src/scala/collection/SeqView.scala index 960de6f1d752..14cb3bdf66ed 100644 --- a/library/src/scala/collection/SeqView.scala +++ b/library/src/scala/collection/SeqView.scala @@ -138,7 +138,7 @@ object SeqView { extends SeqView[A] { outer: Sorted[A, B]^ => - private var underlying = underlying_ + private var underlying: SomeSeqOps[A] | Null = underlying_ // force evaluation immediately by calling `length` so infinite collections // hang on `sorted`/`sortWith`/`sortBy` rather than on arbitrary method calls @@ -169,10 +169,10 @@ object SeqView { val res = { val len = this.len if (len == 0) Nil - else if (len == 1) List(underlying.head) + else if (len == 1) List(underlying.nn.head) else { val arr = new Array[Any](len) // Array[Any] =:= Array[AnyRef] - @annotation.unused val copied = underlying.copyToArray(arr) + @annotation.unused val copied = underlying.nn.copyToArray(arr) //assert(copied == len) java.util.Arrays.sort(arr.asInstanceOf[Array[AnyRef]], ord.asInstanceOf[Ordering[AnyRef]]) // casting the Array[AnyRef] to Array[A] and creating an ArraySeq from it @@ -183,7 +183,7 @@ object SeqView { // contains items of another type, we'd get a CCE anyway) // - the cast doesn't actually do anything in the runtime because the // type of A is not known and Array[_] is Array[AnyRef] - immutable.ArraySeq.unsafeWrapArray(arr.asInstanceOf[Array[A]]) + immutable.ArraySeq.unsafeWrapArray(arr.asInstanceOf[Array[A]]).nn } } evaluated = true @@ -192,7 +192,7 @@ object SeqView { } private[this] def elems: SomeSeqOps[A]^{this} = { - val orig: SomeSeqOps[A]^{this} = underlying + val orig: SomeSeqOps[A]^{this} = underlying.nn if (evaluated) _sorted else orig } diff --git a/library/src/scala/collection/Stepper.scala b/library/src/scala/collection/Stepper.scala index 7c4b5821aef9..e8f563489916 100644 --- a/library/src/scala/collection/Stepper.scala +++ b/library/src/scala/collection/Stepper.scala @@ -54,7 +54,7 @@ trait Stepper[@specialized(Double, Int, Long) +A] { * * See method `trySplit` in [[java.util.Spliterator]]. */ - def trySplit(): Stepper[A]^{this} + def trySplit(): Stepper[A]^{this} | Null /** Returns an estimate of the number of elements of this Stepper, or [[Long.MaxValue]]. See * method `estimateSize` in [[java.util.Spliterator]]. @@ -111,7 +111,7 @@ object Stepper { def nextStep(): Double = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): DoubleStepper^{this} = { + def trySplit(): DoubleStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingDoubleStepper(s) } @@ -122,7 +122,7 @@ object Stepper { def nextStep(): Int = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): IntStepper^{this} = { + def trySplit(): IntStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingIntStepper(s) } @@ -133,7 +133,7 @@ object Stepper { def nextStep(): Long = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): LongStepper^{this} = { + def trySplit(): LongStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingLongStepper(s) } @@ -144,7 +144,7 @@ object Stepper { def nextStep(): Int = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): IntStepper^{this} = { + def trySplit(): IntStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingByteStepper(s) } @@ -155,7 +155,7 @@ object Stepper { def nextStep(): Int = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): IntStepper^{this} = { + def trySplit(): IntStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingCharStepper(s) } @@ -166,7 +166,7 @@ object Stepper { def nextStep(): Int = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): IntStepper^{this} = { + def trySplit(): IntStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingShortStepper(s) } @@ -177,7 +177,7 @@ object Stepper { def nextStep(): Double = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): DoubleStepper^{this} = { + def trySplit(): DoubleStepper^{this} | Null = { val s = st.trySplit() if (s == null) null else new UnboxingFloatStepper(s) } @@ -186,7 +186,7 @@ object Stepper { /** A Stepper for arbitrary element types. See [[Stepper]]. */ trait AnyStepper[+A] extends Stepper[A] { - def trySplit(): AnyStepper[A]^{this} + def trySplit(): AnyStepper[A]^{this} | Null def spliterator[B >: A]: Spliterator[B]^{this} = new AnyStepper.AnyStepperSpliterator(this) @@ -200,7 +200,7 @@ object AnyStepper { class AnyStepperSpliterator[A](s: AnyStepper[A]^) extends Spliterator[A] { def tryAdvance(c: Consumer[_ >: A]): Boolean = if (s.hasStep) { c.accept(s.nextStep()); true } else false - def trySplit(): Spliterator[A]^{this} = { + def trySplit(): Spliterator[A]^{this} | Null = { val sp = s.trySplit() if (sp == null) null else sp.spliterator } @@ -225,7 +225,7 @@ object AnyStepper { def nextStep(): Double = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): AnyStepper[Double] = { + def trySplit(): AnyStepper[Double] | Null = { val s = st.trySplit() if (s == null) null else new BoxedDoubleStepper(s) } @@ -236,7 +236,7 @@ object AnyStepper { def nextStep(): Int = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): AnyStepper[Int] = { + def trySplit(): AnyStepper[Int] | Null = { val s = st.trySplit() if (s == null) null else new BoxedIntStepper(s) } @@ -247,7 +247,7 @@ object AnyStepper { def nextStep(): Long = st.nextStep() def estimateSize: Long = st.estimateSize def characteristics: Int = st.characteristics - def trySplit(): AnyStepper[Long] = { + def trySplit(): AnyStepper[Long] | Null = { val s = st.trySplit() if (s == null) null else new BoxedLongStepper(s) } @@ -256,7 +256,7 @@ object AnyStepper { /** A Stepper for Ints. See [[Stepper]]. */ trait IntStepper extends Stepper[Int] { - def trySplit(): IntStepper^{this} + def trySplit(): IntStepper^{this} | Null def spliterator[B >: Int]: Spliterator.OfInt^{this} = new IntStepper.IntStepperSpliterator(this) @@ -275,7 +275,7 @@ object IntStepper { case _ => if (s.hasStep) { c.accept(jl.Integer.valueOf(s.nextStep())); true } else false } // override required for dotty#6152 - override def trySplit(): Spliterator.OfInt^{this} = { + override def trySplit(): Spliterator.OfInt^{this} | Null = { val sp = s.trySplit() if (sp == null) null else sp.spliterator } @@ -294,7 +294,7 @@ object IntStepper { /** A Stepper for Doubles. See [[Stepper]]. */ trait DoubleStepper extends Stepper[Double] { - def trySplit(): DoubleStepper^{this} + def trySplit(): DoubleStepper^{this} | Null def spliterator[B >: Double]: Spliterator.OfDouble^{this} = new DoubleStepper.DoubleStepperSpliterator(this) @@ -314,7 +314,7 @@ object DoubleStepper { case _ => if (s.hasStep) { c.accept(java.lang.Double.valueOf(s.nextStep())); true } else false } // override required for dotty#6152 - override def trySplit(): Spliterator.OfDouble^{this} = { + override def trySplit(): Spliterator.OfDouble^{this} | Null = { val sp = s.trySplit() if (sp == null) null else sp.spliterator } @@ -333,7 +333,7 @@ object DoubleStepper { /** A Stepper for Longs. See [[Stepper]]. */ trait LongStepper extends Stepper[Long] { - def trySplit(): LongStepper^{this} + def trySplit(): LongStepper^{this} | Null def spliterator[B >: Long]: Spliterator.OfLong^{this} = new LongStepper.LongStepperSpliterator(this) @@ -353,7 +353,7 @@ object LongStepper { case _ => if (s.hasStep) { c.accept(java.lang.Long.valueOf(s.nextStep())); true } else false } // override required for dotty#6152 - override def trySplit(): Spliterator.OfLong^{this} = { + override def trySplit(): Spliterator.OfLong^{this} | Null = { val sp = s.trySplit() if (sp == null) null else sp.spliterator } diff --git a/library/src/scala/collection/View.scala b/library/src/scala/collection/View.scala index 6b862aece4ea..b705c7748218 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -452,19 +452,20 @@ object View extends IterableFactory[View] { private final class TakeRightIterator[A](private[this] var underlying: Iterator[A]^, maxlen: Int) extends AbstractIterator[A] { private[this] var len: Int = -1 private[this] var pos: Int = 0 - private[this] var buf: ArrayBuffer[AnyRef] = _ + @annotation.stableNull + private[this] var buf: ArrayBuffer[AnyRef] | Null = _ def init(): Unit = if(buf eq null) { buf = new ArrayBuffer[AnyRef](maxlen min 256) len = 0 while(underlying.hasNext) { val n = underlying.next().asInstanceOf[AnyRef] - if(pos >= buf.length) buf.addOne(n) - else buf(pos) = n + if(pos >= buf.nn.length) buf.nn.addOne(n) + else buf.nn(pos) = n pos += 1 if(pos == maxlen) pos = 0 len += 1 } - underlying = null + underlying = null.asInstanceOf[Iterator[A]^] // allow GC of underlying iterator if(len > maxlen) len = maxlen pos = pos - len if(pos < 0) pos += maxlen @@ -478,7 +479,7 @@ object View extends IterableFactory[View] { init() if(len == 0) Iterator.empty.next() else { - val x = buf(pos).asInstanceOf[A] + val x = buf.nn(pos).asInstanceOf[A] pos += 1 if(pos == maxlen) pos = 0 len -= 1 @@ -507,11 +508,12 @@ object View extends IterableFactory[View] { private final class DropRightIterator[A](private[this] var underlying: Iterator[A]^, maxlen: Int) extends AbstractIterator[A] { private[this] var len: Int = -1 // known size or -1 if the end of `underlying` has not been seen yet private[this] var pos: Int = 0 - private[this] var buf: ArrayBuffer[AnyRef] = _ + @annotation.stableNull + private[this] var buf: ArrayBuffer[AnyRef] | Null = _ def init(): Unit = if(buf eq null) { buf = new ArrayBuffer[AnyRef](maxlen min 256) while(pos < maxlen && underlying.hasNext) { - buf.addOne(underlying.next().asInstanceOf[AnyRef]) + buf.nn.addOne(underlying.next().asInstanceOf[AnyRef]) pos += 1 } if(!underlying.hasNext) len = 0 @@ -525,9 +527,9 @@ object View extends IterableFactory[View] { def next(): A = { if(!hasNext) Iterator.empty.next() else { - val x = buf(pos).asInstanceOf[A] + val x = buf.nn(pos).asInstanceOf[A] if(len == -1) { - buf(pos) = underlying.next().asInstanceOf[AnyRef] + buf.nn(pos) = underlying.next().asInstanceOf[AnyRef] if(!underlying.hasNext) len = 0 } else len -= 1 pos += 1 diff --git a/library/src/scala/collection/concurrent/TrieMap.scala b/library/src/scala/collection/concurrent/TrieMap.scala index a29eb902afb4..a40504fd7268 100644 --- a/library/src/scala/collection/concurrent/TrieMap.scala +++ b/library/src/scala/collection/concurrent/TrieMap.scala @@ -16,6 +16,7 @@ package concurrent import scala.language.`2.13` import language.experimental.captureChecking +import scala.language.unsafeNulls import java.util.concurrent.atomic._ import scala.{unchecked => uc} diff --git a/library/src/scala/collection/convert/AsJavaConverters.scala b/library/src/scala/collection/convert/AsJavaConverters.scala index 079847776368..1ee8742b9356 100644 --- a/library/src/scala/collection/convert/AsJavaConverters.scala +++ b/library/src/scala/collection/convert/AsJavaConverters.scala @@ -40,10 +40,10 @@ trait AsJavaConverters { * @param i The Scala `Iterator` to be converted. * @return A Java `Iterator` view of the argument. */ - def asJava[A](i: Iterator[A]): ju.Iterator[A] = i match { + def asJava[A](i: Iterator[A] | Null): ju.Iterator[A] | Null = i match { case null => null case wrapper: JIteratorWrapper[A @uc] => wrapper.underlying - case _ => new IteratorWrapper(i) + case _ => new IteratorWrapper(i.nn) } /** @@ -58,10 +58,10 @@ trait AsJavaConverters { * @param i The Scala `Iterator` to be converted. * @return A Java `Enumeration` view of the argument. */ - def asJavaEnumeration[A](i: Iterator[A]): ju.Enumeration[A] = i match { + def asJavaEnumeration[A](i: Iterator[A] | Null): ju.Enumeration[A] | Null = i match { case null => null case wrapper: JEnumerationWrapper[A @uc] => wrapper.underlying - case _ => new IteratorWrapper(i) + case _ => new IteratorWrapper(i.nn) } /** @@ -76,10 +76,10 @@ trait AsJavaConverters { * @param i The Scala `Iterable` to be converted. * @return A Java `Iterable` view of the argument. */ - def asJava[A](i: Iterable[A]): jl.Iterable[A] = i match { + def asJava[A](i: Iterable[A] | Null): jl.Iterable[A] | Null = i match { case null => null case wrapper: JIterableWrapper[A @uc] => wrapper.underlying - case _ => new IterableWrapper(i) + case _ => new IterableWrapper(i.nn) } /** @@ -91,10 +91,10 @@ trait AsJavaConverters { * @param i The Scala `Iterable` to be converted. * @return A Java `Collection` view of the argument. */ - def asJavaCollection[A](i: Iterable[A]): ju.Collection[A] = i match { + def asJavaCollection[A](i: Iterable[A] | Null): ju.Collection[A] | Null = i match { case null => null case wrapper: JCollectionWrapper[A @uc] => wrapper.underlying - case _ => new IterableWrapper(i) + case _ => new IterableWrapper(i.nn) } /** @@ -109,10 +109,10 @@ trait AsJavaConverters { * @param b The Scala `Buffer` to be converted. * @return A Java `List` view of the argument. */ - def asJava[A](b: mutable.Buffer[A]): ju.List[A] = b match { + def asJava[A](b: mutable.Buffer[A] | Null): ju.List[A] | Null = b match { case null => null case wrapper: JListWrapper[A @uc] => wrapper.underlying - case _ => new MutableBufferWrapper(b) + case _ => new MutableBufferWrapper(b.nn) } /** @@ -127,10 +127,10 @@ trait AsJavaConverters { * @param s The Scala `Seq` to be converted. * @return A Java `List` view of the argument. */ - def asJava[A](s: mutable.Seq[A]): ju.List[A] = s match { + def asJava[A](s: mutable.Seq[A] | Null): ju.List[A] | Null = s match { case null => null case wrapper: JListWrapper[A @uc] => wrapper.underlying - case _ => new MutableSeqWrapper(s) + case _ => new MutableSeqWrapper(s.nn) } /** @@ -145,10 +145,10 @@ trait AsJavaConverters { * @param s The Scala `Seq` to be converted. * @return A Java `List` view of the argument. */ - def asJava[A](s: Seq[A]): ju.List[A] = s match { + def asJava[A](s: Seq[A] | Null): ju.List[A] | Null = s match { case null => null case wrapper: JListWrapper[A @uc] => wrapper.underlying - case _ => new SeqWrapper(s) + case _ => new SeqWrapper(s.nn) } /** @@ -163,10 +163,10 @@ trait AsJavaConverters { * @param s The Scala mutable `Set` to be converted. * @return A Java `Set` view of the argument. */ - def asJava[A](s: mutable.Set[A]): ju.Set[A] = s match { + def asJava[A](s: mutable.Set[A] | Null): ju.Set[A] | Null = s match { case null => null case wrapper: JSetWrapper[A @uc] => wrapper.underlying - case _ => new MutableSetWrapper(s) + case _ => new MutableSetWrapper(s.nn) } /** @@ -181,10 +181,10 @@ trait AsJavaConverters { * @param s The Scala `Set` to be converted. * @return A Java `Set` view of the argument. */ - def asJava[A](s: Set[A]): ju.Set[A] = s match { + def asJava[A](s: Set[A] | Null): ju.Set[A] | Null = s match { case null => null case wrapper: JSetWrapper[A @uc] => wrapper.underlying - case _ => new SetWrapper(s) + case _ => new SetWrapper(s.nn) } /** @@ -199,10 +199,10 @@ trait AsJavaConverters { * @param m The Scala mutable `Map` to be converted. * @return A Java `Map` view of the argument. */ - def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = m match { + def asJava[K, V](m: mutable.Map[K, V] | Null): ju.Map[K, V] | Null = m match { case null => null case wrapper: JMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new MutableMapWrapper(m) + case _ => new MutableMapWrapper(m.nn) } /** @@ -218,10 +218,10 @@ trait AsJavaConverters { * @param m The Scala `Map` to be converted. * @return A Java `Dictionary` view of the argument. */ - def asJavaDictionary[K, V](m: mutable.Map[K, V]): ju.Dictionary[K, V] = m match { + def asJavaDictionary[K, V](m: mutable.Map[K, V] | Null): ju.Dictionary[K, V] | Null = m match { case null => null case wrapper: JDictionaryWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new DictionaryWrapper(m) + case _ => new DictionaryWrapper(m.nn) } /** @@ -236,10 +236,10 @@ trait AsJavaConverters { * @param m The Scala `Map` to be converted. * @return A Java `Map` view of the argument. */ - def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = m match { + def asJava[K, V](m: Map[K, V] | Null): ju.Map[K, V] | Null = m match { case null => null case wrapper: JMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new MapWrapper(m) + case _ => new MapWrapper(m.nn) } /** @@ -255,9 +255,9 @@ trait AsJavaConverters { * @param m The Scala `concurrent.Map` to be converted. * @return A Java `ConcurrentMap` view of the argument. */ - def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = m match { + def asJava[K, V](m: concurrent.Map[K, V] | Null): juc.ConcurrentMap[K, V] | Null = m match { case null => null case wrapper: JConcurrentMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new ConcurrentMapWrapper(m) + case _ => new ConcurrentMapWrapper(m.nn) } } diff --git a/library/src/scala/collection/convert/AsJavaExtensions.scala b/library/src/scala/collection/convert/AsJavaExtensions.scala index 67f127d9e042..fc9aa48d5d51 100644 --- a/library/src/scala/collection/convert/AsJavaExtensions.scala +++ b/library/src/scala/collection/convert/AsJavaExtensions.scala @@ -24,88 +24,88 @@ import java.{lang => jl, util => ju} trait AsJavaExtensions { import scala.jdk.javaapi.{CollectionConverters => conv} - implicit class IteratorHasAsJava[A](i: Iterator[A]) { + implicit class IteratorHasAsJava[A](i: Iterator[A] | Null) { /** Converts a Scala `Iterator` to a Java `Iterator`, see * [[AsJavaConverters.asJava[A](i:Iterator[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.Iterator[A] = conv.asJava(i) + def asJava: ju.Iterator[A] | Null = conv.asJava(i) /** Converts a Scala `Iterator` to a Java `Enumeration`, see * [[AsJavaConverters.asJavaEnumeration `scala.jdk.javaapi.CollectionConverters.asJavaEnumeration`]]. */ - def asJavaEnumeration: ju.Enumeration[A] = conv.asJavaEnumeration(i) + def asJavaEnumeration: ju.Enumeration[A] | Null = conv.asJavaEnumeration(i) } - implicit class IterableHasAsJava[A](i: Iterable[A]) { + implicit class IterableHasAsJava[A](i: Iterable[A] | Null) { /** Converts a Scala `Iterable` to a Java `Iterable`, see * [[AsJavaConverters.asJava[A](i:Iterable[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: jl.Iterable[A] = conv.asJava(i) + def asJava: jl.Iterable[A] | Null = conv.asJava(i) /** Converts a Scala `Iterator` to a Java `Collection`, see * [[AsJavaConverters.asJavaCollection `scala.jdk.javaapi.CollectionConverters.asJavaCollection`]]. */ - def asJavaCollection: ju.Collection[A] = conv.asJavaCollection(i) + def asJavaCollection: ju.Collection[A] | Null = conv.asJavaCollection(i) } - implicit class BufferHasAsJava[A](b: mutable.Buffer[A]) { + implicit class BufferHasAsJava[A](b: mutable.Buffer[A] | Null) { /** Converts a Scala `Buffer` to a Java `List`, see * [[AsJavaConverters.asJava[A](b:scala\.collection\.mutable\.Buffer[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.List[A] = conv.asJava(b) + def asJava: ju.List[A] | Null = conv.asJava(b) } - implicit class MutableSeqHasAsJava[A](s: mutable.Seq[A]) { + implicit class MutableSeqHasAsJava[A](s: mutable.Seq[A] | Null) { /** Converts a Scala `Seq` to a Java `List`, see * [[AsJavaConverters.asJava[A](s:scala\.collection\.mutable\.Seq[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.List[A] = conv.asJava(s) + def asJava: ju.List[A] | Null = conv.asJava(s) } - implicit class SeqHasAsJava[A](s: Seq[A]) { + implicit class SeqHasAsJava[A](s: Seq[A] | Null) { /** Converts a Scala `Seq` to a Java `List`, see * [[AsJavaConverters.asJava[A](s:scala\.collection\.Seq[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.List[A] = conv.asJava(s) + def asJava: ju.List[A] | Null = conv.asJava(s) } - implicit class MutableSetHasAsJava[A](s: mutable.Set[A]) { + implicit class MutableSetHasAsJava[A](s: mutable.Set[A] | Null) { /** Converts a Scala `mutable.Set` to a Java `Set`, see * [[AsJavaConverters.asJava[A](s:scala\.collection\.mutable\.Set[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.Set[A] = conv.asJava(s) + def asJava: ju.Set[A] | Null = conv.asJava(s) } - implicit class SetHasAsJava[A](s: Set[A]) { + implicit class SetHasAsJava[A](s: Set[A] | Null) { /** Converts a Scala `Set` to a Java `Set`, see * [[AsJavaConverters.asJava[A](s:scala\.collection\.Set[A])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.Set[A] = conv.asJava(s) + def asJava: ju.Set[A] | Null = conv.asJava(s) } - implicit class MutableMapHasAsJava[K, V](m: mutable.Map[K, V]) { + implicit class MutableMapHasAsJava[K, V](m: mutable.Map[K, V] | Null) { /** Converts a Scala `mutable.Map` to a Java `Map`, see * [[AsJavaConverters.asJava[K,V](m:scala\.collection\.mutable\.Map[K,V])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.Map[K, V] = conv.asJava(m) + def asJava: ju.Map[K, V] | Null = conv.asJava(m) /** Converts a Scala `mutable.Map` to a Java `Map`, see * [[AsJavaConverters.asJavaDictionary `scala.jdk.javaapi.CollectionConverters.asJavaDictionary`]]. */ - def asJavaDictionary: ju.Dictionary[K, V] = conv.asJavaDictionary(m) + def asJavaDictionary: ju.Dictionary[K, V] | Null = conv.asJavaDictionary(m) } - implicit class MapHasAsJava[K, V](m: Map[K, V]) { + implicit class MapHasAsJava[K, V](m: Map[K, V] | Null) { /** Converts a Scala `Map` to a Java `Map`, see * [[AsJavaConverters.asJava[K,V](m:scala\.collection\.Map[K,V])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: ju.Map[K, V] = conv.asJava(m) + def asJava: ju.Map[K, V] | Null = conv.asJava(m) } - implicit class ConcurrentMapHasAsJava[K, V](m: concurrent.Map[K, V]) { + implicit class ConcurrentMapHasAsJava[K, V](m: concurrent.Map[K, V] | Null) { /** Converts a Scala `concurrent.Map` to a Java `ConcurrentMap`, see * [[AsJavaConverters.asJava[K,V](m:scala\.collection\.concurrent\.Map[K,V])* `scala.jdk.javaapi.CollectionConverters.asJava`]]. */ - def asJava: juc.ConcurrentMap[K, V] = conv.asJava(m) + def asJava: juc.ConcurrentMap[K, V] | Null = conv.asJava(m) } } diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index e2fa0f39bfef..d4c950d23e2c 100644 --- a/library/src/scala/collection/convert/AsScalaConverters.scala +++ b/library/src/scala/collection/convert/AsScalaConverters.scala @@ -41,10 +41,10 @@ trait AsScalaConverters { * @param i The Java `Iterator` to be converted. * @return A Scala `Iterator` view of the argument. */ - def asScala[A](i: ju.Iterator[A]): Iterator[A] = i match { + def asScala[A](i: ju.Iterator[A] | Null): Iterator[A] | Null = i match { case null => null - case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JIteratorWrapper(i) + case wrapper: IteratorWrapper[A @uc] => wrapper.underlying + case _ => new JIteratorWrapper(i.nn) } /** @@ -59,10 +59,10 @@ trait AsScalaConverters { * @param e The Java `Enumeration` to be converted. * @return A Scala `Iterator` view of the argument. */ - def asScala[A](e: ju.Enumeration[A]): Iterator[A] = e match { + def asScala[A](e: ju.Enumeration[A] | Null): Iterator[A] | Null = e match { case null => null - case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JEnumerationWrapper(e) + case wrapper: IteratorWrapper[A @uc] => wrapper.underlying + case _ => new JEnumerationWrapper(e.nn) } /** @@ -77,10 +77,10 @@ trait AsScalaConverters { * @param i The Java `Iterable` to be converted. * @return A Scala `Iterable` view of the argument. */ - def asScala[A](i: jl.Iterable[A]): Iterable[A] = i match { + def asScala[A](i: jl.Iterable[A] | Null): Iterable[A] | Null = i match { case null => null - case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JIterableWrapper(i) + case wrapper: IterableWrapper[A @uc] => wrapper.underlying + case _ => new JIterableWrapper(i.nn) } /** @@ -92,10 +92,10 @@ trait AsScalaConverters { * @param c The Java `Collection` to be converted. * @return A Scala `Iterable` view of the argument. */ - def asScala[A](c: ju.Collection[A]): Iterable[A] = c match { + def asScala[A](c: ju.Collection[A] | Null): Iterable[A] | Null = c match { case null => null - case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JCollectionWrapper(c) + case wrapper: IterableWrapper[A @uc] => wrapper.underlying + case _ => new JCollectionWrapper(c.nn) } /** @@ -110,10 +110,10 @@ trait AsScalaConverters { * @param l The Java `List` to be converted. * @return A Scala mutable `Buffer` view of the argument. */ - def asScala[A](l: ju.List[A]): mutable.Buffer[A] = l match { + def asScala[A](l: ju.List[A] | Null): mutable.Buffer[A] | Null = l match { case null => null case wrapper: MutableBufferWrapper[A @uc] => wrapper.underlying - case _ => new JListWrapper(l) + case _ => new JListWrapper(l.nn) } /** @@ -128,10 +128,10 @@ trait AsScalaConverters { * @param s The Java `Set` to be converted. * @return A Scala mutable `Set` view of the argument. */ - def asScala[A](s: ju.Set[A]): mutable.Set[A] = s match { + def asScala[A](s: ju.Set[A] | Null): mutable.Set[A] | Null = s match { case null => null case wrapper: MutableSetWrapper[A @uc] => wrapper.underlying - case _ => new JSetWrapper(s) + case _ => new JSetWrapper(s.nn) } /** @@ -151,10 +151,10 @@ trait AsScalaConverters { * @param m The Java `Map` to be converted. * @return A Scala mutable `Map` view of the argument. */ - def asScala[K, V](m: ju.Map[K, V]): mutable.Map[K, V] = m match { + def asScala[K, V](m: ju.Map[K, V] | Null): mutable.Map[K, V] | Null = m match { case null => null case wrapper: MutableMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new JMapWrapper(m) + case _ => new JMapWrapper(m.nn) } /** @@ -170,10 +170,10 @@ trait AsScalaConverters { * @param m The Java `ConcurrentMap` to be converted. * @return A Scala mutable `ConcurrentMap` view of the argument. */ - def asScala[K, V](m: juc.ConcurrentMap[K, V]): concurrent.Map[K, V] = m match { + def asScala[K, V](m: juc.ConcurrentMap[K, V] | Null): concurrent.Map[K, V] | Null = m match { case null => null case wrapper: ConcurrentMapWrapper[K @uc, V @uc] => wrapper.underlyingConcurrentMap - case _ => new JConcurrentMapWrapper(m) + case _ => new JConcurrentMapWrapper(m.nn) } /** @@ -188,10 +188,10 @@ trait AsScalaConverters { * @param d The Java `Dictionary` to be converted. * @return A Scala mutable `Map` view of the argument. */ - def asScala[K, V](d: ju.Dictionary[K, V]): mutable.Map[K, V] = d match { + def asScala[K, V](d: ju.Dictionary[K, V] | Null): mutable.Map[K, V] | Null = d match { case null => null case wrapper: DictionaryWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new JDictionaryWrapper(d) + case _ => new JDictionaryWrapper(d.nn) } /** @@ -204,8 +204,8 @@ trait AsScalaConverters { * @param p The Java `Properties` to be converted. * @return A Scala mutable `Map[String, String]` view of the argument. */ - def asScala(p: ju.Properties): mutable.Map[String, String] = p match { + def asScala(p: ju.Properties | Null): mutable.Map[String, String] | Null = p match { case null => null - case _ => new JPropertiesWrapper(p) + case _ => new JPropertiesWrapper(p.nn) } } diff --git a/library/src/scala/collection/convert/AsScalaExtensions.scala b/library/src/scala/collection/convert/AsScalaExtensions.scala index 3ef08f0690f3..cf33c5a12cd3 100644 --- a/library/src/scala/collection/convert/AsScalaExtensions.scala +++ b/library/src/scala/collection/convert/AsScalaExtensions.scala @@ -24,73 +24,73 @@ import java.{lang => jl, util => ju} trait AsScalaExtensions { import scala.jdk.javaapi.{CollectionConverters => conv} - implicit class IteratorHasAsScala[A](i: ju.Iterator[A]) { + implicit class IteratorHasAsScala[A](i: ju.Iterator[A] | Null) { /** Converts a Java `Iterator` to a Scala `Iterator`, see * [[AsScalaConverters.asScala[A](i:java\.util\.Iterator[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: Iterator[A] = conv.asScala(i) + def asScala: Iterator[A] | Null = conv.asScala(i) } - implicit class EnumerationHasAsScala[A](e: ju.Enumeration[A]) { + implicit class EnumerationHasAsScala[A](e: ju.Enumeration[A] | Null) { /** Converts a Java `Enumeration` to a Scala `Iterator`, see * [[AsScalaConverters.asScala[A](e:java\.util\.Enumeration[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: Iterator[A] = conv.asScala(e) + def asScala: Iterator[A] | Null = conv.asScala(e) } - implicit class IterableHasAsScala[A](i: jl.Iterable[A]) { + implicit class IterableHasAsScala[A](i: jl.Iterable[A] | Null) { /** Converts a Java `Iterable` to a Scala `Iterable`, see * [[AsScalaConverters.asScala[A](i:Iterable[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: Iterable[A] = conv.asScala(i) + def asScala: Iterable[A] | Null = conv.asScala(i) } - implicit class CollectionHasAsScala[A](c: ju.Collection[A]) { + implicit class CollectionHasAsScala[A](c: ju.Collection[A] | Null) { /** Converts a Java `Collection` to a Scala `Iterable`, see * [[AsScalaConverters.asScala[A](c:java\.util\.Collection[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: Iterable[A] = conv.asScala(c) + def asScala: Iterable[A] | Null = conv.asScala(c) } - implicit class ListHasAsScala[A](l: ju.List[A]) { + implicit class ListHasAsScala[A](l: ju.List[A] | Null) { /** Converts a Java `List` to a Scala `Buffer`, see * [[AsScalaConverters.asScala[A](l:java\.util\.List[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: mutable.Buffer[A] = conv.asScala(l) + def asScala: mutable.Buffer[A] | Null = conv.asScala(l) } - implicit class SetHasAsScala[A](s: ju.Set[A]) { + implicit class SetHasAsScala[A](s: ju.Set[A] | Null) { /** Converts a Java `Set` to a Scala `Set`, see * [[AsScalaConverters.asScala[A](s:java\.util\.Set[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: mutable.Set[A] = conv.asScala(s) + def asScala: mutable.Set[A] | Null = conv.asScala(s) } - implicit class MapHasAsScala[K, V](m: ju.Map[K, V]) { + implicit class MapHasAsScala[K, V](m: ju.Map[K, V] | Null) { /** Converts a Java `Map` to a Scala `Map`, see * [[AsScalaConverters.asScala[A,B](m:java\.util\.Map[A,B])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: mutable.Map[K, V] = conv.asScala(m) + def asScala: mutable.Map[K, V] | Null = conv.asScala(m) } - implicit class ConcurrentMapHasAsScala[K, V](m: juc.ConcurrentMap[K, V]) { + implicit class ConcurrentMapHasAsScala[K, V](m: juc.ConcurrentMap[K, V] | Null) { /** Converts a Java `ConcurrentMap` to a Scala `concurrent.Map`, see * [[AsScalaConverters.asScala[A,B](m:java\.util\.concurrent\.ConcurrentMap[A,B])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: concurrent.Map[K, V] = conv.asScala(m) + def asScala: concurrent.Map[K, V] | Null = conv.asScala(m) } - implicit class DictionaryHasAsScala[K, V](d: ju.Dictionary[K, V]) { + implicit class DictionaryHasAsScala[K, V](d: ju.Dictionary[K, V] | Null) { /** Converts a Java `Dictionary` to a Scala `Map`, see * [[AsScalaConverters.asScala[A,B](d:java\.util\.Dictionary[A,B])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: mutable.Map[K, V] = conv.asScala(d) + def asScala: mutable.Map[K, V] | Null = conv.asScala(d) } - implicit class PropertiesHasAsScala(i: ju.Properties) { + implicit class PropertiesHasAsScala(i: ju.Properties | Null) { /** Converts a Java `Properties` to a Scala `Map`, see * [[AsScalaConverters.asScala(p:java\.util\.Properties)* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: mutable.Map[String, String] = conv.asScala(i) + def asScala: mutable.Map[String, String] | Null = conv.asScala(i) } } diff --git a/library/src/scala/collection/convert/ImplicitConversions.scala b/library/src/scala/collection/convert/ImplicitConversions.scala index b2ebd48f16e9..be4c764cf3c4 100644 --- a/library/src/scala/collection/convert/ImplicitConversions.scala +++ b/library/src/scala/collection/convert/ImplicitConversions.scala @@ -29,52 +29,52 @@ trait ToScalaImplicits { /** Implicitly converts a Java `Iterator` to a Scala `Iterator`. * @see [[JavaConverters.asScalaIterator]] */ - implicit def `iterator asScala`[A](it: ju.Iterator[A]): Iterator[A] = asScalaIterator(it) + implicit def `iterator asScala`[A](it: ju.Iterator[A] | Null): Iterator[A] | Null = asScalaIterator(it) /** Implicitly converts a Java `Enumeration` to a Scala `Iterator`. * @see [[JavaConverters.enumerationAsScalaIterator]] */ - implicit def `enumeration AsScalaIterator`[A](i: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(i) + implicit def `enumeration AsScalaIterator`[A](i: ju.Enumeration[A] | Null): Iterator[A] | Null = enumerationAsScalaIterator(i) /** Implicitly converts a Java `Iterable` to a Scala `Iterable`. * @see [[JavaConverters.iterableAsScalaIterable]] */ - implicit def `iterable AsScalaIterable`[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i) + implicit def `iterable AsScalaIterable`[A](i: jl.Iterable[A] | Null): Iterable[A] | Null = iterableAsScalaIterable(i) /** Implicitly converts a Java `Collection` to an Scala `Iterable`. * @see [[JavaConverters.collectionAsScalaIterable]] */ - implicit def `collection AsScalaIterable`[A](i: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(i) + implicit def `collection AsScalaIterable`[A](i: ju.Collection[A] | Null): Iterable[A] | Null = collectionAsScalaIterable(i) /** Implicitly converts a Java `List` to a Scala mutable `Buffer`. * @see [[JavaConverters.asScalaBuffer]] */ - implicit def `list asScalaBuffer`[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l) + implicit def `list asScalaBuffer`[A](l: ju.List[A] | Null): mutable.Buffer[A] | Null = asScalaBuffer(l) /** Implicitly converts a Java `Set` to a Scala mutable `Set`. * @see [[JavaConverters.asScalaSet]] */ - implicit def `set asScala`[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s) + implicit def `set asScala`[A](s: ju.Set[A] | Null): mutable.Set[A] | Null = asScalaSet(s) /** Implicitly converts a Java `Map` to a Scala mutable `Map`. * @see [[JavaConverters.mapAsScalaMap]] */ - implicit def `map AsScala`[K, V](m: ju.Map[K, V]): mutable.Map[K, V] = mapAsScalaMap(m) + implicit def `map AsScala`[K, V](m: ju.Map[K, V] | Null): mutable.Map[K, V] | Null = mapAsScalaMap(m) /** Implicitly converts a Java `ConcurrentMap` to a Scala mutable `ConcurrentMap`. * @see [[JavaConverters.mapAsScalaConcurrentMap]] */ - implicit def `map AsScalaConcurrentMap`[K, V](m: juc.ConcurrentMap[K, V]): concurrent.Map[K, V] = mapAsScalaConcurrentMap(m) + implicit def `map AsScalaConcurrentMap`[K, V](m: juc.ConcurrentMap[K, V] | Null): concurrent.Map[K, V] | Null = mapAsScalaConcurrentMap(m) /** Implicitly converts a Java `Dictionary` to a Scala mutable `Map`. * @see [[JavaConverters.dictionaryAsScalaMap]] */ - implicit def `dictionary AsScalaMap`[K, V](p: ju.Dictionary[K, V]): mutable.Map[K, V] = dictionaryAsScalaMap(p) + implicit def `dictionary AsScalaMap`[K, V](p: ju.Dictionary[K, V] | Null): mutable.Map[K, V] | Null = dictionaryAsScalaMap(p) /** Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`. * @see [[JavaConverters.propertiesAsScalaMap]] */ - implicit def `properties AsScalaMap`(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p) + implicit def `properties AsScalaMap`(p: ju.Properties | Null): mutable.Map[String, String] | Null = propertiesAsScalaMap(p) } /** Defines implicit conversions from Scala to Java collections. */ @@ -83,67 +83,67 @@ trait ToJavaImplicits { /** Implicitly converts a Scala `Iterator` to a Java `Iterator`. * @see [[JavaConverters.asJavaIterator]] */ - implicit def `iterator asJava`[A](it: Iterator[A]): ju.Iterator[A] = asJavaIterator(it) + implicit def `iterator asJava`[A](it: Iterator[A] | Null): ju.Iterator[A] | Null = asJavaIterator(it) /** Implicitly converts a Scala `Iterator` to a Java `Enumeration`. * @see [[JavaConverters.asJavaEnumeration]] */ - implicit def `enumeration asJava`[A](it: Iterator[A]): ju.Enumeration[A] = asJavaEnumeration(it) + implicit def `enumeration asJava`[A](it: Iterator[A] | Null): ju.Enumeration[A] | Null = asJavaEnumeration(it) /** Implicitly converts a Scala `Iterable` to a Java `Iterable`. * @see [[JavaConverters.asJavaIterable]] */ - implicit def `iterable asJava`[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i) + implicit def `iterable asJava`[A](i: Iterable[A] | Null): jl.Iterable[A] | Null = asJavaIterable(i) /** Implicitly converts a Scala `Iterable` to an immutable Java `Collection`. * @see [[JavaConverters.asJavaCollection]] */ - implicit def `collection asJava`[A](it: Iterable[A]): ju.Collection[A] = asJavaCollection(it) + implicit def `collection asJava`[A](it: Iterable[A] | Null): ju.Collection[A] | Null = asJavaCollection(it) /** Implicitly converts a Scala mutable `Buffer` to a Java `List`. * @see [[JavaConverters.bufferAsJavaList]] */ - implicit def `buffer AsJavaList`[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b) + implicit def `buffer AsJavaList`[A](b: mutable.Buffer[A] | Null): ju.List[A] | Null = bufferAsJavaList(b) /** Implicitly converts a Scala mutable `Seq` to a Java `List`. * @see [[JavaConverters.mutableSeqAsJavaList]] */ - implicit def `mutableSeq AsJavaList`[A](seq: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(seq) + implicit def `mutableSeq AsJavaList`[A](seq: mutable.Seq[A] | Null): ju.List[A] | Null = mutableSeqAsJavaList(seq) /** Implicitly converts a Scala `Seq` to a Java `List`. * @see [[JavaConverters.seqAsJavaList]] */ - implicit def `seq AsJavaList`[A](seq: Seq[A]): ju.List[A] = seqAsJavaList(seq) + implicit def `seq AsJavaList`[A](seq: Seq[A] | Null): ju.List[A] | Null = seqAsJavaList(seq) /** Implicitly converts a Scala mutable `Set` to a Java `Set`. * @see [[JavaConverters.mutableSetAsJavaSet]] */ - implicit def `mutableSet AsJavaSet`[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s) + implicit def `mutableSet AsJavaSet`[A](s: mutable.Set[A] | Null): ju.Set[A] | Null = mutableSetAsJavaSet(s) /** Implicitly converts a Scala `Set` to a Java `Set`. * @see [[JavaConverters.setAsJavaSet]] */ - implicit def `set AsJavaSet`[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s) + implicit def `set AsJavaSet`[A](s: Set[A] | Null): ju.Set[A] | Null = setAsJavaSet(s) /** Implicitly converts a Scala mutable `Map` to a Java `Map`. * @see [[JavaConverters.mutableMapAsJavaMap]] */ - implicit def `mutableMap AsJavaMap`[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m) + implicit def `mutableMap AsJavaMap`[K, V](m: mutable.Map[K, V] | Null): ju.Map[K, V] | Null = mutableMapAsJavaMap(m) /** Implicitly converts a Scala mutable `Map` to a Java `Dictionary`. * @see [[JavaConverters.asJavaDictionary]] */ - implicit def `dictionary asJava`[K, V](m: mutable.Map[K, V]): ju.Dictionary[K, V] = asJavaDictionary(m) + implicit def `dictionary asJava`[K, V](m: mutable.Map[K, V] | Null): ju.Dictionary[K, V] | Null = asJavaDictionary(m) /** Implicitly converts a Scala `Map` to a Java `Map`. * @see [[JavaConverters.mapAsJavaMap]] */ - implicit def `map AsJavaMap`[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m) + implicit def `map AsJavaMap`[K, V](m: Map[K, V] | Null): ju.Map[K, V] | Null = mapAsJavaMap(m) /** Implicitly converts a Scala mutable `concurrent.Map` to a Java `ConcurrentMap`. * @see [[JavaConverters.mapAsJavaConcurrentMap]] */ - implicit def `map AsJavaConcurrentMap`[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m) + implicit def `map AsJavaConcurrentMap`[K, V](m: concurrent.Map[K, V] | Null): juc.ConcurrentMap[K, V] | Null = mapAsJavaConcurrentMap(m) } /** diff --git a/library/src/scala/collection/convert/JavaCollectionWrappers.scala b/library/src/scala/collection/convert/JavaCollectionWrappers.scala index 5058f93fc48f..a891f7787454 100644 --- a/library/src/scala/collection/convert/JavaCollectionWrappers.scala +++ b/library/src/scala/collection/convert/JavaCollectionWrappers.scala @@ -87,7 +87,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { extends AbstractIterable[A] with StrictOptimizedIterableOps[A, Iterable, Iterable[A]] with Serializable { - def iterator = underlying.iterator.asScala + def iterator = underlying.iterator.asScala.nn override def iterableFactory: mutable.ArrayBuffer.type = mutable.ArrayBuffer override def isEmpty: Boolean = !underlying.iterator().hasNext override def equals(other: Any): Boolean = other match { @@ -102,7 +102,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { extends AbstractIterable[A] with StrictOptimizedIterableOps[A, Iterable, Iterable[A]] with Serializable { - def iterator = underlying.iterator.asScala + def iterator: Iterator[A] = underlying.iterator.asScala.nn override def size = underlying.size override def knownSize: Int = if (underlying.isEmpty) 0 else super.knownSize override def isEmpty = underlying.isEmpty @@ -147,7 +147,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { def length = underlying.size override def knownSize: Int = if (underlying.isEmpty) 0 else super.knownSize override def isEmpty = underlying.isEmpty - override def iterator: Iterator[A] = underlying.iterator.asScala + override def iterator: Iterator[A] = underlying.iterator.asScala.nn def apply(i: Int) = underlying.get(i) def update(i: Int, elem: A) = underlying.set(i, elem) def prepend(elem: A) = { underlying.subList(0, 0) add elem; this } @@ -224,7 +224,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { override def size: Int = underlying.size override def isEmpty: Boolean = underlying.isEmpty override def knownSize: Int = if (underlying.isEmpty) 0 else super.knownSize - def iterator: Iterator[A] = underlying.iterator.asScala + def iterator: Iterator[A] = underlying.iterator.asScala.nn def contains(elem: A): Boolean = underlying.contains(elem) @@ -524,8 +524,8 @@ private[collection] object JavaCollectionWrappers extends Serializable { class DictionaryWrapper[K, V](val underlying: mutable.Map[K, V]) extends ju.Dictionary[K, V] with Serializable { def size: Int = underlying.size def isEmpty: Boolean = underlying.isEmpty - def keys: ju.Enumeration[K] = underlying.keysIterator.asJavaEnumeration - def elements: ju.Enumeration[V] = underlying.valuesIterator.asJavaEnumeration + def keys: ju.Enumeration[K] = underlying.keysIterator.asJavaEnumeration.nn + def elements: ju.Enumeration[V] = underlying.valuesIterator.asJavaEnumeration.nn def get(key: AnyRef) = try { underlying get key.asInstanceOf[K] match { case None => null.asInstanceOf[V] @@ -571,7 +571,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { override def update(k: K, v: V): Unit = { underlying.put(k, v) } override def remove(k: K): Option[V] = Option(underlying remove k) - def iterator = underlying.keys.asScala map (k => (k, underlying get k)) + def iterator = underlying.keys.asScala.nn map (k => (k, underlying get k)) override def clear() = iterator.foreach(entry => underlying.remove(entry._1)) diff --git a/library/src/scala/collection/convert/StreamExtensions.scala b/library/src/scala/collection/convert/StreamExtensions.scala index 5e70ed1b4fd0..f77f59c8df47 100644 --- a/library/src/scala/collection/convert/StreamExtensions.scala +++ b/library/src/scala/collection/convert/StreamExtensions.scala @@ -271,7 +271,7 @@ trait StreamExtensions { else if (info.companion == LongAccumulator) stream.asInstanceOf[Stream[Long]].collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger).asInstanceOf[C1] else if (info.companion == DoubleAccumulator) stream.asInstanceOf[Stream[Double]].collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger).asInstanceOf[C1] else if (stream.isParallel) anyAcc.to(factory) - else factory.fromSpecific(stream.iterator.asScala) + else factory.fromSpecific(stream.iterator.asScala.nn) } /** Convert a generic Java Stream wrapping a primitive type to a corresponding primitive @@ -303,7 +303,7 @@ trait StreamExtensions { if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Int], AnyAccumulator.unboxedIntAdder, AnyAccumulator.merger[Int]).asInstanceOf[C1] else if (info.companion == IntAccumulator) intAcc.asInstanceOf[C1] else if (stream.isParallel) intAcc.to(factory) - else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Int]].asScala) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Int]].asScala.nn) } } @@ -330,7 +330,7 @@ trait StreamExtensions { if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Long], AnyAccumulator.unboxedLongAdder, AnyAccumulator.merger[Long]).asInstanceOf[C1] else if (info.companion == LongAccumulator) longAcc.asInstanceOf[C1] else if (stream.isParallel) longAcc.to(factory) - else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Long]].asScala) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Long]].asScala.nn) } } @@ -357,7 +357,7 @@ trait StreamExtensions { if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Double], AnyAccumulator.unboxedDoubleAdder, AnyAccumulator.merger[Double]).asInstanceOf[C1] else if (info.companion == DoubleAccumulator) doubleAcc.asInstanceOf[C1] else if (stream.isParallel) doubleAcc.to(factory) - else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Double]].asScala) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Double]].asScala.nn) } } } @@ -449,31 +449,31 @@ object StreamExtensions { * `noAccumulatorFactoryInfo` is passed. */ trait AccumulatorFactoryInfo[A, C] { - val companion: AnyRef + val companion: AnyRef | Null } trait LowPriorityAccumulatorFactoryInfo { implicit def noAccumulatorFactoryInfo[A, C]: AccumulatorFactoryInfo[A, C] = noAccumulatorFactoryInfoPrototype.asInstanceOf[AccumulatorFactoryInfo[A, C]] private val noAccumulatorFactoryInfoPrototype: AccumulatorFactoryInfo[AnyRef, AnyRef] = new AccumulatorFactoryInfo[AnyRef, AnyRef] { - val companion: AnyRef = null + val companion: AnyRef | Null = null } } object AccumulatorFactoryInfo extends LowPriorityAccumulatorFactoryInfo { implicit def anyAccumulatorFactoryInfo[A]: AccumulatorFactoryInfo[A, AnyAccumulator[A]] = anyAccumulatorFactoryInfoPrototype.asInstanceOf[AccumulatorFactoryInfo[A, AnyAccumulator[A]]] private object anyAccumulatorFactoryInfoPrototype extends AccumulatorFactoryInfo[AnyRef, AnyAccumulator[AnyRef]] { - val companion: AnyRef = AnyAccumulator + val companion: AnyRef | Null = null } implicit val intAccumulatorFactoryInfo: AccumulatorFactoryInfo[Int, IntAccumulator] = new AccumulatorFactoryInfo[Int, IntAccumulator] { - val companion: AnyRef = IntAccumulator + val companion: AnyRef | Null = IntAccumulator } implicit val longAccumulatorFactoryInfo: AccumulatorFactoryInfo[Long, LongAccumulator] = new AccumulatorFactoryInfo[Long, LongAccumulator] { - val companion: AnyRef = LongAccumulator + val companion: AnyRef | Null = LongAccumulator } implicit val doubleAccumulatorFactoryInfo: AccumulatorFactoryInfo[Double, DoubleAccumulator] = new AccumulatorFactoryInfo[Double, DoubleAccumulator] { - val companion: AnyRef = DoubleAccumulator + val companion: AnyRef | Null = DoubleAccumulator } implicit val jIntegerAccumulatorFactoryInfo: AccumulatorFactoryInfo[jl.Integer, IntAccumulator] = intAccumulatorFactoryInfo.asInstanceOf[AccumulatorFactoryInfo[jl.Integer, IntAccumulator]] diff --git a/library/src/scala/collection/convert/impl/ArrayStepper.scala b/library/src/scala/collection/convert/impl/ArrayStepper.scala index b53dab574909..bed14aec8739 100644 --- a/library/src/scala/collection/convert/impl/ArrayStepper.scala +++ b/library/src/scala/collection/convert/impl/ArrayStepper.scala @@ -16,7 +16,7 @@ package impl import scala.language.`2.13` import scala.collection._ -private[collection] class ObjectArrayStepper[A <: Object](underlying: Array[A], _i0: Int, _iN: Int) +private[collection] class ObjectArrayStepper[A <: Object | Null](underlying: Array[A], _i0: Int, _iN: Int) extends IndexedStepperBase[AnyStepper[A], ObjectArrayStepper[A]](_i0, _iN) with AnyStepper[A] { def nextStep(): A = if (hasStep) { val j = i0; i0 += 1; underlying(j) } else Stepper.throwNSEE() diff --git a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala index 87823ced9cee..4e8a844c1ac8 100644 --- a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala +++ b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala @@ -14,6 +14,8 @@ package scala.collection.convert package impl import scala.language.`2.13` +import scala.language.unsafeNulls + import java.util.Spliterator import annotation.tailrec @@ -22,7 +24,7 @@ import scala.collection._ private[collection] object BinaryTreeStepper { - val emptyStack = new Array[AnyRef](0) + val emptyStack = new Array[AnyRef | Null](0) } @@ -45,8 +47,8 @@ private[collection] object BinaryTreeStepper { * Subclasses should allow this class to do all the work of maintaining state; `next` should simply * reduce `maxLength` by one, and consume `myCurrent` and set it to `null` if `hasNext` is true. */ -private[collection] abstract class BinaryTreeStepperBase[A, T >: Null <: AnyRef, Sub >: Null, Semi <: Sub with BinaryTreeStepperBase[A, T, _, _]]( - protected var maxLength: Int, protected var myCurrent: T, protected var stack: Array[AnyRef], protected var index: Int, +private[collection] abstract class BinaryTreeStepperBase[A, T <: AnyRef, Sub, Semi <: Sub with BinaryTreeStepperBase[A, T, _, _]]( + protected var maxLength: Int, protected var myCurrent: T | Null, protected var stack: Array[AnyRef | Null], protected var index: Int, protected val left: T => T, protected val right: T => T ) extends EfficientSplit { @@ -101,7 +103,7 @@ extends EfficientSplit { myCurrent = detach(unroll(root)) } - protected def semiclone(maxL: Int, myC: T, stk: Array[AnyRef], ix: Int): Semi + protected def semiclone(maxL: Int, myC: T | Null, stk: Array[AnyRef | Null], ix: Int): Semi def characteristics: Int = Spliterator.ORDERED @@ -122,11 +124,11 @@ extends EfficientSplit { * * If the tree is empty or only has one element left, it returns `null` instead of splitting. */ - def trySplit(): Sub = + def trySplit(): Sub | Null = if (!hasStep || index < 0) null else { val root = stack(0).asInstanceOf[T] - val leftStack = + val leftStack = if (index > 0) java.util.Arrays.copyOfRange(stack, 1, index+1) else BinaryTreeStepper.emptyStack val leftIndex = index - 1 @@ -142,25 +144,25 @@ extends EfficientSplit { } -private[collection] final class AnyBinaryTreeStepper[A, T >: Null <: AnyRef]( - _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _index: Int, _left: T => T, _right: T => T, protected val extract: T => A +private[collection] final class AnyBinaryTreeStepper[A, T <: AnyRef]( + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T, _right: T => T, protected val extract: T => A ) extends BinaryTreeStepperBase[A, T, AnyStepper[A], AnyBinaryTreeStepper[A, T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with AnyStepper[A] { def nextStep(): A = if (hasStep) { - val ans = extract(myCurrent) + val ans = extract(myCurrent.nn) myCurrent = null maxLength -= 1 ans } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef], ix: Int): AnyBinaryTreeStepper[A, T] = + def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): AnyBinaryTreeStepper[A, T] = new AnyBinaryTreeStepper[A, T](maxL, myC, stk, ix, left, right, extract) } private[collection] object AnyBinaryTreeStepper { - def from[A, T >: Null <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => A): AnyBinaryTreeStepper[A, T] = { + def from[A, T <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => A): AnyBinaryTreeStepper[A, T] = { val ans = new AnyBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans @@ -168,25 +170,25 @@ private[collection] object AnyBinaryTreeStepper { } -private[collection] final class DoubleBinaryTreeStepper[T >: Null <: AnyRef]( - _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _index: Int, _left: T => T, _right: T => T, protected val extract: T => Double +private[collection] final class DoubleBinaryTreeStepper[T <: AnyRef]( + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T, _right: T => T, protected val extract: T => Double ) extends BinaryTreeStepperBase[Double, T, DoubleStepper, DoubleBinaryTreeStepper[T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with DoubleStepper { def nextStep(): Double = if (hasStep) { - val ans = extract(myCurrent) + val ans = extract(myCurrent.nn) myCurrent = null maxLength -= 1 ans } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef], ix: Int): DoubleBinaryTreeStepper[T] = + def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): DoubleBinaryTreeStepper[T] = new DoubleBinaryTreeStepper[T](maxL, myC, stk, ix, left, right, extract) } private [collection] object DoubleBinaryTreeStepper { - def from[T >: Null <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Double): DoubleBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Double): DoubleBinaryTreeStepper[T] = { val ans = new DoubleBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans @@ -194,25 +196,25 @@ private [collection] object DoubleBinaryTreeStepper { } -private[collection] final class IntBinaryTreeStepper[T >: Null <: AnyRef]( - _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _index: Int, _left: T => T, _right: T => T, protected val extract: T => Int +private[collection] final class IntBinaryTreeStepper[T <: AnyRef]( + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T, _right: T => T, protected val extract: T => Int ) extends BinaryTreeStepperBase[Int, T, IntStepper, IntBinaryTreeStepper[T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with IntStepper { def nextStep(): Int = if (hasStep) { - val ans = extract(myCurrent) + val ans = extract(myCurrent.nn) myCurrent = null maxLength -= 1 ans } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef], ix: Int): IntBinaryTreeStepper[T] = + def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): IntBinaryTreeStepper[T] = new IntBinaryTreeStepper[T](maxL, myC, stk, ix, left, right, extract) } private [collection] object IntBinaryTreeStepper { - def from[T >: Null <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Int): IntBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Int): IntBinaryTreeStepper[T] = { val ans = new IntBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans @@ -221,25 +223,25 @@ private [collection] object IntBinaryTreeStepper { -private[collection] final class LongBinaryTreeStepper[T >: Null <: AnyRef]( - _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _index: Int, _left: T => T, _right: T => T, protected val extract: T => Long +private[collection] final class LongBinaryTreeStepper[T <: AnyRef]( + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T, _right: T => T, protected val extract: T => Long ) extends BinaryTreeStepperBase[Long, T, LongStepper, LongBinaryTreeStepper[T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with LongStepper { def nextStep(): Long = if (hasStep) { - val ans = extract(myCurrent) + val ans = extract(myCurrent.nn) myCurrent = null maxLength -= 1 ans } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef], ix: Int): LongBinaryTreeStepper[T] = + def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): LongBinaryTreeStepper[T] = new LongBinaryTreeStepper[T](maxL, myC, stk, ix, left, right, extract) } private [collection] object LongBinaryTreeStepper { - def from[T >: Null <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Long): LongBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Long): LongBinaryTreeStepper[T] = { val ans = new LongBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans diff --git a/library/src/scala/collection/convert/impl/BitSetStepper.scala b/library/src/scala/collection/convert/impl/BitSetStepper.scala index a7fa44685d80..d653e969a001 100644 --- a/library/src/scala/collection/convert/impl/BitSetStepper.scala +++ b/library/src/scala/collection/convert/impl/BitSetStepper.scala @@ -19,8 +19,8 @@ import scala.collection.{BitSetOps, IntStepper, Stepper} private[collection] final class BitSetStepper( - private var underlying: BitSetOps[_], - private var cache0: Long, private var cache1: Long, + private var underlying: BitSetOps[_] | Null, + private var cache0: Long, private var cache1: Long, _i0: Int, _iN: Int, private var cacheIndex: Int ) @@ -48,15 +48,15 @@ with IntStepper { findNext() } } - else if (underlying eq null) { + else if (underlying eq null) { i0 = iN found = false found } else { cacheIndex = ix - cache0 = underlying.word(cacheIndex) - cache1 = if ((iN - 1) >> LogWL == ix) -1L else underlying.word(cacheIndex+1) + cache0 = underlying.nn.word(cacheIndex) + cache1 = if ((iN - 1) >> LogWL == ix) -1L else underlying.nn.word(cacheIndex+1) findNext() } } @@ -79,8 +79,8 @@ with IntStepper { // Advance old stepper to breakpoint val ixOld0 = half >> LogWL if (ixOld0 > cacheIndex + 1) { - cache0 = underlying.word(ixOld0) - cache1 = if (((iN - 1) >> LogWL) == ixOld0) -1L else underlying.word(ixOld0+1) + cache0 = underlying.nn.word(ixOld0) + cache1 = if (((iN - 1) >> LogWL) == ixOld0) -1L else underlying.nn.word(ixOld0+1) cacheIndex = ixOld0 i0 = half found = false @@ -97,7 +97,7 @@ with IntStepper { else scanLong(bits, from + 1) def nextStep(): Int = - if (found || findNext()) { + if (found || findNext()) { found = false val ans = i0 i0 += 1 diff --git a/library/src/scala/collection/convert/impl/ChampStepper.scala b/library/src/scala/collection/convert/impl/ChampStepper.scala index 2973cd1ba9d2..05589f1ee04d 100644 --- a/library/src/scala/collection/convert/impl/ChampStepper.scala +++ b/library/src/scala/collection/convert/impl/ChampStepper.scala @@ -23,7 +23,7 @@ import scala.collection.immutable.Node * to the end of all trees. */ private[collection] abstract class ChampStepperBase[ - A, T <: Node[T], Sub >: Null, Semi <: Sub with ChampStepperBase[A, T, _, _] + A, T <: Node[T], Sub, Semi <: Sub with ChampStepperBase[A, T, _, _] ](protected var maxSize: Int) extends EfficientSplit { import Node.MaxDepth @@ -109,7 +109,7 @@ extends EfficientSplit { ans } - final def trySplit(): Sub = + final def trySplit(): Sub | Null = if (!hasStep) null else { var fork = 0 @@ -157,7 +157,7 @@ extends EfficientSplit { } -private[collection] final class AnyChampStepper[A, T >: Null <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => A) +private[collection] final class AnyChampStepper[A, T <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => A) extends ChampStepperBase[A, T, AnyStepper[A], AnyChampStepper[A, T]](_maxSize) with AnyStepper[A] { def nextStep(): A = @@ -172,14 +172,14 @@ with AnyStepper[A] { def semiclone(): AnyChampStepper[A, T] = new AnyChampStepper[A, T](0, extract) } private[collection] object AnyChampStepper { - def from[A, T >: Null <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => A): AnyChampStepper[A, T] = { + def from[A, T <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => A): AnyChampStepper[A, T] = { val ans = new AnyChampStepper[A, T](maxSize, extract) ans.initRoot(root) ans } } -private[collection] final class DoubleChampStepper[T >: Null <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => Double) +private[collection] final class DoubleChampStepper[T <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => Double) extends ChampStepperBase[Double, T, DoubleStepper, DoubleChampStepper[T]](_maxSize) with DoubleStepper { def nextStep(): Double = @@ -194,14 +194,14 @@ with DoubleStepper { def semiclone(): DoubleChampStepper[T] = new DoubleChampStepper[T](0, extract) } private[collection] object DoubleChampStepper { - def from[T >: Null <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => Double): DoubleChampStepper[T] = { + def from[T <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => Double): DoubleChampStepper[T] = { val ans = new DoubleChampStepper[T](maxSize, extract) ans.initRoot(root) ans } } -private[collection] final class IntChampStepper[T >: Null <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => Int) +private[collection] final class IntChampStepper[T <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => Int) extends ChampStepperBase[Int, T, IntStepper, IntChampStepper[T]](_maxSize) with IntStepper { def nextStep(): Int = @@ -216,14 +216,14 @@ with IntStepper { def semiclone(): IntChampStepper[T] = new IntChampStepper[T](0, extract) } private[collection] object IntChampStepper { - def from[T >: Null <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => Int): IntChampStepper[T] = { + def from[T <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => Int): IntChampStepper[T] = { val ans = new IntChampStepper[T](maxSize, extract) ans.initRoot(root) ans } } -private[collection] final class LongChampStepper[T >: Null <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => Long) +private[collection] final class LongChampStepper[T <: Node[T]](_maxSize: Int, protected val extract: (T, Int) => Long) extends ChampStepperBase[Long, T, LongStepper, LongChampStepper[T]](_maxSize) with LongStepper { def nextStep(): Long = @@ -238,7 +238,7 @@ with LongStepper { def semiclone(): LongChampStepper[T] = new LongChampStepper[T](0, extract) } private[collection] object LongChampStepper { - def from[T >: Null <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => Long): LongChampStepper[T] = { + def from[T <: Node[T]](maxSize: Int, root: T, extract: (T, Int) => Long): LongChampStepper[T] = { val ans = new LongChampStepper[T](maxSize, extract) ans.initRoot(root) ans diff --git a/library/src/scala/collection/convert/impl/InOrderStepperBase.scala b/library/src/scala/collection/convert/impl/InOrderStepperBase.scala index 544bfff010d8..92706e95d004 100644 --- a/library/src/scala/collection/convert/impl/InOrderStepperBase.scala +++ b/library/src/scala/collection/convert/impl/InOrderStepperBase.scala @@ -23,7 +23,7 @@ import scala.collection.Stepper.EfficientSplit * * For collections that are guaranteed to not have gaps, use `IndexedStepperBase` instead. */ -private[convert] abstract class InOrderStepperBase[Sub >: Null, Semi <: Sub](protected var i0: Int, protected var iN: Int) +private[convert] abstract class InOrderStepperBase[Sub, Semi <: Sub](protected var i0: Int, protected var iN: Int) extends EfficientSplit { /** Set `true` if the element at `i0` is known to be there. `false` if either not known or is a gap. */ @@ -42,7 +42,7 @@ extends EfficientSplit { def estimateSize: Long = iN - i0 - def trySplit(): Sub = { + def trySplit(): Sub | Null = { if (iN-1 > i0) { val half = (i0 + iN) >>> 1 val ans = semiclone(half) diff --git a/library/src/scala/collection/convert/impl/IndexedStepperBase.scala b/library/src/scala/collection/convert/impl/IndexedStepperBase.scala index 3acb743e7c57..cc649bf09901 100644 --- a/library/src/scala/collection/convert/impl/IndexedStepperBase.scala +++ b/library/src/scala/collection/convert/impl/IndexedStepperBase.scala @@ -19,7 +19,7 @@ import java.util.Spliterator import scala.collection.Stepper.EfficientSplit /** Abstracts all the generic operations of stepping over an indexable collection */ -private[convert] abstract class IndexedStepperBase[Sub >: Null, Semi <: Sub](protected var i0: Int, protected var iN: Int) +private[convert] abstract class IndexedStepperBase[Sub, Semi <: Sub](protected var i0: Int, protected var iN: Int) extends EfficientSplit { protected def semiclone(half: Int): Semi @@ -29,7 +29,7 @@ private[convert] abstract class IndexedStepperBase[Sub >: Null, Semi <: Sub](pro def estimateSize: Long = iN - i0 - def trySplit(): Sub = { + def trySplit(): Sub | Null = { if (iN-1 > i0) { val half = (i0+iN) >>> 1 val ans = semiclone(half) diff --git a/library/src/scala/collection/convert/impl/IteratorStepper.scala b/library/src/scala/collection/convert/impl/IteratorStepper.scala index 9f8aab9c2165..7e42f9bb75f3 100644 --- a/library/src/scala/collection/convert/impl/IteratorStepper.scala +++ b/library/src/scala/collection/convert/impl/IteratorStepper.scala @@ -19,21 +19,21 @@ import java.util.Spliterator import scala.collection.{AnyStepper, DoubleStepper, IntStepper, LongStepper, Stepper} import scala.jdk.{AnyAccumulator, DoubleAccumulator, IntAccumulator, LongAccumulator} -private[collection] class AnyIteratorStepper[A](_underlying: Iterator[A]) +private[collection] class AnyIteratorStepper[A](_underlying: Iterator[A] | Null) extends IteratorStepperBase[A, AnyStepper[A], AnyIteratorStepper[A]](_underlying) with AnyStepper[A] { protected def semiclone(): AnyIteratorStepper[A] = new AnyIteratorStepper(null) - def nextStep(): A = if (proxied ne null) proxied.nextStep() else underlying.next() + def nextStep(): A = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() - def trySplit(): AnyStepper[A] = if (proxied ne null) proxied.trySplit() else { + def trySplit(): AnyStepper[A] | Null = if (proxied ne null) proxied.nn.trySplit() else { val acc = new AnyAccumulator[A] var i = 0 val n = nextChunkSize & 0xFFFFFFFC - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { + while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } + if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.trySplit() + proxied.nn.trySplit() } else { val ans = semiclone() @@ -44,21 +44,21 @@ private[collection] class AnyIteratorStepper[A](_underlying: Iterator[A]) } } -private[collection] class DoubleIteratorStepper(_underlying: Iterator[Double]) +private[collection] class DoubleIteratorStepper(_underlying: Iterator[Double] | Null) extends IteratorStepperBase[Double, DoubleStepper, DoubleIteratorStepper](_underlying) with DoubleStepper { protected def semiclone(): DoubleIteratorStepper = new DoubleIteratorStepper(null) - def nextStep(): Double = if (proxied ne null) proxied.nextStep() else underlying.next() + def nextStep(): Double = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() - def trySplit(): DoubleStepper = if (proxied ne null) proxied.trySplit() else { + def trySplit(): DoubleStepper | Null = if (proxied ne null) proxied.nn.trySplit() else { val acc = new DoubleAccumulator var i = 0 val n = nextChunkSize & 0xFFFFFFFC - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { + while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } + if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.trySplit() + proxied.nn.trySplit() } else { val ans = semiclone() @@ -69,21 +69,21 @@ private[collection] class DoubleIteratorStepper(_underlying: Iterator[Double]) } } -private[collection] class IntIteratorStepper(_underlying: Iterator[Int]) +private[collection] class IntIteratorStepper(_underlying: Iterator[Int] | Null) extends IteratorStepperBase[Int, IntStepper, IntIteratorStepper](_underlying) with IntStepper { protected def semiclone(): IntIteratorStepper = new IntIteratorStepper(null) - def nextStep(): Int = if (proxied ne null) proxied.nextStep() else underlying.next() + def nextStep(): Int = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() - def trySplit(): IntStepper = if (proxied ne null) proxied.trySplit() else { + def trySplit(): IntStepper | Null = if (proxied ne null) proxied.nn.trySplit() else { val acc = new IntAccumulator var i = 0 val n = nextChunkSize & 0xFFFFFFFC - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { + while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } + if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.trySplit() + proxied.nn.trySplit() } else { val ans = semiclone() @@ -94,21 +94,21 @@ private[collection] class IntIteratorStepper(_underlying: Iterator[Int]) } } -private[collection] class LongIteratorStepper(_underlying: Iterator[Long]) +private[collection] class LongIteratorStepper(_underlying: Iterator[Long] | Null) extends IteratorStepperBase[Long, LongStepper, LongIteratorStepper](_underlying) with LongStepper { protected def semiclone(): LongIteratorStepper = new LongIteratorStepper(null) - def nextStep(): Long = if (proxied ne null) proxied.nextStep() else underlying.next() + def nextStep(): Long = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() - def trySplit(): LongStepper = if (proxied ne null) proxied.trySplit() else { + def trySplit(): LongStepper | Null = if (proxied ne null) proxied.nn.trySplit() else { val acc = new LongAccumulator var i = 0 val n = nextChunkSize & 0xFFFFFFFC - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { + while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } + if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.trySplit() + proxied.nn.trySplit() } else { val ans = semiclone() @@ -120,11 +120,12 @@ private[collection] class LongIteratorStepper(_underlying: Iterator[Long]) } /** Common functionality for Steppers that step through an Iterator, caching the results as needed when a split is requested. */ -private[convert] abstract class IteratorStepperBase[A, SP >: Null <: Stepper[A], Semi <: SP](final protected val underlying: Iterator[A]) { +private[convert] abstract class IteratorStepperBase[A, SP <: Stepper[A], Semi <: SP](final protected val underlying: Iterator[A] | Null) { final protected var nextChunkSize = 16 - final protected var proxied: SP = null + @annotation.stableNull + final protected var proxied: SP | Null = null protected def semiclone(): Semi // Must initialize with null iterator! def characteristics: Int = if (proxied ne null) Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED else Spliterator.ORDERED - def estimateSize: Long = if (proxied ne null) proxied.estimateSize else Long.MaxValue - def hasStep: Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext + def estimateSize: Long = if (proxied ne null) proxied.nn.estimateSize else Long.MaxValue + def hasStep: Boolean = if (proxied ne null) proxied.nn.hasStep else underlying.nn.hasNext } diff --git a/library/src/scala/collection/convert/impl/RangeStepper.scala b/library/src/scala/collection/convert/impl/RangeStepper.scala index 283975ff0332..ca600a3cf5a1 100644 --- a/library/src/scala/collection/convert/impl/RangeStepper.scala +++ b/library/src/scala/collection/convert/impl/RangeStepper.scala @@ -28,11 +28,11 @@ with IntStepper { val ans = myNext myNext += myStep i0 += 1 - ans + ans } else Stepper.throwNSEE() protected def semiclone(half: Int): RangeStepper = new RangeStepper(myNext, myStep, i0, half) - override def trySplit(): IntStepper = { + override def trySplit(): IntStepper | Null = { val old_i0 = i0 val ans = super.trySplit() myNext += (i0 - old_i0) * myStep diff --git a/library/src/scala/collection/convert/impl/StringStepper.scala b/library/src/scala/collection/convert/impl/StringStepper.scala index 72d4e67ef1cb..f824375b668d 100644 --- a/library/src/scala/collection/convert/impl/StringStepper.scala +++ b/library/src/scala/collection/convert/impl/StringStepper.scala @@ -47,7 +47,7 @@ extends IntStepper with EfficientSplit { } else Stepper.throwNSEE() } - def trySplit(): CodePointStringStepper = + def trySplit(): CodePointStringStepper | Null = if (iN - 3 > i0) { var half = (i0 + iN) >>> 1 if (isLowSurrogate(underlying.charAt(half))) half -= 1 diff --git a/library/src/scala/collection/convert/impl/TableStepper.scala b/library/src/scala/collection/convert/impl/TableStepper.scala index 324732a0c2d1..089fe6bf12af 100644 --- a/library/src/scala/collection/convert/impl/TableStepper.scala +++ b/library/src/scala/collection/convert/impl/TableStepper.scala @@ -17,12 +17,12 @@ import scala.language.`2.13` import scala.collection.Stepper.EfficientSplit import scala.collection._ -private[collection] abstract class TableStepperBase[A, I >: Null <: AnyRef, Sub >: Null, Semi <: Sub with TableStepperBase[A, I, _, _]]( +private[collection] abstract class TableStepperBase[A, I <: AnyRef, Sub, Semi <: Sub with TableStepperBase[A, I, _, _]]( protected var maxLength: Int, protected val table: Array[I], protected var i0: Int, protected val iN: Int ) extends EfficientSplit { // Always holds table(i0); if `null` it is time to switch to the next element - protected var myCurrent: I = if (i0 < iN) table(i0) else null + protected var myCurrent: I | Null = if (i0 < iN) table(i0) else null // Only call this when `myCurrent` is null (meaning we need to advance) @annotation.tailrec @@ -46,7 +46,7 @@ extends EfficientSplit { def hasStep: Boolean = (myCurrent ne null) || findNextCurrent() - def trySplit(): Sub = { + def trySplit(): Sub | Null = { if (iN-1 > i0 && maxLength > 0) { val half = (i0 + iN) >>> 1 val ans = semiclone(half) @@ -70,15 +70,15 @@ extends EfficientSplit { } -private[collection] final class AnyTableStepper[A, I >: Null <: AnyRef]( +private[collection] final class AnyTableStepper[A, I <: AnyRef]( _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => A, _i0: Int, _iN: Int ) extends TableStepperBase[A, I, AnyStepper[A], AnyTableStepper[A, I]](_maxLength, _table, _i0, _iN) with AnyStepper[A] { def nextStep(): A = if (hasStep) { - val ans = extract(myCurrent) - myCurrent = iterate(myCurrent) + val ans = extract(myCurrent.nn) + myCurrent = iterate(myCurrent.nn) ans } else Stepper.throwNSEE() @@ -87,15 +87,15 @@ with AnyStepper[A] { } -private[collection] final class DoubleTableStepper[I >: Null <: AnyRef]( +private[collection] final class DoubleTableStepper[I <: AnyRef]( _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Double, _i0: Int, _iN: Int ) extends TableStepperBase[Double, I, DoubleStepper, DoubleTableStepper[I]](_maxLength, _table, _i0, _iN) with DoubleStepper { def nextStep(): Double = if (hasStep) { - val ans = extract(myCurrent) - myCurrent = iterate(myCurrent) + val ans = extract(myCurrent.nn) + myCurrent = iterate(myCurrent.nn) ans } else Stepper.throwNSEE() @@ -104,15 +104,15 @@ with DoubleStepper { } -private[collection] final class IntTableStepper[I >: Null <: AnyRef]( +private[collection] final class IntTableStepper[I <: AnyRef]( _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Int, _i0: Int, _iN: Int ) extends TableStepperBase[Int, I, IntStepper, IntTableStepper[I]](_maxLength, _table, _i0, _iN) with IntStepper { def nextStep(): Int = if (hasStep) { - val ans = extract(myCurrent) - myCurrent = iterate(myCurrent) + val ans = extract(myCurrent.nn) + myCurrent = iterate(myCurrent.nn) ans } else Stepper.throwNSEE() @@ -121,15 +121,15 @@ with IntStepper { } -private[collection] final class LongTableStepper[I >: Null <: AnyRef]( +private[collection] final class LongTableStepper[I <: AnyRef]( _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Long, _i0: Int, _iN: Int ) extends TableStepperBase[Long, I, LongStepper, LongTableStepper[I]](_maxLength, _table, _i0, _iN) with LongStepper { def nextStep(): Long = if (hasStep) { - val ans = extract(myCurrent) - myCurrent = iterate(myCurrent) + val ans = extract(myCurrent.nn) + myCurrent = iterate(myCurrent.nn) ans } else Stepper.throwNSEE() diff --git a/library/src/scala/collection/convert/impl/VectorStepper.scala b/library/src/scala/collection/convert/impl/VectorStepper.scala index 85f349922f48..750b3cd55e97 100644 --- a/library/src/scala/collection/convert/impl/VectorStepper.scala +++ b/library/src/scala/collection/convert/impl/VectorStepper.scala @@ -16,7 +16,7 @@ package impl import scala.language.`2.13` import scala.collection._ -private[convert] abstract class VectorStepperBase[Sub >: Null, Semi <: Sub]( +private[convert] abstract class VectorStepperBase[Sub, Semi <: Sub]( _i0: Int, _iN: Int, protected val displayN: Int, @@ -24,9 +24,9 @@ private[convert] abstract class VectorStepperBase[Sub >: Null, Semi <: Sub]( ) extends IndexedStepperBase[Sub, Semi](_i0, _iN) { protected var index: Int = 32 // Force an advanceData on the first element - protected var leaves: Array[AnyRef] = null + protected var leaves: Array[AnyRef] = _ protected var index1: Int = 32 // Force advanceData to defer to initTo on the first element - protected var twigs: Array[AnyRef] = null + protected var twigs: Array[AnyRef] = _ protected final def advanceData(iX: Int): Unit = { index1 += 1 @@ -92,7 +92,7 @@ with DoubleStepper { index1 = 32 i0 = half ans - } + } } private[collection] class IntVectorStepper(_i0: Int, _iN: Int, _displayN: Int, _trunk: Array[AnyRef]) @@ -110,7 +110,7 @@ with IntStepper { index1 = 32 i0 = half ans - } + } } private[collection] class LongVectorStepper(_i0: Int, _iN: Int, _displayN: Int, _trunk: Array[AnyRef]) @@ -128,5 +128,5 @@ with LongStepper { index1 = 32 i0 = half ans - } + } } diff --git a/library/src/scala/collection/immutable/ArraySeq.scala b/library/src/scala/collection/immutable/ArraySeq.scala index 76e6097fca50..619470633e8e 100644 --- a/library/src/scala/collection/immutable/ArraySeq.scala +++ b/library/src/scala/collection/immutable/ArraySeq.scala @@ -92,7 +92,7 @@ sealed abstract class ArraySeq[+A] * * @return null if optimisation not possible. */ - private def appendedAllArraySeq[B >: A](that: ArraySeq[B]): ArraySeq[B] = { + private def appendedAllArraySeq[B >: A](that: ArraySeq[B]): ArraySeq[B] | Null = { // Optimise concatenation of two ArraySeqs // For ArraySeqs with sizes of [100, 1000, 10000] this is [3.5, 4.1, 5.2]x as fast if (isEmpty) @@ -283,11 +283,11 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self => def from[A](it: scala.collection.IterableOnce[A]^)(implicit tag: ClassTag[A]): ArraySeq[A] = it match { case as: ArraySeq[A] => as - case _ => unsafeWrapArray(Array.from[A](it)) + case _ => unsafeWrapArray(Array.from[A](it)).nn } def newBuilder[A : ClassTag]: Builder[A, ArraySeq[A]] = - ArrayBuffer.newBuilder[A].mapResult(b => unsafeWrapArray[A](b.toArray)) + ArrayBuffer.newBuilder[A].mapResult(b => unsafeWrapArray[A](b.toArray).nn) override def fill[A : ClassTag](n: Int)(elem: => A): ArraySeq[A] = tabulate(n)(_ => elem) @@ -298,7 +298,7 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self => ScalaRunTime.array_update(elements, i, f(i)) i = i + 1 } - ArraySeq.unsafeWrapArray(elements) + ArraySeq.unsafeWrapArray(elements).nn } /** @@ -313,7 +313,7 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self => * `ArraySeq.unsafeWrapArray(a.asInstanceOf[Array[Int]])` does not work, it throws a * `ClassCastException` at runtime. */ - def unsafeWrapArray[T](x: Array[T]): ArraySeq[T] = ((x: @unchecked) match { + def unsafeWrapArray[T](x: Array[T] | Null): ArraySeq[T] | Null = ((x: @unchecked) match { case null => null case x: Array[AnyRef] => new ofRef[AnyRef](x) case x: Array[Int] => new ofInt(x) @@ -328,7 +328,7 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self => }).asInstanceOf[ArraySeq[T]] @SerialVersionUID(3L) - final class ofRef[T <: AnyRef](val unsafeArray: Array[T]) extends ArraySeq[T] { + final class ofRef[T <: AnyRef | Null](val unsafeArray: Array[T]) extends ArraySeq[T] { def elemTag: ClassTag[T] = ClassTag[T](unsafeArray.getClass.getComponentType) def length: Int = unsafeArray.length @throws[ArrayIndexOutOfBoundsException] diff --git a/library/src/scala/collection/immutable/HashMap.scala b/library/src/scala/collection/immutable/HashMap.scala index 96d1d9cc0d8e..2ca7a7631422 100644 --- a/library/src/scala/collection/immutable/HashMap.scala +++ b/library/src/scala/collection/immutable/HashMap.scala @@ -161,7 +161,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: def removed(key: K): HashMap[K, V] = { val keyUnimprovedHash = key.## - newHashMapOrThis(rootNode.removed(key, keyUnimprovedHash, improve(keyUnimprovedHash), 0)) + newHashMapOrThis(rootNode.removed(key, keyUnimprovedHash, improve(keyUnimprovedHash), 0).nn) } override def concat[V1 >: V](that: scala.IterableOnce[(K, V1)]^): HashMap[K, V1] = that match { @@ -352,7 +352,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: val (mergedK, mergedV) = mergef(payload, thatPayload) val mergedOriginalHash = mergedK.## val mergedImprovedHash = improve(mergedOriginalHash) - new HashMap(that.rootNode.removed(thatPayload._1, originalHash, improved, 0).updated(mergedK, mergedV, mergedOriginalHash, mergedImprovedHash, 0, replaceValue = true)) + new HashMap(that.rootNode.removed(thatPayload._1, originalHash, improved, 0).nn.updated(mergedK, mergedV, mergedOriginalHash, mergedImprovedHash, 0, replaceValue = true)) } else { new HashMap(that.rootNode.updated(k, v, originalHash, improved, 0, replaceValue = true)) } @@ -414,7 +414,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: val next = iter.next() val originalHash = hashSet.unimproveHash(next.hash) val improved = improve(originalHash) - curr = curr.removed(next.key, originalHash, improved, 0) + curr = curr.removed(next.key, originalHash, improved, 0).nn if (curr.size == 0) { return HashMap.empty } @@ -432,7 +432,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: val next = iter.next() val originalHash = lhashSet.unimproveHash(next.hash) val improved = improve(originalHash) - curr = curr.removed(next.key, originalHash, improved, 0) + curr = curr.removed(next.key, originalHash, improved, 0).nn if (curr.size == 0) { return HashMap.empty } @@ -446,7 +446,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: val next = iter.next() val originalHash = next.## val improved = improve(originalHash) - curr = curr.removed(next, originalHash, improved, 0) + curr = curr.removed(next, originalHash, improved, 0).nn if (curr.size == 0) { return HashMap.empty } @@ -863,7 +863,7 @@ private final class BitmapIndexedMapNode[K, +V]( } } - def removed[V1 >: V](key: K, originalHash: Int, keyHash: Int, shift: Int): BitmapIndexedMapNode[K, V1] = { + def removed[V1 >: V](key: K, originalHash: Int, keyHash: Int, shift: Int): BitmapIndexedMapNode[K, V1] | Null = { val mask = maskFrom(keyHash, shift) val bitpos = bitposFrom(mask) @@ -1175,7 +1175,7 @@ private final class BitmapIndexedMapNode[K, +V]( } override def transform[W](f: (K, V) => W): BitmapIndexedMapNode[K, W] = { - var newContent: Array[Any] = null + @annotation.stableNull var newContent: Array[Any] | Null = null val iN = payloadArity // arity doesn't change during this operation val jN = nodeArity // arity doesn't change during this operation val newContentLength = content.length @@ -1718,7 +1718,7 @@ private final class BitmapIndexedMapNode[K, +V]( // bitmap of nodes which, when filtered, returned a single-element node. These must be migrated to data var nodeMigrateToDataTargetMap = 0 // the queue of single-element, post-filter nodes - var nodesToMigrateToData: mutable.Queue[MapNode[K, V]] = null + @annotation.stableNull var nodesToMigrateToData: mutable.Queue[MapNode[K, V]] | Null = null // bitmap of all nodes which, when filtered, returned themselves. They are passed forward to the returned node var nodesToPassThroughMap = 0 @@ -1728,7 +1728,7 @@ private final class BitmapIndexedMapNode[K, +V]( // not named `newNodesMap` (plural) to avoid confusion with `newNodeMap` (singular) var mapOfNewNodes = 0 // each bit in `mapOfNewNodes` corresponds to one element in this queue - var newNodes: mutable.Queue[MapNode[K, V]] = null + @annotation.stableNull var newNodes: mutable.Queue[MapNode[K, V]] | Null = null var newDataMap = 0 var newNodeMap = 0 @@ -1768,18 +1768,18 @@ private final class BitmapIndexedMapNode[K, +V]( nodesToPassThroughMap |= bitpos } else { mapOfNewNodes |= bitpos - if (newNodes eq null) { + if (newNodes == null) { newNodes = mutable.Queue.empty } - newNodes += newSubNode + newNodes.nn += newSubNode } } else if (newSubNode.size == 1) { newDataMap |= bitpos nodeMigrateToDataTargetMap |= bitpos - if (nodesToMigrateToData eq null) { + if (nodesToMigrateToData == null) { nodesToMigrateToData = mutable.Queue() } - nodesToMigrateToData += newSubNode + nodesToMigrateToData.nn += newSubNode } nodeIndex += 1 @@ -1826,14 +1826,14 @@ private final class BitmapIndexedMapNode[K, +V]( oldNodeIndex += 1 } else if ((bitpos & nodeMigrateToDataTargetMap) != 0) { // we need not check for null here. If nodeMigrateToDataTargetMap != 0, then nodesMigrateToData must not be null - val node = nodesToMigrateToData.dequeue() + val node = nodesToMigrateToData.nn.dequeue() newContent(TupleLength * newDataIndex) = node.getKey(0) newContent(TupleLength * newDataIndex + 1) = node.getValue(0) newOriginalHashes(newDataIndex) = node.getHash(0) newDataIndex += 1 oldNodeIndex += 1 } else if ((bitpos & mapOfNewNodes) != 0) { - newContent(newContentSize - newNodeIndex - 1) = newNodes.dequeue() + newContent(newContentSize - newNodeIndex - 1) = newNodes.nn.dequeue() newNodeIndex += 1 oldNodeIndex += 1 } else if ((bitpos & dataMap) != 0) { @@ -2008,16 +2008,16 @@ private final class HashCollisionMapNode[K, +V ]( if (hc eq this) { this } else { - var newContent: VectorBuilder[(K, V1)] = null + var newContent: VectorBuilder[(K, V1)] | Null = null val iter = content.iterator while (iter.hasNext) { val nextPayload = iter.next() if (hc.indexOf(nextPayload._1) < 0) { - if (newContent eq null) { + if (newContent == null) { newContent = new VectorBuilder[(K, V1)]() - newContent.addAll(hc.content) + newContent.nn.addAll(hc.content) } - newContent.addOne(nextPayload) + newContent.nn.addOne(nextPayload) } } if (newContent eq null) hc else new HashCollisionMapNode(originalHash, hash, newContent.result()) @@ -2031,7 +2031,7 @@ private final class HashCollisionMapNode[K, +V ]( override def mergeInto[V1 >: V](that: MapNode[K, V1], builder: HashMapBuilder[K, V1], shift: Int)(mergef: ((K, V), (K, V1)) => (K, V1)): Unit = that match { case hc: HashCollisionMapNode[K, V1] => val iter = content.iterator - val rightArray = hc.content.toArray[AnyRef] // really Array[(K, V1)] + val rightArray: Array[AnyRef | Null] = hc.content.toArray[AnyRef | Null] // really Array[(K, V1)] def rightIndexOf(key: K): Int = { var i = 0 @@ -2178,7 +2178,7 @@ private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) keyHash = improve(originalHash), originalHash = originalHash, shift = 0 - ) + ).nn currentValueCursor += 1 } curr @@ -2202,7 +2202,7 @@ object HashMap extends MapFactory[HashMap] { def empty[K, V]: HashMap[K, V] = EmptyMap.asInstanceOf[HashMap[K, V]] - def from[K, V](source: collection.IterableOnce[(K, V)]^): HashMap[K, V] = + def from[K, V](source: collection.IterableOnce[(K, V)]): HashMap[K, V] = source match { case hs: HashMap[K, V] => hs case _ => (newBuilder[K, V] ++= source).result() @@ -2227,7 +2227,8 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K, /** The last given out HashMap as a return value of `result()`, if any, otherwise null. * Indicates that on next add, the elements should be copied to an identical structure, before continuing * mutations. */ - private var aliased: HashMap[K, V] = _ + @annotation.stableNull + private var aliased: HashMap[K, V] | Null = _ private def isAliased: Boolean = aliased != null @@ -2334,11 +2335,11 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K, if (rootNode.size == 0) { HashMap.empty } else if (aliased != null) { - aliased + aliased.nn } else { aliased = new HashMap(rootNode) releaseFence() - aliased + aliased.nn } override def addOne(elem: (K, V)): this.type = { diff --git a/library/src/scala/collection/immutable/HashSet.scala b/library/src/scala/collection/immutable/HashSet.scala index 65dca3dbba79..ea2bd788606c 100644 --- a/library/src/scala/collection/immutable/HashSet.scala +++ b/library/src/scala/collection/immutable/HashSet.scala @@ -1097,7 +1097,7 @@ private final class BitmapIndexedSetNode[A]( // return at runtime a SetNode[A], or a tuple of (A, Int, Int) // the queue of single-element, post-filter nodes - var nodesToMigrateToData: mutable.Queue[SetNode[A]] = null + var nodesToMigrateToData: mutable.Queue[SetNode[A]] | Null = null // bitmap of all nodes which, when filtered, returned themselves. They are passed forward to the returned node var nodesToPassThroughMap = 0 @@ -1107,7 +1107,7 @@ private final class BitmapIndexedSetNode[A]( // not named `newNodesMap` (plural) to avoid confusion with `newNodeMap` (singular) var mapOfNewNodes = 0 // each bit in `mapOfNewNodes` corresponds to one element in this queue - var newNodes: mutable.Queue[SetNode[A]] = null + var newNodes: mutable.Queue[SetNode[A]] | Null = null var newDataMap = 0 var newNodeMap = 0 @@ -1150,7 +1150,7 @@ private final class BitmapIndexedSetNode[A]( if (newNodes eq null) { newNodes = mutable.Queue.empty } - newNodes += newSubNode + newNodes.nn += newSubNode } } else if (newSubNode.size == 1) { newDataMap |= bitpos @@ -1158,7 +1158,7 @@ private final class BitmapIndexedSetNode[A]( if (nodesToMigrateToData eq null) { nodesToMigrateToData = mutable.Queue.empty } - nodesToMigrateToData += newSubNode + nodesToMigrateToData.nn += newSubNode } nodeIndex += 1 @@ -1199,7 +1199,7 @@ private final class BitmapIndexedSetNode[A]( // bitmap of nodes which, when filtered, returned a single-element node. These must be migrated to data var nodeMigrateToDataTargetMap = 0 // the queue of single-element, post-filter nodes - var nodesToMigrateToData: mutable.Queue[SetNode[A]] = null + var nodesToMigrateToData: mutable.Queue[SetNode[A]] | Null = null // bitmap of all nodes which, when filtered, returned themselves. They are passed forward to the returned node var nodesToPassThroughMap = 0 @@ -1209,7 +1209,7 @@ private final class BitmapIndexedSetNode[A]( // not named `newNodesMap` (plural) to avoid confusion with `newNodeMap` (singular) var mapOfNewNodes = 0 // each bit in `mapOfNewNodes` corresponds to one element in this queue - var newNodes: mutable.Queue[SetNode[A]] = null + var newNodes: mutable.Queue[SetNode[A]] | Null = null var newDataMap = 0 var newNodeMap = 0 @@ -1265,7 +1265,7 @@ private final class BitmapIndexedSetNode[A]( if (newNodes eq null) { newNodes = mutable.Queue.empty } - newNodes += newSubNode + newNodes.nn += newSubNode } } else if (newSubNode.size == 1) { newDataMap |= bitpos @@ -1273,7 +1273,7 @@ private final class BitmapIndexedSetNode[A]( if (nodesToMigrateToData eq null) { nodesToMigrateToData = mutable.Queue.empty } - nodesToMigrateToData += newSubNode + nodesToMigrateToData.nn += newSubNode } nodeIndex += 1 @@ -1327,9 +1327,9 @@ private final class BitmapIndexedSetNode[A]( oldDataPassThrough: Int, nodesToPassThroughMap: Int, nodeMigrateToDataTargetMap: Int, - nodesToMigrateToData: mutable.Queue[SetNode[A]], + nodesToMigrateToData: mutable.Queue[SetNode[A]] | Null, mapOfNewNodes: Int, - newNodes: mutable.Queue[SetNode[A]], + newNodes: mutable.Queue[SetNode[A]] | Null, newCachedHashCode: Int): BitmapIndexedSetNode[A] = { if (newSize == 0) { SetNode.empty @@ -1368,14 +1368,14 @@ private final class BitmapIndexedSetNode[A]( oldNodeIndex += 1 } else if ((bitpos & nodeMigrateToDataTargetMap) != 0) { // we need not check for null here. If nodeMigrateToDataTargetMap != 0, then nodesMigrateToData must not be null - val node = nodesToMigrateToData.dequeue() + val node = nodesToMigrateToData.nn.dequeue() newContent(newDataIndex) = node.getPayload(0) newOriginalHashes(newDataIndex) = node.getHash(0) newDataIndex += 1 oldNodeIndex += 1 } else if ((bitpos & mapOfNewNodes) != 0) { // we need not check for null here. If mapOfNewNodes != 0, then newNodes must not be null - newContent(newContentSize - newNodeIndex - 1) = newNodes.dequeue() + newContent(newContentSize - newNodeIndex - 1) = newNodes.nn.dequeue() newNodeIndex += 1 oldNodeIndex += 1 } else if ((bitpos & dataMap) != 0) { @@ -1842,7 +1842,7 @@ private final class HashCollisionSetNode[A](val originalHash: Int, val hash: Int if (hc eq this) { this } else { - var newContent: VectorBuilder[A] = null + var newContent: VectorBuilder[A] | Null = null val iter = hc.content.iterator while (iter.hasNext) { val nextPayload = iter.next() @@ -1964,7 +1964,8 @@ private[collection] final class HashSetBuilder[A] extends ReusableBuilder[A, Has /** The last given out HashSet as a return value of `result()`, if any, otherwise null. * Indicates that on next add, the elements should be copied to an identical structure, before continuing * mutations. */ - private var aliased: HashSet[A] = _ + @annotation.stableNull + private var aliased: HashSet[A] | Null = null private def isAliased: Boolean = aliased != null diff --git a/library/src/scala/collection/immutable/LazyList.scala b/library/src/scala/collection/immutable/LazyList.scala index 823144a19338..a0430c3a0339 100644 --- a/library/src/scala/collection/immutable/LazyList.scala +++ b/library/src/scala/collection/immutable/LazyList.scala @@ -287,7 +287,7 @@ final class LazyList[+A] private (lazyState: AnyRef /* EmptyMarker.type | () => // after initialization (`_head ne Uninitialized`) // - `null` if this is an empty lazy list // - `head: A` otherwise (can be `null`, `_tail == null` is used to test emptiness) - @volatile private[this] var _head: Any /* Uninitialized | A */ = + @volatile private[this] var _head: Any | Null /* Uninitialized | A */ = if (lazyState eq EmptyMarker) null else Uninitialized // when `_head eq Uninitialized` @@ -296,11 +296,11 @@ final class LazyList[+A] private (lazyState: AnyRef /* EmptyMarker.type | () => // when `_head ne Uninitialized` // - `null` if this is an empty lazy list // - `tail: LazyList[A]` otherwise - private[this] var _tail: AnyRef /* () => LazyList[A] | MidEvaluation.type | LazyList[A] */ = + private[this] var _tail: AnyRef | Null /* () => LazyList[A] | MidEvaluation.type | LazyList[A] */ = if (lazyState eq EmptyMarker) null else lazyState private def rawHead: Any = _head - private def rawTail: AnyRef = _tail + private def rawTail: AnyRef | Null = _tail @inline private def isEvaluated: Boolean = _head.asInstanceOf[AnyRef] ne Uninitialized @@ -1112,22 +1112,22 @@ object LazyList extends SeqFactory[LazyList] { // DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD var restRef = ll // val restRef = new ObjectRef(ll) newLL { - var it: Iterator[B] = null + var it: Iterator[B] | Null = null var itHasNext = false var rest = restRef // var rest = restRef.elem while (!itHasNext && !rest.isEmpty) { it = f(rest.head).iterator - itHasNext = it.hasNext + itHasNext = it.nn.hasNext if (!itHasNext) { // wait to advance `rest` because `it.next()` can throw rest = rest.tail restRef = rest // restRef.elem = rest } } if (itHasNext) { - val head = it.next() + val head = it.nn.next() rest = rest.tail restRef = rest // restRef.elem = rest - eagerCons(head, newLL(eagerHeadPrependIterator(it)(flatMapImpl(rest, f)))) + eagerCons(head, newLL(eagerHeadPrependIterator(it.nn)(flatMapImpl(rest, f)))) } else Empty } } diff --git a/library/src/scala/collection/immutable/LazyListIterable.scala b/library/src/scala/collection/immutable/LazyListIterable.scala index f1d14bbb1fad..f0fddc2fb543 100644 --- a/library/src/scala/collection/immutable/LazyListIterable.scala +++ b/library/src/scala/collection/immutable/LazyListIterable.scala @@ -294,11 +294,11 @@ final class LazyListIterable[+A] private (lazyState: LazyListIterable.EmptyMarke // when `_head ne Uninitialized` // - `null` if this is an empty lazy list // - `tail: LazyListIterable[A]` otherwise - private[this] var _tail: AnyRef^{this} /* () => LazyListIterable[A] | MidEvaluation.type | LazyListIterable[A] */ = + private[this] var _tail: AnyRef^{this} | Null /* () => LazyListIterable[A] | MidEvaluation.type | LazyListIterable[A] */ = if (lazyState eq EmptyMarker) null else lazyState private def rawHead: Any = _head - private def rawTail: AnyRef^{this} = _tail + private def rawTail: AnyRef^{this} | Null = _tail @inline private def isEvaluated: Boolean = _head.asInstanceOf[AnyRef] ne Uninitialized @@ -1134,22 +1134,22 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { // DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD var restRef: LazyListIterable[A]^{ll} = ll // val restRef = new ObjectRef(ll) newLL { - var it: Iterator[B]^{f} = null + var it: Iterator[B]^{f} | Null = null var itHasNext = false var rest: LazyListIterable[A]^{ll} = restRef // var rest = restRef.elem while (!itHasNext && !rest.isEmpty) { it = f(rest.head).iterator - itHasNext = it.hasNext + itHasNext = it.nn.hasNext if (!itHasNext) { // wait to advance `rest` because `it.next()` can throw rest = rest.tail restRef = rest // restRef.elem = rest } } if (itHasNext) { - val head = it.next() + val head = it.nn.next() rest = rest.tail restRef = rest // restRef.elem = rest - eagerCons(head, newLL(eagerHeadPrependIterator(it)(flatMapImpl(rest, f)))) + eagerCons(head, newLL(eagerHeadPrependIterator(it.nn)(flatMapImpl(rest, f)))) } else Empty } } diff --git a/library/src/scala/collection/immutable/List.scala b/library/src/scala/collection/immutable/List.scala index dde3e5e8a05c..408d3c117c4a 100644 --- a/library/src/scala/collection/immutable/List.scala +++ b/library/src/scala/collection/immutable/List.scala @@ -264,16 +264,16 @@ sealed abstract class List[+A] final override def collect[B](pf: PartialFunction[A, B]^): List[B] = { if (this eq Nil) Nil else { var rest = this - var h: ::[B] = null + var h: ::[B] | Null = null var x: Any = null // Special case for first element while (h eq null) { x = pf.applyOrElse(rest.head, List.partialNotApplied) if (x.asInstanceOf[AnyRef] ne List.partialNotApplied) h = new ::(x.asInstanceOf[B], Nil) rest = rest.tail - if (rest eq Nil) return if (h eq null) Nil else h + if (rest eq Nil) return if (h eq null) Nil else h.nn } - var t = h + var t = h.nn // Remaining elements while (rest ne Nil) { x = pf.applyOrElse(rest.head, List.partialNotApplied) @@ -285,14 +285,14 @@ sealed abstract class List[+A] rest = rest.tail } releaseFence() - h + h.nn } } final override def flatMap[B](f: A => IterableOnce[B]^): List[B] = { var rest = this - var h: ::[B] = null - var t: ::[B] = null + var h: ::[B] | Null = null + var t: ::[B] | Null = null while (rest ne Nil) { val it = f(rest.head).iterator while (it.hasNext) { @@ -300,7 +300,7 @@ sealed abstract class List[+A] if (t eq null) { h = nx } else { - t.next = nx + t.nn.next = nx } t = nx } @@ -463,12 +463,12 @@ sealed abstract class List[+A] // Note to developers: there exists a duplication between this function and `reflect.internal.util.Collections#map2Conserve`. // If any successful optimization attempts or other changes are made, please rehash them there too. @tailrec - def loop(mappedHead: List[B], mappedLast: ::[B], unchanged: List[A], pending: List[A]): List[B] = { + def loop(mappedHead: List[B] | Null, mappedLast: ::[B] | Null, unchanged: List[A], pending: List[A]): List[B] = { if (pending.isEmpty) { if (mappedHead eq null) unchanged else { - mappedLast.next = (unchanged: List[B]) - mappedHead + mappedLast.nn.next = (unchanged: List[B]) + mappedHead.nn } } else { @@ -479,18 +479,18 @@ sealed abstract class List[+A] loop(mappedHead, mappedLast, unchanged, pending.tail) else { var xc = unchanged - var mappedHead1: List[B] = mappedHead - var mappedLast1: ::[B] = mappedLast + var mappedHead1: List[B] | Null = mappedHead + var mappedLast1: ::[B] | Null = mappedLast while (xc ne pending) { val next = new ::[B](xc.head, Nil) if (mappedHead1 eq null) mappedHead1 = next - if (mappedLast1 ne null) mappedLast1.next = next + if (mappedLast1 ne null) mappedLast1.nn.next = next mappedLast1 = next xc = xc.tail } val next = new ::(head1, Nil) if (mappedHead1 eq null) mappedHead1 = next - if (mappedLast1 ne null) mappedLast1.next = next + if (mappedLast1 ne null) mappedLast1.nn.next = next mappedLast1 = next val tail0 = pending.tail loop(mappedHead1, mappedLast1, tail0, tail0) diff --git a/library/src/scala/collection/immutable/ListMap.scala b/library/src/scala/collection/immutable/ListMap.scala index 0d6ef12296e2..0780e9d99eb7 100644 --- a/library/src/scala/collection/immutable/ListMap.scala +++ b/library/src/scala/collection/immutable/ListMap.scala @@ -136,7 +136,7 @@ object ListMap extends MapFactory[ListMap] { private[immutable] final class Node[K, V]( override private[immutable] val key: K, private[immutable] var _value: V, - private[immutable] var _init: ListMap[K, V] + private[immutable] var _init: ListMap[K, V] | Null ) extends ListMap[K, V] { releaseFence() @@ -195,28 +195,28 @@ object ListMap extends MapFactory[ListMap] { if (found) { if (isDifferent) { - var newHead: ListMap.Node[K, V1] = null - var prev: ListMap.Node[K, V1] = null + var newHead: ListMap.Node[K, V1] | Null = null + var prev: ListMap.Node[K, V1] | Null = null var curr: ListMap[K, V1] = this var i = 0 while (i < index) { val temp = new ListMap.Node(curr.key, curr.value, null) - if (prev ne null) { - prev._init = temp + if (prev != null) { + prev.nn._init = temp } prev = temp curr = curr.init - if (newHead eq null) { + if (newHead == null) { newHead = prev } i += 1 } val newNode = new ListMap.Node(curr.key, v, curr.init) - if (prev ne null) { - prev._init = newNode + if (prev != null) { + prev.nn._init = newNode } releaseFence() - if (newHead eq null) newNode else newHead + if (newHead == null) newNode else newHead.nn } else { this } @@ -232,7 +232,7 @@ object ListMap extends MapFactory[ListMap] { override def removed(k: K): ListMap[K, V] = removeInternal(k, this, Nil) - override private[immutable] def next: ListMap[K, V] = _init + override private[immutable] def next: ListMap[K, V] = _init.nn override def last: (K, V) = (key, value) override def init: ListMap[K, V] = next diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 94d6ed434d75..1e711ad035ae 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -16,6 +16,7 @@ package immutable import scala.language.`2.13` import language.experimental.captureChecking +import scala.language.unsafeNulls import scala.annotation.meta.{getter, setter} import scala.annotation.tailrec @@ -159,7 +160,7 @@ private[collection] object RedBlackTree { } } private[immutable] class SetHelper[A](implicit ordering: Ordering[A]) extends Helper[A] { - protected[this] final def mutableUpd(tree: Tree[A, Any], k: A): Tree[A, Any] = + protected[this] final def mutableUpd(tree: Tree[A, Any] | Null, k: A): Tree[A, Any] = if (tree eq null) { mutableRedTree(k, (), null, null) } else if (k.asInstanceOf[AnyRef] eq tree.key.asInstanceOf[AnyRef]) { @@ -174,7 +175,7 @@ private[collection] object RedBlackTree { } } private[immutable] class MapHelper[A, B](implicit ordering: Ordering[A]) extends Helper[A] { - protected[this] final def mutableUpd[B1 >: B](tree: Tree[A, B], k: A, v: B1): Tree[A, B1] = + protected[this] final def mutableUpd[B1 >: B](tree: Tree[A, B] | Null, k: A, v: B1): Tree[A, B1] = if (tree eq null) { mutableRedTree(k, v, null, null) } else if (k.asInstanceOf[AnyRef] eq tree.key.asInstanceOf[AnyRef]) { @@ -189,7 +190,7 @@ private[collection] object RedBlackTree { } } - def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count + def count(tree: Tree[_, _] | Null) = if (tree eq null) 0 else tree.count def update[A: Ordering, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) def delete[A: Ordering, B](tree: Tree[A, B], k: A): Tree[A, B] = blacken(del(tree, k)) def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { @@ -207,21 +208,21 @@ private[collection] object RedBlackTree { def take[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doTake(tree, n)) def slice[A: Ordering, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) - def smallest[A, B](tree: Tree[A, B]): Tree[A, B] = { + def smallest[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { if (tree eq null) throw new NoSuchElementException("empty tree") var result = tree while (result.left ne null) result = result.left result } - def greatest[A, B](tree: Tree[A, B]): Tree[A, B] = { + def greatest[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { if (tree eq null) throw new NoSuchElementException("empty tree") var result = tree while (result.right ne null) result = result.right result } - def tail[A, B](tree: Tree[A, B]): Tree[A, B] = { - def _tail(tree: Tree[A, B]): Tree[A, B] = + def tail[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { + def _tail(tree: Tree[A, B] | Null): Tree[A, B] = if (tree eq null) throw new NoSuchElementException("empty tree") else { val tl = tree.left @@ -232,7 +233,7 @@ private[collection] object RedBlackTree { blacken(_tail(tree)) } - def init[A, B](tree: Tree[A, B]): Tree[A, B] = { + def init[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { def _init(tree: Tree[A, B]): Tree[A, B] = if (tree eq null) throw new NoSuchElementException("empty tree") else { @@ -328,7 +329,7 @@ private[collection] object RedBlackTree { @`inline` private[this] def isRedTree(tree: Tree[_, _]) = (tree ne null) && tree.isRed @`inline` private[this] def isBlackTree(tree: Tree[_, _]) = (tree ne null) && tree.isBlack - private[this] def blacken[A, B](t: Tree[A, B]): Tree[A, B] = if (t eq null) null else t.black + private[this] def blacken[A, B](t: Tree[A, B] | Null): Tree[A, B] = if (t eq null) null else t.black // Blacken if the tree is red and has a red child. This is necessary when using methods such as `upd` or `updNth` // for building subtrees. Use `blacken` instead when building top-level trees. @@ -423,7 +424,7 @@ private[collection] object RedBlackTree { } } - private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { + private[this] def upd[A, B, B1 >: B](tree: Tree[A, B] | Null, k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { RedTree(k, v, null, null) } else if (k.asInstanceOf[AnyRef] eq tree.key.asInstanceOf[AnyRef]) { if (overwrite) @@ -439,7 +440,7 @@ private[collection] object RedBlackTree { tree.withV(v) else tree } - private[this] def updNth[A, B, B1 >: B](tree: Tree[A, B], idx: Int, k: A, v: B1): Tree[A, B1] = if (tree eq null) { + private[this] def updNth[A, B, B1 >: B](tree: Tree[A, B] | Null, idx: Int, k: A, v: B1): Tree[A, B1] = if (tree eq null) { RedTree(k, v, null, null) } else { val rank = count(tree.left) + 1 @@ -450,7 +451,7 @@ private[collection] object RedBlackTree { else tree } - private[this] def doFrom[A, B](tree: Tree[A, B], from: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + private[this] def doFrom[A, B](tree: Tree[A, B] | Null, from: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = { if (tree eq null) return null if (ordering.lt(tree.key, from)) return doFrom(tree.right, from) val newLeft = doFrom(tree.left, from) @@ -458,7 +459,7 @@ private[collection] object RedBlackTree { else if (newLeft eq null) maybeBlacken(upd(tree.right, tree.key, tree.value, overwrite = false)) else join(newLeft, tree.key, tree.value, tree.right) } - private[this] def doTo[A, B](tree: Tree[A, B], to: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + private[this] def doTo[A, B](tree: Tree[A, B] | Null, to: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = { if (tree eq null) return null if (ordering.lt(to, tree.key)) return doTo(tree.left, to) val newRight = doTo(tree.right, to) @@ -466,7 +467,7 @@ private[collection] object RedBlackTree { else if (newRight eq null) maybeBlacken(upd(tree.left, tree.key, tree.value, overwrite = false)) else join(tree.left, tree.key, tree.value, newRight) } - private[this] def doUntil[A, B](tree: Tree[A, B], until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + private[this] def doUntil[A, B](tree: Tree[A, B] | Null, until: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = { if (tree eq null) return null if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until) val newRight = doUntil(tree.right, until) @@ -475,7 +476,7 @@ private[collection] object RedBlackTree { else join(tree.left, tree.key, tree.value, newRight) } - private[this] def doRange[A, B](tree: Tree[A, B], from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { + private[this] def doRange[A, B](tree: Tree[A, B] | Null, from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = { if (tree eq null) return null if (ordering.lt(tree.key, from)) return doRange(tree.right, from, until) if (ordering.lteq(until, tree.key)) return doRange(tree.left, from, until) @@ -487,7 +488,7 @@ private[collection] object RedBlackTree { else join(newLeft, tree.key, tree.value, newRight) } - private[this] def doDrop[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = + private[this] def doDrop[A, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] | Null = if((tree eq null) || (n <= 0)) tree else if(n >= tree.count) null else { @@ -497,7 +498,7 @@ private[collection] object RedBlackTree { else join(doDrop(tree.left, n), tree.key, tree.value, tree.right) } - private[this] def doTake[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = + private[this] def doTake[A, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] | Null = if((tree eq null) || (n <= 0)) null else if(n >= tree.count) tree else { @@ -507,7 +508,7 @@ private[collection] object RedBlackTree { else join(tree.left, tree.key, tree.value, doTake(tree.right, n-l-1)) } - private[this] def doSlice[A, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = + private[this] def doSlice[A, B](tree: Tree[A, B] | Null, from: Int, until: Int): Tree[A, B] | Null = if((tree eq null) || (from >= until) || (from >= tree.count) || (until <= 0)) null else if((from <= 0) && (until >= tree.count)) tree else { @@ -782,8 +783,8 @@ private[collection] object RedBlackTree { private[RedBlackTree] final val initialBlackCount = colourBit private[RedBlackTree] final val initialRedCount = 0 - @`inline` private[RedBlackTree] def mutableRedTree[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new Tree[A,B](key, value.asInstanceOf[AnyRef], left, right, initialRedCount) - @`inline` private[RedBlackTree] def mutableBlackTree[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new Tree[A,B](key, value.asInstanceOf[AnyRef], left, right, initialBlackCount) + @`inline` private[RedBlackTree] def mutableRedTree[A, B](key: A, value: B, left: Tree[A, B] | Null, right: Tree[A, B] | Null) = new Tree[A,B](key, value.asInstanceOf[AnyRef], left, right, initialRedCount) + @`inline` private[RedBlackTree] def mutableBlackTree[A, B](key: A, value: B, left: Tree[A, B] | Null, right: Tree[A, B] | Null) = new Tree[A,B](key, value.asInstanceOf[AnyRef], left, right, initialBlackCount) /** create a new immutable red tree. * left and right may be null @@ -1051,7 +1052,7 @@ private[collection] object RedBlackTree { // Constructing Red-Black Trees, Ralf Hinze: [[https://www.cs.ox.ac.uk/ralf.hinze/publications/WAAAPL99b.ps.gz]] // Red-Black Trees in a Functional Setting, Chris Okasaki: [[https://wiki.rice.edu/confluence/download/attachments/2761212/Okasaki-Red-Black.pdf]] */ - private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + private[this] def del[A, B](tree: Tree[A, B] | Null, k: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if (tree eq null) null else { val cmp = ordering.compare(k, tree.key) if (cmp < 0) { val newLeft = del(tree.left, k) @@ -1125,15 +1126,15 @@ private[collection] object RedBlackTree { // of child nodes from it. Where possible the black height is used directly instead of deriving the rank from it. // Our trees are supposed to have a black root so we always blacken as the last step of union/intersect/difference. - def union[A, B](t1: Tree[A, B], t2: Tree[A, B])(implicit ordering: Ordering[A]): Tree[A, B] = blacken(_union(t1, t2)) + def union[A, B](t1: Tree[A, B] | Null, t2: Tree[A, B] | Null)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(_union(t1, t2)) - def intersect[A, B](t1: Tree[A, B], t2: Tree[A, B])(implicit ordering: Ordering[A]): Tree[A, B] = blacken(_intersect(t1, t2)) + def intersect[A, B](t1: Tree[A, B] | Null, t2: Tree[A, B] | Null)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(_intersect(t1, t2)) - def difference[A, B](t1: Tree[A, B], t2: Tree[A, _])(implicit ordering: Ordering[A]): Tree[A, B] = + def difference[A, B](t1: Tree[A, B] | Null, t2: Tree[A, _] | Null)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(_difference(t1, t2.asInstanceOf[Tree[A, B]])) /** Compute the rank from a tree and its black height */ - @`inline` private[this] def rank(t: Tree[_, _], bh: Int): Int = { + @`inline` private[this] def rank(t: Tree[_, _] | Null, bh: Int): Int = { if(t eq null) 0 else if(t.isBlack) 2*(bh-1) else 2*bh-1 @@ -1169,7 +1170,7 @@ private[collection] object RedBlackTree { } } - private[this] def join[A, B](tl: Tree[A, B], k: A, v: B, tr: Tree[A, B]): Tree[A, B] = { + private[this] def join[A, B](tl: Tree[A, B] | Null, k: A, v: B, tr: Tree[A, B] | Null): Tree[A, B] = { @tailrec def h(t: Tree[_, _], i: Int): Int = if(t eq null) i+1 else h(t.left, if(t.isBlack) i+1 else i) val bhtl = h(tl, 0) @@ -1185,7 +1186,7 @@ private[collection] object RedBlackTree { } else mkTree(isRedTree(tl) || isRedTree(tr), k, v, tl, tr) } - private[this] def split[A, B](t: Tree[A, B], k2: A)(implicit ordering: Ordering[A]): (Tree[A, B], Tree[A, B], Tree[A, B], A) = + private[this] def split[A, B](t: Tree[A, B] | Null, k2: A)(implicit ordering: Ordering[A]): (Tree[A, B] | Null, Tree[A, B] | Null, Tree[A, B] | Null, A) = if(t eq null) (null, null, null, k2) else { val cmp = ordering.compare(k2, t.key) @@ -1206,7 +1207,7 @@ private[collection] object RedBlackTree { (join(t.left, t.key, t.value, tt), kk, vv) } - private[this] def join2[A, B](tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = + private[this] def join2[A, B](tl: Tree[A, B] | Null, tr: Tree[A, B] | Null): Tree[A, B] | Null = if(tl eq null) tr else if(tr eq null) tl else { @@ -1214,7 +1215,7 @@ private[collection] object RedBlackTree { join(ttl, k, v, tr) } - private[this] def _union[A, B](t1: Tree[A, B], t2: Tree[A, B])(implicit ordering: Ordering[A]): Tree[A, B] = + private[this] def _union[A, B](t1: Tree[A, B] | Null, t2: Tree[A, B] | Null)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if((t1 eq null) || (t1 eq t2)) t2 else if(t2 eq null) t1 else { @@ -1224,7 +1225,7 @@ private[collection] object RedBlackTree { join(tl, k1, t2.value, tr) } - private[this] def _intersect[A, B](t1: Tree[A, B], t2: Tree[A, B])(implicit ordering: Ordering[A]): Tree[A, B] = + private[this] def _intersect[A, B](t1: Tree[A, B] | Null, t2: Tree[A, B] | Null)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if((t1 eq null) || (t2 eq null)) null else if (t1 eq t2) t1 else { @@ -1235,7 +1236,7 @@ private[collection] object RedBlackTree { else join2(tl, tr) } - private[this] def _difference[A, B](t1: Tree[A, B], t2: Tree[A, B])(implicit ordering: Ordering[A]): Tree[A, B] = + private[this] def _difference[A, B](t1: Tree[A, B] | Null, t2: Tree[A, B] | Null)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if((t1 eq null) || (t2 eq null)) t1 else if (t1 eq t2) null else { diff --git a/library/src/scala/collection/immutable/Stream.scala b/library/src/scala/collection/immutable/Stream.scala index b31c5c8018c6..352d4d5224c5 100644 --- a/library/src/scala/collection/immutable/Stream.scala +++ b/library/src/scala/collection/immutable/Stream.scala @@ -396,13 +396,13 @@ object Stream extends SeqFactory[Stream] { final class Cons[A](override val head: A, tl: => Stream[A]) extends Stream[A] { override def isEmpty: Boolean = false @volatile private[this] var tlVal: Stream[A] = _ - @volatile private[this] var tlGen = () => tl + @volatile private[this] var tlGen: (() => Stream[A]) | Null = () => tl protected def tailDefined: Boolean = tlGen eq null override def tail: Stream[A] = { if (!tailDefined) synchronized { if (!tailDefined) { - tlVal = tlGen() + tlVal = tlGen.nn() tlGen = null } } @@ -479,8 +479,8 @@ object Stream extends SeqFactory[Stream] { new WithFilter[A](l, p) private[this] final class WithFilter[A](l: Stream[A] @uncheckedVariance, p: A => Boolean) extends collection.WithFilter[A, Stream] { - private[this] var s = l // set to null to allow GC after filtered - private[this] lazy val filtered: Stream[A] = { val f = s.filter(p); s = null.asInstanceOf[Stream[A]]; f } // don't set to null if throw during filter + private[this] var s: Stream[A] | Null = l // set to null to allow GC after filtered + private[this] lazy val filtered: Stream[A] = { val f = s.nn.filter(p); s = null; f } // don't set to null if throw during filter def map[B](f: A => B): Stream[B] = filtered.map(f) def flatMap[B](f: A => IterableOnce[B]): Stream[B] = filtered.flatMap(f) def foreach[U](f: A => U): Unit = filtered.foreach(f) diff --git a/library/src/scala/collection/immutable/TreeMap.scala b/library/src/scala/collection/immutable/TreeMap.scala index 84ca78c48b75..ee68bc2a7a12 100644 --- a/library/src/scala/collection/immutable/TreeMap.scala +++ b/library/src/scala/collection/immutable/TreeMap.scala @@ -16,6 +16,7 @@ package immutable import scala.language.`2.13` import language.experimental.captureChecking +import scala.language.unsafeNulls import scala.annotation.tailrec import scala.collection.Stepper.EfficientSplit diff --git a/library/src/scala/collection/immutable/TreeSeqMap.scala b/library/src/scala/collection/immutable/TreeSeqMap.scala index 0741bcbaec58..ba94814da45f 100644 --- a/library/src/scala/collection/immutable/TreeSeqMap.scala +++ b/library/src/scala/collection/immutable/TreeSeqMap.scala @@ -320,7 +320,8 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { private[this] val bdr = new MapBuilderImpl[K, (Int, V)] private[this] var ong = Ordering.empty[K] private[this] var ord = 0 - private[this] var aliased: TreeSeqMap[K, V] = _ + @annotation.stableNull + private[this] var aliased: TreeSeqMap[K, V] | Null = null override def addOne(elem: (K, V)): this.type = addOne(elem._1, elem._2) def addOne(key: K, value: V): this.type = { @@ -355,7 +356,7 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { if (aliased eq null) { aliased = new TreeSeqMap(ong, bdr.result(), ord, orderedBy) } - aliased + aliased.nn } } @@ -574,7 +575,7 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { } @inline private[collection] final def appendInPlace[S >: T](ordinal: Int, value: S): Ordering[S] = appendInPlace1(null, ordinal, value) - private[collection] final def appendInPlace1[S >: T](parent: Bin[S], ordinal: Int, value: S): Ordering[S] = this match { + private[collection] final def appendInPlace1[S >: T](parent: Bin[S] | Null, ordinal: Int, value: S): Ordering[S] = this match { case Zero => Tip(ordinal, value) case Tip(o, _) if o >= ordinal => @@ -582,14 +583,14 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { case Tip(o, _) if parent == null => join(ordinal, Tip(ordinal, value), o, this) case Tip(o, _) => - parent.right = join(ordinal, Tip(ordinal, value), o, this) - parent + parent.nn.right = join(ordinal, Tip(ordinal, value), o, this) + parent.nn case b @ Bin(p, m, _, r) => if (!hasMatch(ordinal, p, m)) { val b2 = join(ordinal, Tip(ordinal, value), p, this) if (parent != null) { - parent.right = b2 - parent + parent.nn.right = b2 + parent.nn } else b2 } else if (zero(ordinal, m)) throw new IllegalArgumentException(s"Append called with ordinal out of range: $ordinal is not greater than current max ordinal ${this.ordinal}") else { diff --git a/library/src/scala/collection/immutable/TreeSet.scala b/library/src/scala/collection/immutable/TreeSet.scala index d30380b88101..8a34204e44a1 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -39,7 +39,7 @@ import scala.runtime.AbstractFunction1 * @define mayNotTerminateInf * @define willNotTerminateInf */ -final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[A, Any])(implicit val ordering: Ordering[A]) +final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[A, Any] | Null)(implicit val ordering: Ordering[A]) extends AbstractSet[A] with SortedSet[A] with SortedSetOps[A, TreeSet, TreeSet[A]] @@ -53,19 +53,19 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ override def sortedIterableFactory: TreeSet.type = TreeSet - private[this] def newSetOrSelf(t: RB.Tree[A, Any]) = if(t eq tree) this else new TreeSet[A](t) + private[this] def newSetOrSelf(t: RB.Tree[A, Any] | Null) = if(t eq tree) this else new TreeSet[A](t) override def size: Int = RB.count(tree) override def isEmpty = size == 0 - override def head: A = RB.smallest(tree).key + override def head: A = RB.smallest(tree.nn).key - override def last: A = RB.greatest(tree).key + override def last: A = RB.greatest(tree.nn).key - override def tail: TreeSet[A] = new TreeSet(RB.tail(tree)) + override def tail: TreeSet[A] = new TreeSet(RB.tail(tree.nn)) - override def init: TreeSet[A] = new TreeSet(RB.init(tree)) + override def init: TreeSet[A] = new TreeSet(RB.init(tree.nn)) override def min[A1 >: A](implicit ord: Ordering[A1]): A = { if ((ord eq ordering) && nonEmpty) { @@ -86,20 +86,20 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ override def drop(n: Int): TreeSet[A] = { if (n <= 0) this else if (n >= size) empty - else new TreeSet(RB.drop(tree, n)) + else new TreeSet(RB.drop(tree.nn, n)) } override def take(n: Int): TreeSet[A] = { if (n <= 0) empty else if (n >= size) this - else new TreeSet(RB.take(tree, n)) + else new TreeSet(RB.take(tree.nn, n)) } override def slice(from: Int, until: Int): TreeSet[A] = { if (until <= from) empty else if (from <= 0) take(until) else if (until >= size) drop(from) - else new TreeSet(RB.slice(tree, from, until)) + else new TreeSet(RB.slice(tree.nn, from, until)) } override def dropRight(n: Int): TreeSet[A] = take(size - math.max(n, 0)) @@ -118,30 +118,30 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ override def span(p: A => Boolean): (TreeSet[A], TreeSet[A]) = splitAt(countWhile(p)) - override def foreach[U](f: A => U): Unit = RB.foreachKey(tree, f) + override def foreach[U](f: A => U): Unit = RB.foreachKey(tree.nn, f) override def minAfter(key: A): Option[A] = { - val v = RB.minAfter(tree, key) + val v = RB.minAfter(tree.nn, key) if (v eq null) Option.empty else Some(v.key) } override def maxBefore(key: A): Option[A] = { - val v = RB.maxBefore(tree, key) + val v = RB.maxBefore(tree.nn, key) if (v eq null) Option.empty else Some(v.key) } - def iterator: Iterator[A] = RB.keysIterator(tree) + def iterator: Iterator[A] = RB.keysIterator(tree.nn) - def iteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree, Some(start)) + def iteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree.nn, Some(start)) override def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S with EfficientSplit = { import scala.collection.convert.impl._ type T = RB.Tree[A, Any] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left, _.right, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree, _.left, _.right, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.nn, _.left, _.right, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left, _.right, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.nn, _.left, _.right, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.nn, _.left, _.right, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -151,11 +151,11 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ * @param elem the element to check for membership. * @return true, iff `elem` is contained in this set. */ - def contains(elem: A): Boolean = RB.contains(tree, elem) + def contains(elem: A): Boolean = RB.contains(tree.nn, elem) - override def range(from: A, until: A): TreeSet[A] = newSetOrSelf(RB.range(tree, from, until)) + override def range(from: A, until: A): TreeSet[A] = newSetOrSelf(RB.range(tree.nn, from, until)) - def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = newSetOrSelf(RB.rangeImpl(tree, from, until)) + def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = newSetOrSelf(RB.rangeImpl(tree.nn, from, until)) /** Creates a new `TreeSet` with the entry added. * @@ -163,7 +163,7 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ * @return a new $coll containing `elem` and all the elements of this $coll. */ def incl(elem: A): TreeSet[A] = - newSetOrSelf(RB.update(tree, elem, null, overwrite = false)) + newSetOrSelf(RB.update(tree.nn, elem, null, overwrite = false)) /** Creates a new `TreeSet` with the entry removed. * @@ -171,15 +171,15 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ * @return a new $coll containing all the elements of this $coll except `elem`. */ def excl(elem: A): TreeSet[A] = - newSetOrSelf(RB.delete(tree, elem)) + newSetOrSelf(RB.delete(tree.nn, elem)) override def concat(that: collection.IterableOnce[A]^): TreeSet[A] = { val t = that match { case ts: TreeSet[A] if ordering == ts.ordering => - RB.union(tree, ts.tree) + RB.union(tree.nn, ts.tree.nn) case _ => val it = that.iterator - var t = tree + var t = tree.nn while (it.hasNext) t = RB.update(t, it.next(), null, overwrite = false) t } @@ -188,12 +188,12 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ override def removedAll(that: IterableOnce[A]^): TreeSet[A] = that match { case ts: TreeSet[A] if ordering == ts.ordering => - newSetOrSelf(RB.difference(tree, ts.tree)) + newSetOrSelf(RB.difference(tree.nn, ts.tree.nn)) case _ => //TODO add an implementation of a mutable subtractor similar to TreeMap //but at least this doesn't create a TreeSet for each iteration object sub extends AbstractFunction1[A, Unit] { - var currentTree = tree + var currentTree = tree.nn override def apply(k: A): Unit = { currentTree = RB.delete(currentTree, k) } @@ -204,27 +204,27 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ override def intersect(that: collection.Set[A]): TreeSet[A] = that match { case ts: TreeSet[A] if ordering == ts.ordering => - newSetOrSelf(RB.intersect(tree, ts.tree)) + newSetOrSelf(RB.intersect(tree.nn, ts.tree.nn)) case _ => super.intersect(that) } override def diff(that: collection.Set[A]): TreeSet[A] = that match { case ts: TreeSet[A] if ordering == ts.ordering => - newSetOrSelf(RB.difference(tree, ts.tree)) + newSetOrSelf(RB.difference(tree.nn, ts.tree.nn)) case _ => super.diff(that) } - override def filter(f: A => Boolean): TreeSet[A] = newSetOrSelf(RB.filterEntries[A, Any](tree, {(k, _) => f(k)})) + override def filter(f: A => Boolean): TreeSet[A] = newSetOrSelf(RB.filterEntries[A, Any](tree.nn, {(k, _) => f(k)})) override def partition(p: A => Boolean): (TreeSet[A], TreeSet[A]) = { - val (l, r) = RB.partitionEntries(tree, {(a:A, _: Any) => p(a)}) + val (l, r) = RB.partitionEntries(tree.nn, {(a:A, _: Any) => p(a)}) (newSetOrSelf(l), newSetOrSelf(r)) } override def equals(obj: Any): Boolean = obj match { - case that: TreeSet[A @unchecked] if ordering == that.ordering => RB.keysEqual(tree, that.tree) + case that: TreeSet[A @unchecked] if ordering == that.ordering => RB.keysEqual(tree.nn, that.tree.nn) case _ => super.equals(obj) } @@ -254,9 +254,9 @@ object TreeSet extends SortedIterableFactory[TreeSet] { // Dotty doesn't infer that E =:= Int, since instantiation of covariant GADTs is unsound new TreeSet[E](tree) case _ => - var t: RB.Tree[E, Null] = null + var t: RB.Tree[E, Null] | Null = null val i = it.iterator - while (i.hasNext) t = RB.update(t, i.next(), null, overwrite = false) + while (i.hasNext) t = RB.update(t.nn, i.next(), null, overwrite = false) new TreeSet[E](t) } @@ -265,7 +265,7 @@ object TreeSet extends SortedIterableFactory[TreeSet] { extends RB.SetHelper[A] with ReusableBuilder[A, TreeSet[A]] { type Tree = RB.Tree[A, Any] - private [this] var tree:RB.Tree[A, Any] = null + private [this] var tree:RB.Tree[A, Any] | Null = null override def addOne(elem: A): this.type = { tree = mutableUpd(tree, elem) @@ -280,10 +280,10 @@ object TreeSet extends SortedIterableFactory[TreeSet] { // calling `beforePublish` makes `tree` immutable case ts: TreeSet[A] if ts.ordering == ordering => if (tree eq null) tree = ts.tree - else tree = RB.union(beforePublish(tree), ts.tree)(ordering) + else tree = RB.union(beforePublish(tree.nn), ts.tree)(ordering) case ts: TreeMap[A @unchecked, _] if ts.ordering == ordering => if (tree eq null) tree = ts.tree0 - else tree = RB.union(beforePublish(tree), ts.tree0)(ordering) + else tree = RB.union(beforePublish(tree.nn), ts.tree0)(ordering) case _ => super.addAll(xs) } @@ -294,6 +294,6 @@ object TreeSet extends SortedIterableFactory[TreeSet] { tree = null } - override def result(): TreeSet[A] = new TreeSet[A](beforePublish(tree))(ordering) + override def result(): TreeSet[A] = new TreeSet[A](beforePublish(tree.nn))(ordering) } } diff --git a/library/src/scala/collection/immutable/Vector.scala b/library/src/scala/collection/immutable/Vector.scala index 78768577b99b..8017b7b7aa06 100644 --- a/library/src/scala/collection/immutable/Vector.scala +++ b/library/src/scala/collection/immutable/Vector.scala @@ -364,7 +364,7 @@ private object Vector0 extends BigVector[Nothing](empty1, empty1, 0) { protected[this] def slice0(lo: Int, hi: Int): Vector[Nothing] = this protected[immutable] def vectorSliceCount: Int = 0 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = null + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] | Null = null protected[immutable] def vectorSlicePrefixLength(idx: Int): Int = 0 override def equals(o: Any): Boolean = { @@ -1170,7 +1170,7 @@ private final class Vector6[+A](_prefix1: Arr1, private[immutable] val len1: Int private final class VectorSliceBuilder(lo: Int, hi: Int) { //println(s"***** VectorSliceBuilder($lo, $hi)") - private[this] val slices = new Array[Array[AnyRef]](11) + private[this] val slices = new Array[Array[AnyRef] | Null](11) private[this] var len, pos, maxDim = 0 @inline private[this] def prefixIdx(n: Int) = n-1 @@ -1264,7 +1264,7 @@ private final class VectorSliceBuilder(lo: Int, hi: Int) { if((pre ne null) && (suf ne null)) { // The highest-dimensional data consists of two slices: concatenate if they fit into the main data array, // otherwise increase the dimension - if(pre.length + suf.length <= WIDTH-2) { + if(pre.nn.length + suf.nn.length <= WIDTH-2) { slices(prefixIdx(maxDim)) = concatArrays(pre, suf) slices(suffixIdx(maxDim)) = null } else resultDim += 1 @@ -1272,11 +1272,11 @@ private final class VectorSliceBuilder(lo: Int, hi: Int) { // A single highest-dimensional slice could have length WIDTH-1 if it came from a prefix or suffix but we // only allow WIDTH-2 for the main data, so increase the dimension in this case val one = if(pre ne null) pre else suf - if(one.length > WIDTH-2) resultDim += 1 + if(one.nn.length > WIDTH-2) resultDim += 1 } } - val prefix1 = slices(prefixIdx(1)) - val suffix1 = slices(suffixIdx(1)) + val prefix1 = slices(prefixIdx(1)).nn + val suffix1 = slices(suffixIdx(1)).nn val len1 = prefix1.length val res = (resultDim: @switch) match { case 2 => @@ -1393,7 +1393,7 @@ private final class VectorSliceBuilder(lo: Int, hi: Int) { override def toString: String = s"VectorSliceBuilder(lo=$lo, hi=$hi, len=$len, pos=$pos, maxDim=$maxDim)" - private[immutable] def getSlices: Array[Array[AnyRef]] = slices + private[immutable] def getSlices: Array[Array[AnyRef] | Null] = slices } @@ -1421,11 +1421,11 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { @inline def nonEmpty: Boolean = knownSize != 0 def clear(): Unit = { - a6 = null - a5 = null - a4 = null - a3 = null - a2 = null + a6 = null.asInstanceOf[Arr6] + a5 = null.asInstanceOf[Arr5] + a4 = null.asInstanceOf[Arr4] + a3 = null.asInstanceOf[Arr3] + a2 = null.asInstanceOf[Arr2] a1 = new Arr1(WIDTH) len1 = 0 lenRest = 0 @@ -1614,8 +1614,8 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { lenRest -= offset - newOffset offset = newOffset } - var a: Array[AnyRef] = null // the array we modify - var aParent: Array[AnyRef] = null // a's parent, so aParent(0) == a + var a: Array[AnyRef] = null.asInstanceOf[Array[AnyRef]] // the array we modify + var aParent: Array[AnyRef] = null.asInstanceOf[Array[AnyRef]] // a's parent, so aParent(0) == a if (depth >= 6) { a = a6.asInstanceOf[Array[AnyRef]] val i = offset >>> BITS5 @@ -2189,7 +2189,7 @@ private object VectorStatics { ac.asInstanceOf[Array[T]] } - final def prepend1IfSpace(prefix1: Arr1, xs: IterableOnce[_]^): Arr1 = xs match { + final def prepend1IfSpace(prefix1: Arr1, xs: IterableOnce[_]^): Arr1 | Null = xs match { case it: Iterable[_] => if(it.sizeCompare(WIDTH-prefix1.length) <= 0) { it.size match { @@ -2214,7 +2214,7 @@ private object VectorStatics { } else null } - final def append1IfSpace(suffix1: Arr1, xs: IterableOnce[_]^): Arr1 = xs match { + final def append1IfSpace(suffix1: Arr1, xs: IterableOnce[_]^): Arr1 | Null = xs match { case it: Iterable[_] => if(it.sizeCompare(WIDTH-suffix1.length) <= 0) { it.size match { @@ -2431,7 +2431,7 @@ private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLe } -private abstract class VectorStepperBase[A, Sub >: Null <: Stepper[A], Semi <: Sub](it: NewVectorIterator[A]) +private abstract class VectorStepperBase[A, Sub <: Stepper[A], Semi <: Sub](it: NewVectorIterator[A]) extends Stepper[A] with EfficientSplit { protected[this] def build(it: NewVectorIterator[A]): Semi @@ -2442,7 +2442,7 @@ private abstract class VectorStepperBase[A, Sub >: Null <: Stepper[A], Semi <: S final def estimateSize: Long = it.knownSize - def trySplit(): Sub = { + def trySplit(): Sub | Null = { val len = it.knownSize if(len > 1) build(it.split(len >>> 1)) else null diff --git a/library/src/scala/collection/immutable/VectorMap.scala b/library/src/scala/collection/immutable/VectorMap.scala index bf257fd7759e..ffd87448e97d 100644 --- a/library/src/scala/collection/immutable/VectorMap.scala +++ b/library/src/scala/collection/immutable/VectorMap.scala @@ -247,7 +247,8 @@ object VectorMap extends MapFactory[VectorMap] { private[immutable] final class VectorMapBuilder[K, V] extends mutable.Builder[(K, V), VectorMap[K, V]] { private[this] val vectorBuilder = new VectorBuilder[K] private[this] val mapBuilder = new MapBuilderImpl[K, (Int, V)] - private[this] var aliased: VectorMap[K, V] = _ + @annotation.stableNull + private[this] var aliased: VectorMap[K, V] | Null = null override def clear(): Unit = { vectorBuilder.clear() diff --git a/library/src/scala/collection/mutable/AnyRefMap.scala b/library/src/scala/collection/mutable/AnyRefMap.scala index 984fb1ff781e..0c361f31b847 100644 --- a/library/src/scala/collection/mutable/AnyRefMap.scala +++ b/library/src/scala/collection/mutable/AnyRefMap.scala @@ -70,9 +70,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi private[this] var mask = 0 private[this] var _size = 0 private[this] var _vacant = 0 - private[this] var _hashes: Array[Int] = null - private[this] var _keys: Array[AnyRef] = null - private[this] var _values: Array[AnyRef] = null + @annotation.stableNull private[this] var _hashes: Array[Int] | Null = null + @annotation.stableNull private[this] var _keys: Array[AnyRef | Null] | Null = null + @annotation.stableNull private[this] var _values: Array[AnyRef | Null] | Null = null if (initBlank) defaultInitialize(initialBufferSize) @@ -81,12 +81,12 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi if (n<0) 0x7 else (((1 << (32 - java.lang.Integer.numberOfLeadingZeros(n-1))) - 1) & 0x3FFFFFFF) | 0x7 _hashes = new Array[Int](mask+1) - _keys = new Array[AnyRef](mask+1) - _values = new Array[AnyRef](mask+1) + _keys = new Array[AnyRef | Null](mask+1) + _values = new Array[AnyRef | Null](mask+1) } private[collection] def initializeTo( - m: Int, sz: Int, vc: Int, hz: Array[Int], kz: Array[AnyRef], vz: Array[AnyRef] + m: Int, sz: Int, vc: Int, hz: Array[Int], kz: Array[AnyRef | Null], vz: Array[AnyRef | Null] ): Unit = { mask = m; _size = sz; _vacant = vc; _hashes = hz; _keys = kz; _values = vz } @@ -125,8 +125,8 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi var e = h & mask var x = 0 var g = 0 - val hashes = _hashes - val keys = _keys + val hashes = _hashes.nn + val keys = _keys.nn while ({ g = hashes(e); g != 0}) { if (g == h && { val q = keys(e); (q eq k) || ((q ne null) && (q equals k)) }) return e x += 1 @@ -140,8 +140,8 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi var x = 0 var g = 0 var o = -1 - while ({ g = _hashes(e); g != 0}) { - if (g == h && { val q = _keys(e); (q eq k) || ((q ne null) && (q equals k)) }) return e + while ({ g = _hashes.nn(e); g != 0}) { + if (g == h && { val q = _keys.nn(e); (q eq k) || ((q ne null) && (q equals k)) }) return e else if (o == -1 && g+g == 0) o = e x += 1 e = (e + 2*(x+1)*x - 3) & mask @@ -153,12 +153,12 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi override def get(key: K): Option[V] = { val i = seekEntry(hashOf(key), key) - if (i < 0) None else Some(_values(i).asInstanceOf[V]) + if (i < 0) None else Some(_values.nn(i).asInstanceOf[V]) } override def getOrElse[V1 >: V](key: K, default: => V1): V1 = { val i = seekEntry(hashOf(key), key) - if (i < 0) default else _values(i).asInstanceOf[V] + if (i < 0) default else _values.nn(i).asInstanceOf[V] } override def getOrElseUpdate(key: K, defaultValue: => V): V = { @@ -166,7 +166,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi var i = seekEntryOrOpen(h, key) if (i < 0) { val value = { - val ohs = _hashes + val ohs = _hashes.nn val j = i & IndexMask val oh = ohs(j) val ans = defaultValue @@ -175,7 +175,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi // - element added at `j`: since `i < 0`, the key was missing and `oh` is either 0 or MinValue. // If `defaultValue` added an element at `j` then `_hashes(j)` must be different now. // (`hashOf` never returns 0 or MinValue.) - if (ohs.ne(_hashes) || oh != _hashes(j)) { + if (ohs.ne(_hashes) || oh != _hashes.nn(j)) { i = seekEntryOrOpen(h, key) if (i >= 0) _size -= 1 } @@ -183,14 +183,14 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi } _size += 1 val j = i & IndexMask - _hashes(j) = h - _keys(j) = key.asInstanceOf[AnyRef] - _values(j) = value.asInstanceOf[AnyRef] + _hashes.nn(j) = h + _keys.nn(j) = key.asInstanceOf[AnyRef] + _values.nn(j) = value.asInstanceOf[AnyRef] if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() value } - else _values(i).asInstanceOf[V] + else _values.nn(i).asInstanceOf[V] } /** Retrieves the value associated with a key, or the default for that type if none exists @@ -200,9 +200,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi * may not exist, if the default null/zero is acceptable. For key/value * pairs that do exist, `apply` (i.e. `map(key)`) is equally fast. */ - def getOrNull(key: K): V = { + def getOrNull(key: K): V | Null = { val i = seekEntry(hashOf(key), key) - (if (i < 0) null else _values(i)).asInstanceOf[V] + if (i < 0) null else _values.nn(i).asInstanceOf[V] } /** Retrieves the value associated with a key. @@ -212,7 +212,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi */ override def apply(key: K): V = { val i = seekEntry(hashOf(key), key) - if (i < 0) defaultEntry(key) else _values(i).asInstanceOf[V] + if (i < 0) defaultEntry(key) else _values.nn(i).asInstanceOf[V] } /** Defers to defaultEntry to find a default value for the key. Throws an @@ -221,13 +221,13 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi override def default(key: K): V = defaultEntry(key) private def repack(newMask: Int): Unit = { - val oh = _hashes - val ok = _keys - val ov = _values + val oh = _hashes.nn + val ok = _keys.nn + val ov = _values.nn mask = newMask _hashes = new Array[Int](mask+1) - _keys = new Array[AnyRef](mask+1) - _values = new Array[AnyRef](mask+1) + _keys = new Array[AnyRef | Null](mask+1) + _values = new Array[AnyRef | Null](mask+1) _vacant = 0 var i = 0 while (i < oh.length) { @@ -235,10 +235,10 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi if (h+h != 0) { var e = h & mask var x = 0 - while (_hashes(e) != 0) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } - _hashes(e) = h - _keys(e) = ok(i) - _values(e) = ov(i) + while (_hashes.nn(e) != 0) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } + _hashes.nn(e) = h + _keys.nn(e) = ok(i) + _values.nn(e) = ov(i) } i += 1 } @@ -264,18 +264,18 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi val i = seekEntryOrOpen(h, key) if (i < 0) { val j = i & IndexMask - _hashes(j) = h - _keys(j) = key - _values(j) = value.asInstanceOf[AnyRef] + _hashes.nn(j) = h + _keys.nn(j) = key + _values.nn(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() None } else { - val ans = Some(_values(i).asInstanceOf[V]) - _hashes(i) = h - _values(i) = value.asInstanceOf[AnyRef] + val ans = Some(_values.nn(i).asInstanceOf[V]) + _hashes.nn(i) = h + _values.nn(i) = value.asInstanceOf[AnyRef] ans } } @@ -289,16 +289,16 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi val i = seekEntryOrOpen(h, key) if (i < 0) { val j = i & IndexMask - _hashes(j) = h - _keys(j) = key - _values(j) = value.asInstanceOf[AnyRef] + _hashes.nn(j) = h + _keys.nn(j) = key + _values.nn(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() } else { - _hashes(i) = h - _values(i) = value.asInstanceOf[AnyRef] + _hashes.nn(i) = h + _values.nn(i) = value.asInstanceOf[AnyRef] } } @@ -316,9 +316,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi if (i >= 0) { _size -= 1 _vacant += 1 - _hashes(i) = Int.MinValue - _keys(i) = null - _values(i) = null + _hashes.nn(i) = Int.MinValue + _keys.nn(i) = null + _values.nn(i) = null } this } @@ -334,13 +334,13 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi } private abstract class AnyRefMapIterator[A] extends AbstractIterator[A] { - private[this] val hz = _hashes - private[this] val kz = _keys - private[this] val vz = _values + private[this] val hz = _hashes.nn + private[this] val kz = _keys.nn + private[this] val vz = _values.nn private[this] var index = 0 - def hasNext: Boolean = index V, initi var i = 0 var e = _size while (e > 0) { - while(i < _hashes.length && { val h = _hashes(i); h+h == 0 && i < _hashes.length}) i += 1 - if (i < _hashes.length) { - f((_keys(i).asInstanceOf[K], _values(i).asInstanceOf[V])) + while(i < _hashes.nn.length && { val h = _hashes.nn(i); h+h == 0 && i < _hashes.nn.length}) i += 1 + if (i < _hashes.nn.length) { + f((_keys.nn(i).asInstanceOf[K], _values.nn(i).asInstanceOf[V])) i += 1 e -= 1 } @@ -381,9 +381,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi var i = 0 var e = _size while (e > 0) { - while(i < _hashes.length && { val h = _hashes(i); h+h == 0 && i < _hashes.length}) i += 1 - if (i < _hashes.length) { - f(_keys(i).asInstanceOf[K], _values(i).asInstanceOf[V]) + while(i < _hashes.nn.length && { val h = _hashes.nn(i); h+h == 0 && i < _hashes.nn.length}) i += 1 + if (i < _hashes.nn.length) { + f(_keys.nn(i).asInstanceOf[K], _values.nn(i).asInstanceOf[V]) i += 1 e -= 1 } @@ -392,11 +392,11 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi } override def clone(): AnyRefMap[K, V] = { - val hz = java.util.Arrays.copyOf(_hashes, _hashes.length) - val kz = java.util.Arrays.copyOf(_keys, _keys.length) - val vz = java.util.Arrays.copyOf(_values, _values.length) + val hz = java.util.Arrays.copyOf(_hashes.nn, _hashes.nn.length) + val kz = java.util.Arrays.copyOf(_keys.nn, _keys.nn.length) + val vz = java.util.Arrays.copyOf(_values.nn, _values.nn.length) val arm = new AnyRefMap[K, V](defaultEntry, 1, initBlank = false) - arm.initializeTo(mask, _size, _vacant, hz, kz, vz) + arm.initializeTo(mask, _size, _vacant, hz, kz, vz) arm } @@ -422,13 +422,13 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi override def updated[V1 >: V](key: K, value: V1): AnyRefMap[K, V1] = clone().asInstanceOf[AnyRefMap[K, V1]].addOne(key, value) - private[this] def foreachElement[A,B](elems: Array[AnyRef], f: A => B): Unit = { + private[this] def foreachElement[A,B](elems: Array[AnyRef | Null] | Null, f: A => B): Unit = { var i,j = 0 - while (i < _hashes.length & j < _size) { - val h = _hashes(i) + while (i < _hashes.nn.length & j < _size) { + val h = _hashes.nn(i) if (h+h != 0) { j += 1 - f(elems(i).asInstanceOf[A]) + f(elems.nn(i).asInstanceOf[A]) } i += 1 } @@ -445,16 +445,16 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi * collection immediately. */ def mapValuesNow[V1](f: V => V1): AnyRefMap[K, V1] = { - val arm = new AnyRefMap[K,V1](AnyRefMap.exceptionDefault, 1, initBlank = false) - val hz = java.util.Arrays.copyOf(_hashes, _hashes.length) - val kz = java.util.Arrays.copyOf(_keys, _keys.length) - val vz = new Array[AnyRef](_values.length) + val arm = new AnyRefMap[K,V1](AnyRefMap.exceptionDefault, 1, initBlank = false) + val hz = java.util.Arrays.copyOf(_hashes.nn, _hashes.nn.length) + val kz = java.util.Arrays.copyOf(_keys.nn, _keys.nn.length) + val vz = new Array[AnyRef | Null](_values.nn.length) var i,j = 0 - while (i < _hashes.length & j < _size) { - val h = _hashes(i) + while (i < _hashes.nn.length & j < _size) { + val h = _hashes.nn(i) if (h+h != 0) { j += 1 - vz(i) = f(_values(i).asInstanceOf[V]).asInstanceOf[AnyRef] + vz(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef] } i += 1 } @@ -473,11 +473,11 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi */ def transformValuesInPlace(f: V => V): this.type = { var i,j = 0 - while (i < _hashes.length & j < _size) { - val h = _hashes(i) + while (i < _hashes.nn.length & j < _size) { + val h = _hashes.nn(i) if (h+h != 0) { j += 1 - _values(i) = f(_values(i).asInstanceOf[V]).asInstanceOf[AnyRef] + _values.nn(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef] } i += 1 } @@ -513,9 +513,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi override def clear(): Unit = { import java.util.Arrays.fill - fill(_keys, null) - fill(_values, null) - fill(_hashes, 0) + fill(_keys.nn, null) + fill(_values.nn, null) + fill(_hashes.nn, 0) _size = 0 _vacant = 0 } diff --git a/library/src/scala/collection/mutable/ArrayBuilder.scala b/library/src/scala/collection/mutable/ArrayBuilder.scala index 608fb85564a3..f3f007e8569b 100644 --- a/library/src/scala/collection/mutable/ArrayBuilder.scala +++ b/library/src/scala/collection/mutable/ArrayBuilder.scala @@ -27,7 +27,7 @@ sealed abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable { protected[this] var capacity: Int = 0 - protected[this] def elems: Array[T] // may not be allocated at size = capacity = 0 + protected[this] def elems: Array[T] | Null // may not be allocated at size = capacity = 0 protected var size: Int = 0 /** Current number of elements. */ @@ -61,7 +61,7 @@ sealed abstract class ArrayBuilder[T] private def doAddAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = { if (length > 0) { ensureSize(this.size + length) - Array.copy(xs, offset, elems, this.size, length) + Array.copy(xs, offset, elems.nn, this.size, length) size += length } this @@ -71,7 +71,7 @@ sealed abstract class ArrayBuilder[T] val k = xs.knownSize if (k > 0) { ensureSize(this.size + k) - val actual = IterableOnce.copyElemsToArray(xs, elems, this.size) + val actual = IterableOnce.copyElemsToArray(xs, elems.nn, this.size) if (actual != k) throw new IllegalStateException(s"Copied $actual of $k") size += k } else if (k < 0) super.addAll(xs) @@ -111,7 +111,7 @@ object ArrayBuilder { * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. */ @SerialVersionUID(3L) - final class ofRef[T <: AnyRef](implicit ct: ClassTag[T]) extends ArrayBuilder[T] { + final class ofRef[T <: AnyRef | Null](implicit ct: ClassTag[T]) extends ArrayBuilder[T] { protected var elems: Array[T] = _ @@ -137,7 +137,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[T]] res } else mkArray(size) @@ -184,7 +184,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Byte]] res } else mkArray(size) @@ -226,7 +226,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Short]] res } else mkArray(size) @@ -268,7 +268,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Char]] res } else mkArray(size) @@ -310,7 +310,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Int]] res } else mkArray(size) @@ -352,7 +352,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Long]] res } else mkArray(size) @@ -394,7 +394,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Float]] res } else mkArray(size) @@ -436,7 +436,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Double]] res } else mkArray(size) @@ -479,7 +479,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Boolean]] res } else mkArray(size) diff --git a/library/src/scala/collection/mutable/ArrayDeque.scala b/library/src/scala/collection/mutable/ArrayDeque.scala index e395a651778c..08a89754720a 100644 --- a/library/src/scala/collection/mutable/ArrayDeque.scala +++ b/library/src/scala/collection/mutable/ArrayDeque.scala @@ -39,7 +39,7 @@ import scala.reflect.ClassTag * @define willNotTerminateInf */ class ArrayDeque[A] protected ( - protected var array: Array[AnyRef], + protected var array: Array[AnyRef | Null], private[ArrayDeque] var start: Int, private[ArrayDeque] var end: Int ) extends AbstractBuffer[A] @@ -53,7 +53,7 @@ class ArrayDeque[A] protected ( reset(array, start, end) - private[this] def reset(array: Array[AnyRef], start: Int, end: Int) = { + private[this] def reset(array: Array[AnyRef | Null], start: Int, end: Int) = { assert((array.length & (array.length - 1)) == 0, s"Array.length must be power of 2") requireBounds(idx = start, until = array.length) requireBounds(idx = end, until = array.length) @@ -463,7 +463,7 @@ class ArrayDeque[A] protected ( this } - protected def ofArray(array: Array[AnyRef], end: Int): ArrayDeque[A] = + protected def ofArray(array: Array[AnyRef | Null], end: Int): ArrayDeque[A] = new ArrayDeque[A](array, start = 0, end) override def copyToArray[B >: A](dest: Array[B], destStart: Int, len: Int): Int = { @@ -566,18 +566,18 @@ object ArrayDeque extends StrictOptimizedSeqFactory[ArrayDeque] { require(len >= 0, s"Non-negative array size required") val size = (1 << 31) >>> java.lang.Integer.numberOfLeadingZeros(len) << 1 require(size >= 0, s"ArrayDeque too big - cannot allocate ArrayDeque of length $len") - new Array[AnyRef](Math.max(size, DefaultInitialSize)) + new Array[AnyRef | Null](Math.max(size, DefaultInitialSize)) } } transparent trait ArrayDequeOps[A, +CC[_] <: caps.Pure, +C <: AnyRef] extends StrictOptimizedSeqOps[A, CC, C] { - protected def array: Array[AnyRef] + protected def array: Array[AnyRef | Null] final override def clone(): C = klone() protected def klone(): C - protected def ofArray(array: Array[AnyRef], end: Int): C + protected def ofArray(array: Array[AnyRef | Null], end: Int): C protected def start_+(idx: Int): Int diff --git a/library/src/scala/collection/mutable/ArraySeq.scala b/library/src/scala/collection/mutable/ArraySeq.scala index 53afc6cf66be..500056893b67 100644 --- a/library/src/scala/collection/mutable/ArraySeq.scala +++ b/library/src/scala/collection/mutable/ArraySeq.scala @@ -138,7 +138,7 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self => }).asInstanceOf[ArraySeq[T]] @SerialVersionUID(3L) - final class ofRef[T <: AnyRef](val array: Array[T]) extends ArraySeq[T] { + final class ofRef[T <: AnyRef | Null](val array: Array[T]) extends ArraySeq[T] { def elemTag: ClassTag[T] = ClassTag[T](array.getClass.getComponentType) def length: Int = array.length def apply(index: Int): T = array(index) diff --git a/library/src/scala/collection/mutable/BitSet.scala b/library/src/scala/collection/mutable/BitSet.scala index 03f81bf64907..172c483fc3e6 100644 --- a/library/src/scala/collection/mutable/BitSet.scala +++ b/library/src/scala/collection/mutable/BitSet.scala @@ -329,21 +329,21 @@ class BitSet(protected[collection] final var elems: Array[Long]) // * over-allocating -- the resulting array will be exactly the right size // * multiple resizing allocations -- the array is allocated one time, not log(n) times. var i = nwords - 1 - var newArray: Array[Long] = null + var newArray: Array[Long] | Null = null while (i >= 0) { val w = BitSetOps.computeWordForFilter(pred, isFlipped, word(i), i) if (w != 0L) { if (newArray eq null) { newArray = new Array(i + 1) } - newArray(i) = w + newArray.nn(i) = w } i -= 1 } if (newArray eq null) { empty } else { - fromBitMaskNoCopy(newArray) + fromBitMaskNoCopy(newArray.nn) } } diff --git a/library/src/scala/collection/mutable/CollisionProofHashMap.scala b/library/src/scala/collection/mutable/CollisionProofHashMap.scala index 35fa6393deab..6519df0ce3a2 100644 --- a/library/src/scala/collection/mutable/CollisionProofHashMap.scala +++ b/library/src/scala/collection/mutable/CollisionProofHashMap.scala @@ -15,6 +15,7 @@ package mutable import scala.language.`2.13` import language.experimental.captureChecking +import scala.language.unsafeNulls import scala.{unchecked => uc} import scala.annotation.{implicitNotFound, tailrec, unused} import scala.annotation.unchecked.uncheckedVariance diff --git a/library/src/scala/collection/mutable/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index 3204d0924110..01a6e4bbcbee 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -15,6 +15,8 @@ package mutable import scala.language.`2.13` import language.experimental.captureChecking +import scala.language.unsafeNulls + import scala.annotation.{nowarn, tailrec} import scala.collection.Stepper.EfficientSplit import scala.collection.generic.DefaultSerializationProxy @@ -52,7 +54,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) import HashMap.Node /** The actual hash table. */ - private[this] var table = new Array[Node[K, V]](tableSizeFor(initialCapacity)) + private[this] var table = new Array[Node[K, V] | Null](tableSizeFor(initialCapacity)) /** The next size value at which to resize (capacity * load factor). */ private[this] var threshold: Int = newThreshold(table.length) @@ -83,7 +85,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) override def contains(key: K): Boolean = findNode(key) ne null - @`inline` private[this] def findNode(key: K): Node[K, V] = { + @`inline` private[this] def findNode(key: K): Node[K, V] | Null = { val hash = computeHash(key) table(index(hash)) match { case null => null @@ -137,19 +139,19 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) val hash = computeHash(key) val indexedHash = index(hash) - var foundNode: Node[K, V] = null - var previousNode: Node[K, V] = null + var foundNode: Node[K, V] | Null = null + var previousNode: Node[K, V] | Null = null table(indexedHash) match { case null => case nd => @tailrec - def findNode(prev: Node[K, V], nd: Node[K, V], k: K, h: Int): Unit = { + def findNode(prev: Node[K, V] | Null, nd: Node[K, V], k: K, h: Int): Unit = { if (h == nd.hash && k == nd.key) { previousNode = prev foundNode = nd } else if ((nd.next eq null) || (nd.hash > h)) () - else findNode(nd, nd.next, k, h) + else findNode(nd, nd.next.nn, k, h) } findNode(null, nd, key, hash) @@ -166,8 +168,8 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) case (None, None) => // do nothing case (Some(_), None) => - if (previousNode != null) previousNode.next = foundNode.next - else table(indexedHash) = foundNode.next + if (previousNode != null) previousNode.nn.next = foundNode.nn.next + else table(indexedHash) = foundNode.nn.next contentSize -= 1 case (None, Some(value)) => @@ -178,7 +180,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) } else indexedHash put0(key, value, getOld = false, hash, newIndexedHash) - case (Some(_), Some(newValue)) => foundNode.value = newValue + case (Some(_), Some(newValue)) => foundNode.nn.value = newValue } nextValue } @@ -223,13 +225,13 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) * @param hash the **improved** hashcode of `key` (see computeHash) * @param getOld if true, then the previous value for `key` will be returned, otherwise, false */ - private[this] def put0(key: K, value: V, hash: Int, getOld: Boolean): Some[V] = { + private[this] def put0(key: K, value: V, hash: Int, getOld: Boolean): Some[V] | Null = { if(contentSize + 1 >= threshold) growTable(table.length * 2) val idx = index(hash) put0(key, value, getOld, hash, idx) } - private[this] def put0(key: K, value: V, getOld: Boolean): Some[V] = { + private[this] def put0(key: K, value: V, getOld: Boolean): Some[V] | Null = { if(contentSize + 1 >= threshold) growTable(table.length * 2) val hash = computeHash(key) val idx = index(hash) @@ -237,13 +239,13 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) } - private[this] def put0(key: K, value: V, getOld: Boolean, hash: Int, idx: Int): Some[V] = { + private[this] def put0(key: K, value: V, getOld: Boolean, hash: Int, idx: Int): Some[V] | Null = { table(idx) match { case null => table(idx) = new Node[K, V](key, hash, value, null) case old => - var prev: Node[K, V] = null - var n = old + var prev: Node[K, V] | Null = null + var n: Node[K, V] | Null = old while((n ne null) && n.hash <= hash) { if(n.hash == hash && key == n.key) { val old = n.value @@ -254,13 +256,13 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) n = n.next } if(prev eq null) table(idx) = new Node(key, hash, value, old) - else prev.next = new Node(key, hash, value, prev.next) + else prev.nn.next = new Node(key, hash, value, prev.nn.next) } contentSize += 1 null } - private def remove0(elem: K) : Node[K, V] = remove0(elem, computeHash(elem)) + private def remove0(elem: K) : Node[K, V] | Null = remove0(elem, computeHash(elem)) /** Removes a key from this map if it exists * @@ -268,7 +270,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) * @param hash the **improved** hashcode of `element` (see computeHash) * @return the node that contained element if it was present, otherwise null */ - private[this] def remove0(elem: K, hash: Int) : Node[K, V] = { + private[this] def remove0(elem: K, hash: Int) : Node[K, V] | Null = { val idx = index(hash) table(idx) match { case null => null @@ -296,7 +298,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) private[this] abstract class HashMapIterator[A] extends AbstractIterator[A] { private[this] var i = 0 - private[this] var node: Node[K, V] = null + private[this] var node: Node[K, V] | Null = null private[this] val len = table.length protected[this] def extract(nd: Node[K, V]): A @@ -316,8 +318,8 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) def next(): A = if(!hasNext) Iterator.empty.next() else { - val r = extract(node) - node = node.next + val r = extract(node.nn) + node = node.nn.next r } } @@ -350,16 +352,16 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape. - parUnbox(new convert.impl.AnyTableStepper[(K, V), Node[K, V]](size, table, _.next, node => (node.key, node.value), 0, table.length)). + parUnbox(new convert.impl.AnyTableStepper[(K, V), Node[K, V]](size, table, _.next.nn, node => (node.key, node.value), 0, table.length)). asInstanceOf[S with EfficientSplit] override def keyStepper[S <: Stepper[_]](implicit shape: StepperShape[K, S]): S with EfficientSplit = { import convert.impl._ val s = shape.shape match { - case StepperShape.IntShape => new IntTableStepper[Node[K, V]] (size, table, _.next, _.key.asInstanceOf[Int], 0, table.length) - case StepperShape.LongShape => new LongTableStepper[Node[K, V]] (size, table, _.next, _.key.asInstanceOf[Long], 0, table.length) - case StepperShape.DoubleShape => new DoubleTableStepper[Node[K, V]](size, table, _.next, _.key.asInstanceOf[Double], 0, table.length) - case _ => shape.parUnbox(new AnyTableStepper[K, Node[K, V]](size, table, _.next, _.key, 0, table.length)) + case StepperShape.IntShape => new IntTableStepper[Node[K, V]] (size, table, _.next.nn, _.key.asInstanceOf[Int], 0, table.length) + case StepperShape.LongShape => new LongTableStepper[Node[K, V]] (size, table, _.next.nn, _.key.asInstanceOf[Long], 0, table.length) + case StepperShape.DoubleShape => new DoubleTableStepper[Node[K, V]](size, table, _.next.nn, _.key.asInstanceOf[Double], 0, table.length) + case _ => shape.parUnbox(new AnyTableStepper[K, Node[K, V]](size, table, _.next.nn, _.key, 0, table.length)) } s.asInstanceOf[S with EfficientSplit] } @@ -367,10 +369,10 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) override def valueStepper[S <: Stepper[_]](implicit shape: StepperShape[V, S]): S with EfficientSplit = { import convert.impl._ val s = shape.shape match { - case StepperShape.IntShape => new IntTableStepper[Node[K, V]] (size, table, _.next, _.value.asInstanceOf[Int], 0, table.length) - case StepperShape.LongShape => new LongTableStepper[Node[K, V]] (size, table, _.next, _.value.asInstanceOf[Long], 0, table.length) - case StepperShape.DoubleShape => new DoubleTableStepper[Node[K, V]](size, table, _.next, _.value.asInstanceOf[Double], 0, table.length) - case _ => shape.parUnbox(new AnyTableStepper[V, Node[K, V]](size, table, _.next, _.value, 0, table.length)) + case StepperShape.IntShape => new IntTableStepper[Node[K, V]] (size, table, _.next.nn, _.value.asInstanceOf[Int], 0, table.length) + case StepperShape.LongShape => new LongTableStepper[Node[K, V]] (size, table, _.next.nn, _.value.asInstanceOf[Long], 0, table.length) + case StepperShape.DoubleShape => new DoubleTableStepper[Node[K, V]](size, table, _.next.nn, _.value.asInstanceOf[Double], 0, table.length) + case _ => shape.parUnbox(new AnyTableStepper[V, Node[K, V]](size, table, _.next.nn, _.value, 0, table.length)) } s.asInstanceOf[S with EfficientSplit] } @@ -380,11 +382,11 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) throw new RuntimeException(s"new HashMap table size $newlen exceeds maximum") var oldlen = table.length threshold = newThreshold(newlen) - if(size == 0) table = new Array(newlen) + if(size == 0) table = new Array[Node[K, V] | Null](newlen) else { table = java.util.Arrays.copyOf(table, newlen) - val preLow: Node[K, V] = new Node(null.asInstanceOf[K], 0, null.asInstanceOf[V], null) - val preHigh: Node[K, V] = new Node(null.asInstanceOf[K], 0, null.asInstanceOf[V], null) + val preLow: Node[K, V] | Null = new Node(null.asInstanceOf[K], 0, null.asInstanceOf[V], null) + val preHigh: Node[K, V] | Null = new Node(null.asInstanceOf[K], 0, null.asInstanceOf[V], null) // Split buckets until the new length has been reached. This could be done more // efficiently when growing an already filled table to more than double the size. while(oldlen < newlen) { @@ -392,27 +394,27 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) while (i < oldlen) { val old = table(i) if(old ne null) { - preLow.next = null - preHigh.next = null - var lastLow: Node[K, V] = preLow - var lastHigh: Node[K, V] = preHigh + preLow.nn.next = null + preHigh.nn.next = null + var lastLow: Node[K, V] | Null = preLow + var lastHigh: Node[K, V] | Null = preHigh var n = old while(n ne null) { val next = n.next if((n.hash & oldlen) == 0) { // keep low - lastLow.next = n + lastLow.nn.next = n lastLow = n } else { // move to high - lastHigh.next = n + lastHigh.nn.next = n lastHigh = n } - n = next + n = next.nn } - lastLow.next = null - if(old ne preLow.next) table(i) = preLow.next - if(preHigh.next ne null) { - table(i + oldlen) = preHigh.next - lastHigh.next = null + lastLow.nn.next = null + if(old ne preLow.nn.next) table(i) = preLow.nn.next.nn + if(preHigh.nn.next ne null) { + table(i + oldlen) = preHigh.nn.next.nn + lastHigh.nn.next = null } } i += 1 @@ -503,7 +505,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) var i = 0 while(i < len) { val n = table(i) - if(n ne null) n.foreach(f) + if(n ne null) n.nn.foreach(f) i += 1 } } @@ -513,7 +515,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) var i = 0 while(i < len) { val n = table(i) - if(n ne null) n.foreachEntry(f) + if(n ne null) n.nn.foreachEntry(f) i += 1 } } @@ -528,7 +530,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) var head = table(bucket) while ((head ne null) && !p(head.key, head.value)) { - head = head.next + head = head.next.nn contentSize -= 1 } @@ -543,7 +545,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) prev.next = next.next contentSize -= 1 } - next = next.next + next = next.next.nn } } @@ -562,7 +564,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) var n = table(i) while (n ne null) { n.value = f(n.key, n.value) - n = n.next + n = n.next.nn } i += 1 } @@ -625,32 +627,33 @@ object HashMap extends MapFactory[HashMap] { def newBuilder: Builder[(K, V), HashMap[K, V]] = HashMap.newBuilder(tableLength, loadFactor) } - private[collection] final class Node[K, V](_key: K, _hash: Int, private[this] var _value: V, private[this] var _next: Node[K, V]) { + private[collection] final class Node[K, V](_key: K, _hash: Int, private[this] var _value: V, private[this] var _next: Node[K, V] | Null) { def key: K = _key def hash: Int = _hash def value: V = _value def value_= (v: V): Unit = _value = v - def next: Node[K, V] = _next - def next_= (n: Node[K, V]): Unit = _next = n + def next: Node[K, V] | Null = _next + def next_= (n: Node[K, V] | Null): Unit = _next = n @tailrec - def findNode(k: K, h: Int): Node[K, V] = + def findNode(k: K, h: Int): Node[K, V] | Null = if(h == _hash && k == _key) this else if((_next eq null) || (_hash > h)) null - else _next.findNode(k, h) + else _next.nn.findNode(k, h) @tailrec def foreach[U](f: ((K, V)) => U): Unit = { f((_key, _value)) - if(_next ne null) _next.foreach(f) + if(_next ne null) _next.nn.foreach(f) } @tailrec def foreachEntry[U](f: (K, V) => U): Unit = { f(_key, _value) - if(_next ne null) _next.foreachEntry(f) + if(_next ne null) _next.nn.foreachEntry(f) } override def toString = s"Node($key, $value, $hash) -> $next" } } + diff --git a/library/src/scala/collection/mutable/HashSet.scala b/library/src/scala/collection/mutable/HashSet.scala index a92db177c110..f8a56dba4fbf 100644 --- a/library/src/scala/collection/mutable/HashSet.scala +++ b/library/src/scala/collection/mutable/HashSet.scala @@ -15,6 +15,8 @@ package mutable import scala.language.`2.13` import language.experimental.captureChecking +import scala.language.unsafeNulls + import scala.annotation.tailrec import scala.collection.Stepper.EfficientSplit import scala.collection.generic.DefaultSerializationProxy @@ -47,7 +49,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) * - The sum of the lengths of all buckets is equal to contentSize. */ /** The actual hash table. */ - private[this] var table = new Array[Node[A]](tableSizeFor(initialCapacity)) + private[this] var table = new Array[Node[A] | Null](tableSizeFor(initialCapacity)) /** The next size value at which to resize (capacity * load factor). */ private[this] var threshold: Int = newThreshold(table.length) @@ -74,7 +76,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) override def contains(elem: A): Boolean = findNode(elem) ne null - @`inline` private[this] def findNode(elem: A): Node[A] = { + @`inline` private[this] def findNode(elem: A): Node[A] | Null = { val hash = computeHash(elem) table(index(hash)) match { case null => null @@ -158,17 +160,17 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) case null => table(idx) = new Node(elem, hash, null) case old => - var prev: Node[A] = null + var prev: Node[A] | Null = null var n = old while((n ne null) && n.hash <= hash) { if(n.hash == hash && elem == n.key) return false prev = n - n = n.next + n = n.nn.next } if(prev eq null) table(idx) = new Node(elem, hash, old) else - prev.next = new Node(elem, hash, prev.next) + prev.nn.next = new Node(elem, hash, prev.nn.next) } contentSize += 1 true @@ -194,7 +196,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) return true } prev = next - next = next.next + next = next.nn.next } false } @@ -204,7 +206,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) private[this] abstract class HashSetIterator[B] extends AbstractIterator[B] { private[this] var i = 0 - private[this] var node: Node[A] = null + private[this] var node: Node[A] | Null = null private[this] val len = table.length protected[this] def extract(nd: Node[A]): B @@ -224,8 +226,8 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) def next(): B = if(!hasNext) Iterator.empty.next() else { - val r = extract(node) - node = node.next + val r = extract(node.nn) + node = node.nn.next r } } @@ -242,10 +244,10 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) override def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S with EfficientSplit = { import convert.impl._ val s = shape.shape match { - case StepperShape.IntShape => new IntTableStepper[Node[A]] (size, table, _.next, _.key.asInstanceOf[Int], 0, table.length) - case StepperShape.LongShape => new LongTableStepper[Node[A]] (size, table, _.next, _.key.asInstanceOf[Long], 0, table.length) - case StepperShape.DoubleShape => new DoubleTableStepper[Node[A]](size, table, _.next, _.key.asInstanceOf[Double], 0, table.length) - case _ => shape.parUnbox(new AnyTableStepper[A, Node[A]](size, table, _.next, _.key, 0, table.length)) + case StepperShape.IntShape => new IntTableStepper[Node[A]] (size, table, _.nn.next.nn, _.key.asInstanceOf[Int], 0, table.length) + case StepperShape.LongShape => new LongTableStepper[Node[A]] (size, table, _.nn.next.nn, _.key.asInstanceOf[Long], 0, table.length) + case StepperShape.DoubleShape => new DoubleTableStepper[Node[A]](size, table, _.nn.next.nn, _.key.asInstanceOf[Double], 0, table.length) + case _ => shape.parUnbox(new AnyTableStepper[A, Node[A]](size, table, _.nn.next.nn, _.key, 0, table.length)) } s.asInstanceOf[S with EfficientSplit] } @@ -253,7 +255,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) private[this] def growTable(newlen: Int) = { var oldlen = table.length threshold = newThreshold(newlen) - if(size == 0) table = new Array(newlen) + if(size == 0) table = new Array[Node[A] | Null](newlen) else { table = java.util.Arrays.copyOf(table, newlen) val preLow: Node[A] = new Node(null.asInstanceOf[A], 0, null) @@ -282,9 +284,9 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) n = next } lastLow.next = null - if(old ne preLow.next) table(i) = preLow.next + if(old ne preLow.next) table(i) = preLow.nn.next if(preHigh.next ne null) { - table(i + oldlen) = preHigh.next + table(i + oldlen) = preHigh.nn.next lastHigh.next = null } } @@ -303,7 +305,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) var head = table(bucket) while ((head ne null) && !p(head.key)) { - head = head.next + head = head.nn.next contentSize -= 1 } @@ -318,7 +320,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) prev.next = next.next contentSize -= 1 } - next = next.next + next = next.nn.next } } @@ -375,7 +377,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) var i = 0 while(i < len) { val n = table(i) - if(n ne null) n.foreach(f) + if(n ne null) n.nn.foreach(f) i += 1 } } @@ -435,22 +437,22 @@ object HashSet extends IterableFactory[HashSet] { def newBuilder: Builder[A, HashSet[A]] = HashSet.newBuilder(tableLength, loadFactor) } - private[collection] final class Node[K](_key: K, _hash: Int, private[this] var _next: Node[K]) { + private[collection] final class Node[K](_key: K, _hash: Int, private[this] var _next: Node[K] | Null) { def key: K = _key def hash: Int = _hash - def next: Node[K] = _next - def next_= (n: Node[K]): Unit = _next = n + def next: Node[K] | Null = _next + def next_= (n: Node[K] | Null): Unit = _next = n @tailrec - def findNode(k: K, h: Int): Node[K] = + def findNode(k: K, h: Int): Node[K] | Null = if(h == _hash && k == _key) this else if((_next eq null) || (_hash > h)) null - else _next.findNode(k, h) + else _next.nn.findNode(k, h) @tailrec def foreach[U](f: K => U): Unit = { f(_key) - if(_next ne null) _next.foreach(f) + if(_next ne null) _next.nn.foreach(f) } override def toString = s"Node($key, $hash) -> $next" diff --git a/library/src/scala/collection/mutable/HashTable.scala b/library/src/scala/collection/mutable/HashTable.scala index 738adce7dfaa..7474ffc54d4f 100644 --- a/library/src/scala/collection/mutable/HashTable.scala +++ b/library/src/scala/collection/mutable/HashTable.scala @@ -38,7 +38,7 @@ import java.lang.Integer * @tparam A type of the elements contained in this hash table. */ // Not used in the standard library, but used in scala-parallel-collections -private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashUtils[A] { +private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends HashTable.HashUtils[A] { // Replacing Entry type parameter by abstract type member here allows to not expose to public // implementation-specific entry classes such as `DefaultEntry` or `LinkedEntry`. // However, I'm afraid it's too late now for such breaking change. @@ -48,7 +48,7 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] /** The actual hash table. */ - protected[collection] var table: Array[HashEntry[A, Entry]] = new Array(initialCapacity) + protected[collection] var table: Array[HashEntry[A, Entry] | Null] = new Array(initialCapacity) /** The number of mappings contained in this hash table. */ @@ -62,7 +62,8 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] /** The array keeping track of the number of elements in 32 element blocks. */ - protected var sizemap: Array[Int] = null + @annotation.stableNull + protected var sizemap: Array[Int] | Null = null protected var seedvalue: Int = tableSizeSeed @@ -132,12 +133,12 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] /** Find entry with given key in table, null if not found. */ - final def findEntry(key: A): Entry = + final def findEntry(key: A): Entry | Null = findEntry0(key, index(elemHashCode(key))) - protected[collection] final def findEntry0(key: A, h: Int): Entry = { - var e = table(h).asInstanceOf[Entry] - while (e != null && !elemEquals(e.key, key)) e = e.next + protected[collection] final def findEntry0(key: A, h: Int): Entry | Null = { + var e = table(h).asInstanceOf[Entry | Null] + while (e != null && !elemEquals(e.key, key)) e = e.nn.next e } @@ -149,7 +150,7 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] } protected[collection] final def addEntry0(e: Entry, h: Int): Unit = { - e.next = table(h).asInstanceOf[Entry] + e.next = table(h).asInstanceOf[Entry | Null] table(h) = e tableSize = tableSize + 1 nnSizeMapAdd(h) @@ -163,7 +164,7 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] * Returns entry found in table or null. * New entries are created by calling `createNewEntry` method. */ - def findOrAddEntry(key: A, value: B): Entry = { + def findOrAddEntry(key: A, value: B): Entry | Null = { val h = index(elemHashCode(key)) val e = findEntry0(key, h) if (e ne null) e else { addEntry0(createNewEntry(key, value), h); null } @@ -177,28 +178,28 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] /** Remove entry from table if present. */ - final def removeEntry(key: A) : Entry = { + final def removeEntry(key: A) : Entry | Null = { removeEntry0(key, index(elemHashCode(key))) } /** Remove entry from table if present. */ - private[collection] final def removeEntry0(key: A, h: Int) : Entry = { - var e = table(h).asInstanceOf[Entry] + private[collection] final def removeEntry0(key: A, h: Int) : Entry | Null = { + var e = table(h).asInstanceOf[Entry | Null] if (e != null) { if (elemEquals(e.key, key)) { - table(h) = e.next + table(h) = e.nn.next tableSize = tableSize - 1 nnSizeMapRemove(h) e.next = null return e } else { - var e1 = e.next + var e1 = e.nn.next while (e1 != null && !elemEquals(e1.key, key)) { e = e1 - e1 = e1.next + e1 = e1.nn.next } if (e1 != null) { - e.next = e1.next + e.nn.next = e1.nn.next tableSize = tableSize - 1 nnSizeMapRemove(h) e1.next = null @@ -219,7 +220,7 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] def hasNext = es != null def next() = { val res = es - es = es.next + es = es.nn.next while (es == null && idx > 0) { idx = idx - 1 es = iterTable(idx) @@ -235,7 +236,7 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] var es = iterTable(idx) while (es != null) { - val next = es.next // Cache next in case f removes es. + val next = es.nn.next // Cache next in case f removes es. f(es.asInstanceOf[Entry]) es = next @@ -263,9 +264,9 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] while (i >= 0) { var e = oldTable(i) while (e != null) { - val h = index(elemHashCode(e.key)) - val e1 = e.next - e.next = table(h).asInstanceOf[Entry] + val h = index(elemHashCode(e.nn.key)) + val e1 = e.nn.next + e.nn.next = table(h).asInstanceOf[Entry | Null] table(h) = e e = e1 nnSizeMapAdd(h) @@ -295,17 +296,17 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] * there. */ protected final def nnSizeMapAdd(h: Int) = if (sizemap ne null) { - sizemap(h >> sizeMapBucketBitSize) += 1 + sizemap.nn(h >> sizeMapBucketBitSize) += 1 } protected final def nnSizeMapRemove(h: Int) = if (sizemap ne null) { - sizemap(h >> sizeMapBucketBitSize) -= 1 + sizemap.nn(h >> sizeMapBucketBitSize) -= 1 } protected final def nnSizeMapReset(tableLength: Int) = if (sizemap ne null) { val nsize = calcSizeMapSize(tableLength) - if (sizemap.length != nsize) sizemap = new Array[Int](nsize) - else java.util.Arrays.fill(sizemap, 0) + if (sizemap.nn.length != nsize) sizemap = new Array[Int](nsize) + else java.util.Arrays.fill(sizemap.nn, 0) } private[collection] final def totalSizeMapBuckets = if (sizeMapBucketSize < table.length) 1 else table.length / sizeMapBucketSize @@ -334,18 +335,18 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] var e = tbl(tableidx) while (e ne null) { currbucketsize += 1 - e = e.next + e = e.nn.next } tableidx += 1 } - sizemap(bucketidx) = currbucketsize + sizemap.nn(bucketidx) = currbucketsize tableuntil += sizeMapBucketSize bucketidx += 1 } } private[collection] def printSizeMap() = { - println(sizemap.to(collection.immutable.List)) + println(sizemap.nn.to(collection.immutable.List)) } protected final def sizeMapDisable() = sizemap = null @@ -415,5 +416,5 @@ private[collection] object HashTable { */ private[collection] trait HashEntry[A, E <: HashEntry[A, E]] { val key: A - var next: E = _ + var next: E | Null = _ } diff --git a/library/src/scala/collection/mutable/LinkedHashMap.scala b/library/src/scala/collection/mutable/LinkedHashMap.scala index a2b1b0e8f94b..eae94f5ca468 100644 --- a/library/src/scala/collection/mutable/LinkedHashMap.scala +++ b/library/src/scala/collection/mutable/LinkedHashMap.scala @@ -51,37 +51,39 @@ class LinkedHashMap[K, V] private[collection] type Entry = LinkedHashMap.LinkedEntry[K, V] - private[collection] def _firstEntry: Entry = firstEntry + private[collection] def _firstEntry: Entry | Null = firstEntry - protected var firstEntry: Entry = null + @annotation.stableNull + protected var firstEntry: Entry | Null = null - protected var lastEntry: Entry = null + @annotation.stableNull + protected var lastEntry: Entry | Null = null /* Uses the same implementation as mutable.HashMap. The hashtable holds the following invariant: * - For each i between 0 and table.length, the bucket at table(i) only contains keys whose hash-index is i. * - Every bucket is sorted in ascendant hash order * - The sum of the lengths of all buckets is equal to contentSize. */ - private[this] var table = new Array[Entry](tableSizeFor(LinkedHashMap.defaultinitialSize)) + private[this] var table = new Array[Entry | Null](tableSizeFor(LinkedHashMap.defaultinitialSize)) private[this] var threshold: Int = newThreshold(table.length) private[this] var contentSize = 0 override def last: (K, V) = - if (size > 0) (lastEntry.key, lastEntry.value) + if (size > 0) (lastEntry.nn.key, lastEntry.nn.value) else throw new NoSuchElementException("Cannot call .last on empty LinkedHashMap") override def lastOption: Option[(K, V)] = - if (size > 0) Some((lastEntry.key, lastEntry.value)) + if (size > 0) Some((lastEntry.nn.key, lastEntry.nn.value)) else None override def head: (K, V) = - if (size > 0) (firstEntry.key, firstEntry.value) + if (size > 0) (firstEntry.nn.key, firstEntry.nn.value) else throw new NoSuchElementException("Cannot call .head on empty LinkedHashMap") override def headOption: Option[(K, V)] = - if (size > 0) Some((firstEntry.key, firstEntry.value)) + if (size > 0) Some((firstEntry.nn.key, firstEntry.nn.value)) else None override def size = contentSize @@ -152,7 +154,7 @@ class LinkedHashMap[K, V] } } - private[this] def removeEntry0(elem: K): Entry = removeEntry0(elem, computeHash(elem)) + private[this] def removeEntry0(elem: K): Entry | Null = removeEntry0(elem, computeHash(elem)) /** Removes a key from this map if it exists * @@ -160,7 +162,7 @@ class LinkedHashMap[K, V] * @param hash the **improved** hashcode of `element` (see computeHash) * @return the node that contained element if it was present, otherwise null */ - private[this] def removeEntry0(elem: K, hash: Int): Entry = { + private[this] def removeEntry0(elem: K, hash: Int): Entry | Null = { val idx = index(hash) table(idx) match { case null => null @@ -199,7 +201,7 @@ class LinkedHashMap[K, V] @`inline` private[this] def index(hash: Int) = hash & (table.length - 1) - @`inline` private[this] def findEntry(key: K): Entry = { + @`inline` private[this] def findEntry(key: K): Entry | Null = { val hash = computeHash(key) table(index(hash)) match { case null => null @@ -218,11 +220,11 @@ class LinkedHashMap[K, V] } private[this] abstract class LinkedHashMapIterator[T] extends AbstractIterator[T] { - private[this] var cur = firstEntry + private[this] var cur: Entry | Null = firstEntry def extract(nd: Entry): T def hasNext: Boolean = cur ne null def next(): T = - if (hasNext) { val r = extract(cur); cur = cur.later; r } + if (hasNext) { val r = extract(cur.nn); cur = cur.nn.later; r } else Iterator.empty.next() } @@ -261,19 +263,19 @@ class LinkedHashMap[K, V] val hash = computeHash(key) val indexedHash = index(hash) - var foundEntry: Entry = null - var previousEntry: Entry = null + var foundEntry: Entry | Null = null + var previousEntry: Entry | Null = null table(indexedHash) match { case null => case nd => @tailrec - def findEntry(prev: Entry, nd: Entry, k: K, h: Int): Unit = { + def findEntry(prev: Entry | Null, nd: Entry, k: K, h: Int): Unit = { if (h == nd.hash && k == nd.key) { previousEntry = prev foundEntry = nd } else if ((nd.next eq null) || (nd.hash > h)) () - else findEntry(nd, nd.next, k, h) + else findEntry(nd, nd.next.nn, k, h) } findEntry(null, nd, key, hash) @@ -290,9 +292,9 @@ class LinkedHashMap[K, V] case (None, None) => // do nothing case (Some(_), None) => - if (previousEntry != null) previousEntry.next = foundEntry.next - else table(indexedHash) = foundEntry.next - deleteEntry(foundEntry) + if (previousEntry != null) previousEntry.nn.next = foundEntry.nn.next + else table(indexedHash) = foundEntry.nn.next + deleteEntry(foundEntry.nn) contentSize -= 1 case (None, Some(value)) => @@ -303,7 +305,7 @@ class LinkedHashMap[K, V] } else indexedHash put0(key, value, getOld = false, hash, newIndexedHash) - case (Some(_), Some(newValue)) => foundEntry.value = newValue + case (Some(_), Some(newValue)) => foundEntry.nn.value = newValue } nextValue } @@ -319,16 +321,16 @@ class LinkedHashMap[K, V] override def foreach[U](f: ((K, V)) => U): Unit = { var cur = firstEntry while (cur ne null) { - f((cur.key, cur.value)) - cur = cur.later + f((cur.nn.key, cur.nn.value)) + cur = cur.nn.later } } override def foreachEntry[U](f: (K, V) => U): Unit = { var cur = firstEntry while (cur ne null) { - f(cur.key, cur.value) - cur = cur.later + f(cur.nn.key, cur.nn.value) + cur = cur.nn.later } } @@ -352,7 +354,7 @@ class LinkedHashMap[K, V] val e = new Entry(key, hash, value) if (firstEntry eq null) firstEntry = e else { - lastEntry.later = e + lastEntry.nn.later = e e.earlier = lastEntry } lastEntry = e @@ -362,28 +364,28 @@ class LinkedHashMap[K, V] /** Delete the entry from the LinkedHashMap, set the `earlier` and `later` pointers correctly */ private[this] def deleteEntry(e: Entry): Unit = { if (e.earlier eq null) firstEntry = e.later - else e.earlier.later = e.later + else e.earlier.nn.later = e.later if (e.later eq null) lastEntry = e.earlier - else e.later.earlier = e.earlier + else e.later.nn.earlier = e.earlier e.earlier = null e.later = null e.next = null } - private[this] def put0(key: K, value: V, getOld: Boolean): Some[V] = { + private[this] def put0(key: K, value: V, getOld: Boolean): Some[V] | Null = { if (contentSize + 1 >= threshold) growTable(table.length * 2) val hash = computeHash(key) val idx = index(hash) put0(key, value, getOld, hash, idx) } - private[this] def put0(key: K, value: V, getOld: Boolean, hash: Int, idx: Int): Some[V] = { + private[this] def put0(key: K, value: V, getOld: Boolean, hash: Int, idx: Int): Some[V] | Null = { table(idx) match { case null => table(idx) = createNewEntry(key, hash, value) case old => - var prev: Entry = null - var n = old + var prev: Entry | Null = null + var n: Entry | Null = old while ((n ne null) && n.hash <= hash) { if (n.hash == hash && key == n.key) { val old = n.value @@ -398,8 +400,8 @@ class LinkedHashMap[K, V] nnode.next = old table(idx) = nnode } else { - nnode.next = prev.next - prev.next = nnode + nnode.next = prev.nn.next + prev.nn.next = nnode } } contentSize += 1 @@ -427,7 +429,7 @@ class LinkedHashMap[K, V] preHigh.next = null var lastLow = preLow var lastHigh = preHigh - var n = old + var n: Entry | Null = old while (n ne null) { val next = n.next if ((n.hash & oldlen) == 0) { // keep low @@ -492,15 +494,15 @@ object LinkedHashMap extends MapFactory[LinkedHashMap] { /** Class for the linked hash map entry, used internally. */ private[mutable] final class LinkedEntry[K, V](val key: K, val hash: Int, var value: V) { - var earlier: LinkedEntry[K, V] = null - var later: LinkedEntry[K, V] = null - var next: LinkedEntry[K, V] = null + var earlier: LinkedEntry[K, V] | Null = null + var later: LinkedEntry[K, V] | Null = null + var next: LinkedEntry[K, V] | Null = null @tailrec - final def findEntry(k: K, h: Int): LinkedEntry[K, V] = + final def findEntry(k: K, h: Int): LinkedEntry[K, V] | Null = if (h == hash && k == key) this else if ((next eq null) || (hash > h)) null - else next.findEntry(k, h) + else next.nn.findEntry(k, h) } /** The default load factor for the hash table */ diff --git a/library/src/scala/collection/mutable/LinkedHashSet.scala b/library/src/scala/collection/mutable/LinkedHashSet.scala index f0c2d2d843c3..ea4040b0d93e 100644 --- a/library/src/scala/collection/mutable/LinkedHashSet.scala +++ b/library/src/scala/collection/mutable/LinkedHashSet.scala @@ -47,9 +47,11 @@ class LinkedHashSet[A] /*private*/ type Entry = LinkedHashSet.Entry[A] - protected var firstEntry: Entry = null + @annotation.stableNull + protected var firstEntry: Entry | Null = null - protected var lastEntry: Entry = null + @annotation.stableNull + protected var lastEntry: Entry | Null = null /* Uses the same implementation as mutable.HashSet. The hashtable holds the following invariant: * - For each i between 0 and table.length, the bucket at table(i) only contains keys whose hash-index is i. @@ -63,19 +65,19 @@ class LinkedHashSet[A] private[this] var contentSize = 0 override def last: A = - if (size > 0) lastEntry.key + if (size > 0) lastEntry.nn.key else throw new NoSuchElementException("Cannot call .last on empty LinkedHashSet") override def lastOption: Option[A] = - if (size > 0) Some(lastEntry.key) + if (size > 0) Some(lastEntry.nn.key) else None override def head: A = - if (size > 0) firstEntry.key + if (size > 0) firstEntry.nn.key else throw new NoSuchElementException("Cannot call .head on empty LinkedHashSet") override def headOption: Option[A] = - if (size > 0) Some(firstEntry.key) + if (size > 0) Some(firstEntry.nn.key) else None override def size: Int = contentSize @@ -108,11 +110,11 @@ class LinkedHashSet[A] override def remove(elem: A): Boolean = remove0(elem, computeHash(elem)) private[this] abstract class LinkedHashSetIterator[T] extends AbstractIterator[T] { - private[this] var cur = firstEntry + private[this] var cur: Entry | Null = firstEntry def extract(nd: Entry): T def hasNext: Boolean = cur ne null def next(): T = - if (hasNext) { val r = extract(cur); cur = cur.later; r } + if (hasNext) { val r = extract(cur.nn); cur = cur.nn.later; r } else Iterator.empty.next() } @@ -125,10 +127,10 @@ class LinkedHashSet[A] } override def foreach[U](f: A => U): Unit = { - var cur = firstEntry + var cur: Entry | Null = firstEntry while (cur ne null) { - f(cur.key) - cur = cur.later + f(cur.nn.key) + cur = cur.nn.later } } @@ -155,7 +157,7 @@ class LinkedHashSet[A] @`inline` private[this] def index(hash: Int) = hash & (table.length - 1) - @`inline` private[this] def findEntry(key: A): Entry = { + @`inline` private[this] def findEntry(key: A): Entry | Null = { val hash = computeHash(key) table(index(hash)) match { case null => null @@ -171,7 +173,7 @@ class LinkedHashSet[A] val e = new Entry(key, hash) if (firstEntry eq null) firstEntry = e else { - lastEntry.later = e + lastEntry.nn.later = e e.earlier = lastEntry } lastEntry = e @@ -194,8 +196,8 @@ class LinkedHashSet[A] case null => table(idx) = createNewEntry(elem, hash) case old => - var prev: Entry = null - var n = old + var prev: Entry | Null = null + var n: Entry | Null = old while ((n ne null) && n.hash <= hash) { if (n.hash == hash && elem == n.key) return false prev = n @@ -220,17 +222,17 @@ class LinkedHashSet[A] case null => false case nd if nd.hash == hash && nd.key == elem => // first element matches - table(idx) = nd.next + table(idx) = nd.next.nn deleteEntry(nd) contentSize -= 1 true case nd => // find an element that matches var prev = nd - var next = nd.next + var next: Entry | Null = nd.next while ((next ne null) && next.hash <= hash) { if (next.hash == hash && next.key == elem) { - prev.next = next.next + prev.next = next.next.nn deleteEntry(next) contentSize -= 1 return true @@ -257,13 +259,13 @@ class LinkedHashSet[A] while (oldlen < newlen) { var i = 0 while (i < oldlen) { - val old = table(i) + val old: Entry | Null = table(i) if (old ne null) { preLow.next = null preHigh.next = null var lastLow = preLow var lastHigh = preHigh - var n = old + var n: Entry | Null = old while (n ne null) { val next = n.next if ((n.hash & oldlen) == 0) { // keep low @@ -276,9 +278,9 @@ class LinkedHashSet[A] n = next } lastLow.next = null - if (old ne preLow.next) table(i) = preLow.next + if (old ne preLow.next) table(i) = preLow.next.nn if (preHigh.next ne null) { - table(i + oldlen) = preHigh.next + table(i + oldlen) = preHigh.next.nn lastHigh.next = null } } @@ -306,7 +308,7 @@ class LinkedHashSet[A] } @nowarn("""cat=deprecation&origin=scala\.collection\.Iterable\.stringPrefix""") - override protected[this] def stringPrefix = "LinkedHashSet" + override protected[this] def stringPrefix: String = "LinkedHashSet" } /** $factoryInfo @@ -330,15 +332,15 @@ object LinkedHashSet extends IterableFactory[LinkedHashSet] { /** Class for the linked hash set entry, used internally. */ private[mutable] final class Entry[A](val key: A, val hash: Int) { - var earlier: Entry[A] = null - var later: Entry[A] = null - var next: Entry[A] = null + @annotation.stableNull var earlier: Entry[A] | Null = null + @annotation.stableNull var later: Entry[A] | Null = null + @annotation.stableNull var next: Entry[A] | Null = null @tailrec - final def findEntry(k: A, h: Int): Entry[A] = + final def findEntry(k: A, h: Int): Entry[A] | Null = if (h == hash && k == key) this else if ((next eq null) || (hash > h)) null - else next.findEntry(k, h) + else next.nn.findEntry(k, h) } /** The default load factor for the hash table */ diff --git a/library/src/scala/collection/mutable/ListBuffer.scala b/library/src/scala/collection/mutable/ListBuffer.scala index f90423b40f67..70bddfeb418a 100644 --- a/library/src/scala/collection/mutable/ListBuffer.scala +++ b/library/src/scala/collection/mutable/ListBuffer.scala @@ -49,11 +49,12 @@ class ListBuffer[A] @transient private[this] var mutationCount: Int = 0 private var first: List[A] = Nil - private var last0: ::[A] = null // last element (`last0` just because the name `last` is already taken) + @annotation.stableNull + private var last0: ::[A] | Null = null // last element (`last0` just because the name `last` is already taken) private[this] var aliased = false private[this] var len = 0 - private type Predecessor[A0] = ::[A0] /*| Null*/ + private type Predecessor[A0] = ::[A0] | Null def iterator: Iterator[A] = new MutationTracker.CheckedIterator(first.iterator, mutationCount) @@ -101,7 +102,7 @@ class ListBuffer[A] if (isEmpty) xs else { ensureUnaliased() - last0.next = xs + last0.nn.next = xs toList } } @@ -117,14 +118,14 @@ class ListBuffer[A] final def addOne(elem: A): this.type = { ensureUnaliased() val last1 = new ::[A](elem, Nil) - if (len == 0) first = last1 else last0.next = last1 + if (len == 0) first = last1 else last0.nn.next = last1 last0 = last1 len += 1 this } // MUST only be called on fresh instances - private def freshFrom(xs: IterableOnce[A]^): this.type = { + private def freshFrom(xs: IterableOnce[A]): this.type = { val it = xs.iterator if (it.hasNext) { var len = 1 @@ -143,13 +144,13 @@ class ListBuffer[A] this } - override final def addAll(xs: IterableOnce[A]^): this.type = { + override final def addAll(xs: IterableOnce[A]): this.type = { val it = xs.iterator if (it.hasNext) { val fresh = new ListBuffer[A].freshFrom(it) ensureUnaliased() if (len == 0) first = fresh.first - else last0.next = fresh.first + else last0.nn.next = fresh.first last0 = fresh.last0 len += fresh.length } @@ -202,22 +203,22 @@ class ListBuffer[A] } private def getNext(p: Predecessor[A]): List[A] = - if (p == null) first else p.next + if (p == null) first else p.nn.next def update(idx: Int, elem: A): Unit = { ensureUnaliased() if (idx < 0 || idx >= len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) if (idx == 0) { val newElem = new :: (elem, first.tail) - if (last0 eq first) { + if (last0.nn eq first) { last0 = newElem } first = newElem } else { // `p` can not be `null` because the case where `idx == 0` is handled above - val p = locate(idx) + val p = locate(idx).nn val newElem = new :: (elem, p.tail.tail) - if (last0 eq p.tail) { + if (last0.nn eq p.tail) { last0 = newElem } p.asInstanceOf[::[A]].next = newElem @@ -231,7 +232,7 @@ class ListBuffer[A] else { val p = locate(idx) val nx = elem :: getNext(p) - if(p eq null) first = nx else p.next = nx + if(p eq null) first = nx else p.nn.next = nx len += 1 } } @@ -245,14 +246,14 @@ class ListBuffer[A] private def insertAfter(prev: Predecessor[A], fresh: ListBuffer[A]): Unit = { if (!fresh.isEmpty) { val follow = getNext(prev) - if (prev eq null) first = fresh.first else prev.next = fresh.first - fresh.last0.next = follow + if (prev eq null) first = fresh.first else prev.nn.next = fresh.first + fresh.last0.nn.next = follow if (follow.isEmpty) last0 = fresh.last0 len += fresh.length } } - def insertAll(idx: Int, elems: IterableOnce[A]^): Unit = { + def insertAll(idx: Int, elems: IterableOnce[A]): Unit = { if (idx < 0 || idx > len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) val it = elems.iterator if (it.hasNext) { @@ -274,8 +275,8 @@ class ListBuffer[A] first = nx.tail if(first.isEmpty) last0 = null } else { - if(last0 eq nx) last0 = p - p.next = nx.tail + if(last0.nn eq nx) last0 = p + p.nn.next = nx.tail } len -= 1 nx.head @@ -294,7 +295,7 @@ class ListBuffer[A] @tailrec def ahead(p: List[A], n: Int): List[A] = if (n == 0) p else ahead(p.tail, n - 1) val nx = ahead(getNext(prev), n) - if(prev eq null) first = nx else prev.next = nx + if(prev eq null) first = nx else prev.nn.next = nx if(nx.isEmpty) last0 = prev len -= n } @@ -319,23 +320,23 @@ class ListBuffer[A] * @param f the mapping function * @return this $coll */ - def flatMapInPlace(f: A => IterableOnce[A]^): this.type = { + def flatMapInPlace(f: A => IterableOnce[A]): this.type = { mutationCount += 1 var src = first - var dst: List[A] = null + var dst: List[A] | Null = null last0 = null len = 0 while(!src.isEmpty) { val it = f(src.head).iterator while(it.hasNext) { val v = new ::(it.next(), Nil) - if(dst eq null) dst = v else last0.next = v + if(dst eq null) dst = v else last0.nn.next = v last0 = v len += 1 } src = src.tail } - first = if(dst eq null) Nil else dst + first = if(dst eq null) Nil else dst.nn aliased = false // we just rebuilt a fresh, unaliased instance this } @@ -347,13 +348,13 @@ class ListBuffer[A] */ def filterInPlace(p: A => Boolean): this.type = { ensureUnaliased() - var prev: Predecessor[A] = null + var prev: Predecessor[A] | Null = null var cur: List[A] = first while (!cur.isEmpty) { val follow = cur.tail if (!p(cur.head)) { if(prev eq null) first = follow - else prev.next = follow + else prev.nn.next = follow len -= 1 } else { prev = cur.asInstanceOf[Predecessor[A]] diff --git a/library/src/scala/collection/mutable/LongMap.scala b/library/src/scala/collection/mutable/LongMap.scala index fe9dab81dc24..36980718874c 100644 --- a/library/src/scala/collection/mutable/LongMap.scala +++ b/library/src/scala/collection/mutable/LongMap.scala @@ -72,12 +72,12 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff private[this] var mask = 0 private[this] var extraKeys: Int = 0 - private[this] var zeroValue: AnyRef = null - private[this] var minValue: AnyRef = null + @annotation.stableNull private[this] var zeroValue: AnyRef | Null = null + @annotation.stableNull private[this] var minValue: AnyRef | Null = null private[this] var _size = 0 private[this] var _vacant = 0 - private[this] var _keys: Array[Long] = null - private[this] var _values: Array[AnyRef] = null + @annotation.stableNull private[this] var _keys: Array[Long] | Null = null + @annotation.stableNull private[this] var _values: Array[AnyRef | Null] | Null = null if (initBlank) defaultInitialize(initialBufferSize) @@ -86,11 +86,11 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if (n<0) 0x7 else (((1 << (32 - java.lang.Integer.numberOfLeadingZeros(n-1))) - 1) & 0x3FFFFFFF) | 0x7 _keys = new Array[Long](mask+1) - _values = new Array[AnyRef](mask+1) + _values = new Array[AnyRef | Null](mask+1) } private[collection] def initializeTo( - m: Int, ek: Int, zv: AnyRef, mv: AnyRef, sz: Int, vc: Int, kz: Array[Long], vz: Array[AnyRef] + m: Int, ek: Int, zv: AnyRef | Null, mv: AnyRef | Null, sz: Int, vc: Int, kz: Array[Long] | Null, vz: Array[AnyRef | Null] | Null ): Unit = { mask = m; extraKeys = ek; zeroValue = zv; minValue = mv; _size = sz; _vacant = vc; _keys = kz; _values = vz } @@ -113,7 +113,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff private def seekEmpty(k: Long): Int = { var e = toIndex(k) var x = 0 - while (_keys(e) != 0) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } + while (_keys.nn(e) != 0) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } e } @@ -121,7 +121,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff var e = toIndex(k) var x = 0 var q = 0L - while ({ q = _keys(e); if (q==k) return e; q != 0}) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } + while ({ q = _keys.nn(e); if (q==k) return e; q != 0}) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } e | MissingBit } @@ -129,13 +129,13 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff var e = toIndex(k) var x = 0 var q = 0L - while ({ q = _keys(e); if (q==k) return e; q+q != 0}) { + while ({ q = _keys.nn(e); if (q==k) return e; q+q != 0}) { x += 1 e = (e + 2*(x+1)*x - 3) & mask } if (q == 0) return e | MissingBit val o = e | MissVacant - while ({ q = _keys(e); if (q==k) return e; q != 0}) { + while ({ q = _keys.nn(e); if (q==k) return e; q != 0}) { x += 1 e = (e + 2*(x+1)*x - 3) & mask } @@ -155,7 +155,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } else { val i = seekEntry(key) - if (i < 0) None else Some(_values(i).asInstanceOf[V]) + if (i < 0) None else Some(_values.nn(i).asInstanceOf[V]) } } @@ -167,7 +167,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } else { val i = seekEntry(key) - if (i < 0) default else _values(i).asInstanceOf[V1] + if (i < 0) default else _values.nn(i).asInstanceOf[V1] } } @@ -188,7 +188,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff var i = seekEntryOrOpen(key) if (i < 0) { val value = { - val oks = _keys + val oks = _keys.nn val j = i & IndexMask val ok = oks(j) val ans = defaultValue @@ -197,7 +197,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff // - element added at `j`: since `i < 0`, the key was missing and `ok` is either 0 or MinValue. // If `defaultValue` added an element at `j` then `_keys(j)` must be different now. // (`_keys` never contains 0 or MinValue.) - if (oks.ne(_keys) || ok != _keys(j)) { + if (oks.ne(_keys.nn) || ok != _keys.nn(j)) { i = seekEntryOrOpen(key) if (i >= 0) _size -= 1 } @@ -205,13 +205,13 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } _size += 1 val j = i & IndexMask - _keys(j) = key - _values(j) = value.asInstanceOf[AnyRef] + _keys.nn(j) = key + _values.nn(j) = value.asInstanceOf[AnyRef] if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() value } - else _values(i).asInstanceOf[V] + else _values.nn(i).asInstanceOf[V] } } @@ -222,15 +222,15 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff * may not exist, if the default null/zero is acceptable. For key/value * pairs that do exist, `apply` (i.e. `map(key)`) is equally fast. */ - def getOrNull(key: Long): V = { + def getOrNull(key: Long): V | Null = { if (key == -key) { - if ((((key>>>63).toInt+1) & extraKeys) == 0) null.asInstanceOf[V] + if ((((key>>>63).toInt+1) & extraKeys) == 0) null else if (key == 0) zeroValue.asInstanceOf[V] else minValue.asInstanceOf[V] } else { val i = seekEntry(key) - if (i < 0) null.asInstanceOf[V] else _values(i).asInstanceOf[V] + if (i < 0) null else _values.nn(i).asInstanceOf[V] } } @@ -246,7 +246,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } else { val i = seekEntry(key) - if (i < 0) defaultEntry(key) else _values(i).asInstanceOf[V] + if (i < 0) defaultEntry(key) else _values.nn(i).asInstanceOf[V] } } @@ -256,19 +256,19 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff override def default(key: Long) = defaultEntry(key) private def repack(newMask: Int): Unit = { - val ok = _keys - val ov = _values + val ok = _keys.nn + val ov = _values.nn mask = newMask _keys = new Array[Long](mask+1) - _values = new Array[AnyRef](mask+1) + _values = new Array[AnyRef | Null](mask+1) _vacant = 0 var i = 0 while (i < ok.length) { val k = ok(i) if (k != -k) { val j = seekEmpty(k) - _keys(j) = k - _values(j) = ov(i) + _keys.nn(j) = k + _values.nn(j) = ov(i) } i += 1 } @@ -303,17 +303,17 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff val i = seekEntryOrOpen(key) if (i < 0) { val j = i & IndexMask - _keys(j) = key - _values(j) = value.asInstanceOf[AnyRef] + _keys.nn(j) = key + _values.nn(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() None } else { - val ans = Some(_values(i).asInstanceOf[V]) - _keys(i) = key - _values(i) = value.asInstanceOf[AnyRef] + val ans = Some(_values.nn(i).asInstanceOf[V]) + _keys.nn(i) = key + _values.nn(i) = value.asInstanceOf[AnyRef] ans } } @@ -338,15 +338,15 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff val i = seekEntryOrOpen(key) if (i < 0) { val j = i & IndexMask - _keys(j) = key - _values(j) = value.asInstanceOf[AnyRef] + _keys.nn(j) = key + _values.nn(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() } else { - _keys(i) = key - _values(i) = value.asInstanceOf[AnyRef] + _keys.nn(i) = key + _values.nn(i) = value.asInstanceOf[AnyRef] } } } @@ -376,33 +376,33 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if (i >= 0) { _size -= 1 _vacant += 1 - _keys(i) = Long.MinValue - _values(i) = null + _keys.nn(i) = Long.MinValue + _values.nn(i) = null } } this } def iterator: Iterator[(Long, V)] = new AbstractIterator[(Long, V)] { - private[this] val kz = _keys - private[this] val vz = _values + private[this] val kz = _keys.nn + private[this] val vz = _values.nn - private[this] var nextPair: (Long, V) = + private[this] var nextPair: (Long, V) | Null = if (extraKeys==0) null else if ((extraKeys&1)==1) (0L, zeroValue.asInstanceOf[V]) else (Long.MinValue, minValue.asInstanceOf[V]) - private[this] var anotherPair: (Long, V) = + private[this] var anotherPair: (Long, V) | Null = if (extraKeys==3) (Long.MinValue, minValue.asInstanceOf[V]) else null private[this] var index = 0 - def hasNext: Boolean = nextPair != null || (index < kz.length && { + def hasNext: Boolean = nextPair != null || (index < kz.nn.length && { var q = kz(index) while (q == -q) { index += 1 - if (index >= kz.length) return false + if (index >= kz.nn.length) return false q = kz(index) } nextPair = (kz(index), vz(index).asInstanceOf[V]) @@ -417,7 +417,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff anotherPair = null } else nextPair = null - ans + ans.nn } } @@ -429,11 +429,11 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if ((extraKeys & 1) == 1) f((0L, zeroValue.asInstanceOf[V])) if ((extraKeys & 2) == 2) f((Long.MinValue, minValue.asInstanceOf[V])) var i,j = 0 - while (i < _keys.length & j < _size) { - val k = _keys(i) + while (i < _keys.nn.length & j < _size) { + val k = _keys.nn(i) if (k != -k) { j += 1 - f((k, _values(i).asInstanceOf[V])) + f((k, _values.nn(i).asInstanceOf[V])) } i += 1 } @@ -443,19 +443,19 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if ((extraKeys & 1) == 1) f(0L, zeroValue.asInstanceOf[V]) if ((extraKeys & 2) == 2) f(Long.MinValue, minValue.asInstanceOf[V]) var i,j = 0 - while (i < _keys.length & j < _size) { - val k = _keys(i) + while (i < _keys.nn.length & j < _size) { + val k = _keys.nn(i) if (k != -k) { j += 1 - f(k, _values(i).asInstanceOf[V]) + f(k, _values.nn(i).asInstanceOf[V]) } i += 1 } } override def clone(): LongMap[V] = { - val kz = java.util.Arrays.copyOf(_keys, _keys.length) - val vz = java.util.Arrays.copyOf(_values, _values.length) + val kz = java.util.Arrays.copyOf(_keys.nn, _keys.nn.length) + val vz = java.util.Arrays.copyOf(_values.nn, _values.nn.length) val lm = new LongMap[V](defaultEntry, 1, initBlank = false) lm.initializeTo(mask, extraKeys, zeroValue, minValue, _size, _vacant, kz, vz) lm @@ -469,19 +469,18 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } @deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0") - override def + [V1 >: V](elem1: (Long, V1), elem2: (Long, V1), elems: (Long, V1)*): LongMap[V1]^{} = { - // TODO: An empty capture annotation is needed in the result type to satisfy the overriding checker. + override def + [V1 >: V](elem1: (Long, V1), elem2: (Long, V1), elems: (Long, V1)*): LongMap[V1] = { val m = this + elem1 + elem2 if(elems.isEmpty) m else m.concat(elems) } - override def concat[V1 >: V](xs: scala.collection.IterableOnce[(Long, V1)]^): LongMap[V1] = { + override def concat[V1 >: V](xs: scala.collection.IterableOnce[(Long, V1)]): LongMap[V1] = { val lm = clone().asInstanceOf[LongMap[V1]] xs.iterator.foreach(kv => lm += kv) lm } - override def ++ [V1 >: V](xs: scala.collection.IterableOnce[(Long, V1)]^): LongMap[V1] = concat(xs) + override def ++ [V1 >: V](xs: scala.collection.IterableOnce[(Long, V1)]): LongMap[V1] = concat(xs) @deprecated("Use m.clone().addOne(k,v) instead of m.updated(k, v)", "2.13.0") override def updated[V1 >: V](key: Long, value: V1): LongMap[V1] = @@ -492,8 +491,8 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if ((extraKeys & 1) == 1) f(0L) if ((extraKeys & 2) == 2) f(Long.MinValue) var i,j = 0 - while (i < _keys.length & j < _size) { - val k = _keys(i) + while (i < _keys.nn.length & j < _size) { + val k = _keys.nn(i) if (k != -k) { j += 1 f(k) @@ -507,11 +506,11 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if ((extraKeys & 1) == 1) f(zeroValue.asInstanceOf[V]) if ((extraKeys & 2) == 2) f(minValue.asInstanceOf[V]) var i,j = 0 - while (i < _keys.length & j < _size) { - val k = _keys(i) + while (i < _keys.nn.length & j < _size) { + val k = _keys.nn(i) if (k != -k) { j += 1 - f(_values(i).asInstanceOf[V]) + f(_values.nn(i).asInstanceOf[V]) } i += 1 } @@ -522,17 +521,17 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff * collection immediately. */ def mapValuesNow[V1](f: V => V1): LongMap[V1] = { - val zv = if ((extraKeys & 1) == 1) f(zeroValue.asInstanceOf[V]).asInstanceOf[AnyRef] else null - val mv = if ((extraKeys & 2) == 2) f(minValue.asInstanceOf[V]).asInstanceOf[AnyRef] else null + val zv = if ((extraKeys & 1) == 1) f(zeroValue.asInstanceOf[V]).asInstanceOf[AnyRef | Null] else null + val mv = if ((extraKeys & 2) == 2) f(minValue.asInstanceOf[V]).asInstanceOf[AnyRef | Null] else null val lm = new LongMap[V1](LongMap.exceptionDefault, 1, initBlank = false) - val kz = java.util.Arrays.copyOf(_keys, _keys.length) - val vz = new Array[AnyRef](_values.length) + val kz = java.util.Arrays.copyOf(_keys, _keys.nn.length) + val vz = new Array[AnyRef | Null](_values.nn.length) var i,j = 0 - while (i < _keys.length & j < _size) { - val k = _keys(i) + while (i < _keys.nn.length & j < _size) { + val k = _keys.nn(i) if (k != -k) { j += 1 - vz(i) = f(_values(i).asInstanceOf[V]).asInstanceOf[AnyRef] + vz(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef | Null] } i += 1 } @@ -550,14 +549,14 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff * Note: the default, if any, is not transformed. */ def transformValuesInPlace(f: V => V): this.type = { - if ((extraKeys & 1) == 1) zeroValue = f(zeroValue.asInstanceOf[V]).asInstanceOf[AnyRef] - if ((extraKeys & 2) == 2) minValue = f(minValue.asInstanceOf[V]).asInstanceOf[AnyRef] + if ((extraKeys & 1) == 1) zeroValue = f(zeroValue.asInstanceOf[V]).asInstanceOf[AnyRef | Null] + if ((extraKeys & 2) == 2) minValue = f(minValue.asInstanceOf[V]).asInstanceOf[AnyRef | Null] var i,j = 0 - while (i < _keys.length & j < _size) { - val k = _keys(i) + while (i < _keys.nn.length & j < _size) { + val k = _keys.nn(i) if (k != -k) { j += 1 - _values(i) = f(_values(i).asInstanceOf[V]).asInstanceOf[AnyRef] + _values.nn(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef | Null] } i += 1 } diff --git a/library/src/scala/collection/mutable/PriorityQueue.scala b/library/src/scala/collection/mutable/PriorityQueue.scala index 050fa5159ee6..2c1e1671b215 100644 --- a/library/src/scala/collection/mutable/PriorityQueue.scala +++ b/library/src/scala/collection/mutable/PriorityQueue.scala @@ -89,7 +89,7 @@ sealed class PriorityQueue[A](implicit val ord: Ordering[A]) def p_size0 = size0 def p_size0_=(s: Int) = size0 = s - def p_array = array + def p_array: Array[AnyRef | Null] = array.asInstanceOf[Array[AnyRef | Null]] def p_ensureSize(n: Int) = super.ensureSize(n) def p_ensureAdditionalSize(n: Int) = super.ensureSize(size0 + n) def p_swap(a: Int, b: Int): Unit = { @@ -130,8 +130,8 @@ sealed class PriorityQueue[A](implicit val ord: Ordering[A]) def result() = this - private def toA(x: AnyRef): A = x.asInstanceOf[A] - protected def fixUp(as: Array[AnyRef], m: Int): Unit = { + private def toA(x: AnyRef | Null): A = x.asInstanceOf[A] + protected def fixUp(as: Array[AnyRef | Null], m: Int): Unit = { var k: Int = m // use `ord` directly to avoid allocating `OrderingOps` while (k > 1 && ord.lt(toA(as(k / 2)), toA(as(k)))) { @@ -140,7 +140,7 @@ sealed class PriorityQueue[A](implicit val ord: Ordering[A]) } } - protected def fixDown(as: Array[AnyRef], m: Int, n: Int): Boolean = { + protected def fixDown(as: Array[AnyRef | Null], m: Int, n: Int): Boolean = { // returns true if any swaps were done (used in heapify) var k: Int = m while (n >= 2 * k) { diff --git a/library/src/scala/collection/mutable/Queue.scala b/library/src/scala/collection/mutable/Queue.scala index 91c2fdd81334..a4b087e068c8 100644 --- a/library/src/scala/collection/mutable/Queue.scala +++ b/library/src/scala/collection/mutable/Queue.scala @@ -29,7 +29,7 @@ import scala.collection.generic.DefaultSerializable * @define mayNotTerminateInf * @define willNotTerminateInf */ -class Queue[A] protected (array: Array[AnyRef], start: Int, end: Int) +class Queue[A] protected (array: Array[AnyRef | Null], start: Int, end: Int) extends ArrayDeque[A](array, start, end) with IndexedSeqOps[A, Queue, Queue[A]] with StrictOptimizedSeqOps[A, Queue, Queue[A]] @@ -118,7 +118,7 @@ class Queue[A] protected (array: Array[AnyRef], start: Int, end: Int) bf.result() } - override protected def ofArray(array: Array[AnyRef], end: Int): Queue[A] = + override protected def ofArray(array: Array[AnyRef | Null], end: Int): Queue[A] = new Queue(array, start = 0, end) } diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index 7a64730d7449..82993eef740f 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -14,6 +14,7 @@ package scala package collection.mutable import scala.language.`2.13` +import scala.language.unsafeNulls import language.experimental.captureChecking import scala.annotation.tailrec import collection.{AbstractIterator, Iterator} diff --git a/library/src/scala/collection/mutable/Stack.scala b/library/src/scala/collection/mutable/Stack.scala index 8ca4b58a7af6..26cda88ecd4f 100644 --- a/library/src/scala/collection/mutable/Stack.scala +++ b/library/src/scala/collection/mutable/Stack.scala @@ -35,7 +35,7 @@ import scala.collection.{IterableFactoryDefaults, IterableOnce, SeqFactory, Stri * @define willNotTerminateInf */ @migration("Stack is now based on an ArrayDeque instead of a linked list", "2.13.0") -class Stack[A] protected (array: Array[AnyRef], start: Int, end: Int) +class Stack[A] protected (array: Array[AnyRef | Null], start: Int, end: Int) extends ArrayDeque[A](array, start, end) with IndexedSeqOps[A, Stack, Stack[A]] with StrictOptimizedSeqOps[A, Stack, Stack[A]] @@ -122,7 +122,7 @@ class Stack[A] protected (array: Array[AnyRef], start: Int, end: Int) bf.result() } - override protected def ofArray(array: Array[AnyRef], end: Int): Stack[A] = + override protected def ofArray(array: Array[AnyRef | Null], end: Int): Stack[A] = new Stack(array, start = 0, end) } diff --git a/library/src/scala/collection/mutable/UnrolledBuffer.scala b/library/src/scala/collection/mutable/UnrolledBuffer.scala index aee908369f0f..f27f87249d36 100644 --- a/library/src/scala/collection/mutable/UnrolledBuffer.scala +++ b/library/src/scala/collection/mutable/UnrolledBuffer.scala @@ -130,20 +130,20 @@ sealed class UnrolledBuffer[T](implicit val tag: ClassTag[T]) def iterator: Iterator[T] = new AbstractIterator[T] { var pos: Int = -1 - var node: Unrolled[T] = headptr + var node: Unrolled[T] | Null = headptr scan() private def scan(): Unit = { pos += 1 - while (pos >= node.size) { + while (pos >= node.nn.size) { pos = 0 - node = node.next + node = node.nn.next if (node eq null) return } } def hasNext = node ne null def next() = if (hasNext) { - val r = node.array(pos) + val r = node.nn.array(pos) scan() r } else Iterator.empty.next() @@ -264,12 +264,12 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] /** Unrolled buffer node. */ - class Unrolled[T: ClassTag] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) { + class Unrolled[T: ClassTag] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T] | Null, val buff: UnrolledBuffer[T] | Null) { this: Unrolled[T]^{} => private[collection] def this() = this(0, new Array[T](unrolledlength), null, null) - private[collection] def this(b: UnrolledBuffer[T]) = this(0, new Array[T](unrolledlength), null, b) + private[collection] def this(b: UnrolledBuffer[T] | Null) = this(0, new Array[T](unrolledlength), null, b) - private def nextlength = if (buff eq null) unrolledlength else buff.calcNextLength(array.length) + private def nextlength = if (buff eq null) unrolledlength else buff.nn.calcNextLength(array.length) // adds and returns itself or the new unrolled if full @tailrec final def append(elem: T): Unrolled[T] = if (size < array.length) { @@ -278,29 +278,29 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] this } else { next = new Unrolled[T](0, new Array[T](nextlength), null, buff) - next append elem + next.nn append elem } def foreach[U](f: T => U): Unit = { - var unrolled = this + var unrolled: Unrolled[T] | Null = this var i = 0 while (unrolled ne null) { - val chunkarr = unrolled.array - val chunksz = unrolled.size + val chunkarr = unrolled.nn.array + val chunksz = unrolled.nn.size while (i < chunksz) { val elem = chunkarr(i) f(elem) i += 1 } i = 0 - unrolled = unrolled.next + unrolled = unrolled.nn.next } } def mapInPlace(f: T => T): Unit = { - var unrolled = this + var unrolled: Unrolled[T] | Null = this var i = 0 while (unrolled ne null) { - val chunkarr = unrolled.array - val chunksz = unrolled.size + val chunkarr = unrolled.nn.array + val chunksz = unrolled.nn.size while (i < chunksz) { val elem = chunkarr(i) chunkarr(i) = f(elem) @@ -311,11 +311,11 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } } @tailrec final def apply(idx: Int): T = - if (idx < size) array(idx) else next.apply(idx - size) + if (idx < size) array(idx) else next.nn.apply(idx - size) @tailrec final def update(idx: Int, newelem: T): Unit = - if (idx < size) array(idx) = newelem else next.update(idx - size, newelem) + if (idx < size) array(idx) = newelem else next.nn.update(idx - size, newelem) @tailrec final def locate(idx: Int): Unrolled[T] = - if (idx < size) this else next.locate(idx - size) + if (idx < size) this else next.nn.locate(idx - size) def prepend(elem: T) = if (size < array.length) { // shift the elements of the array right // then insert the element @@ -326,7 +326,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } else { // allocate a new node and store element // then make it point to this - val newhead = new Unrolled[T](buff) + val newhead = new Unrolled[T](buff.nn) newhead append elem newhead.next = this newhead @@ -349,7 +349,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] size -= 1 if (tryMergeWithNext()) buffer.lastPtr = this r - } else next.remove(idx - size, buffer) + } else next.nn.remove(idx - size, buffer) @tailrec final def subtractOne(elem: T, buffer: UnrolledBuffer[T]): Boolean = { var i = 0 @@ -360,7 +360,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } i += 1 } - if(next ne null) next.subtractOne(elem, buffer) else false + if(next ne null) next.nn.subtractOne(elem, buffer) else false } // shifts left elements after `leftb` (overwrites `leftb`) @@ -372,15 +372,15 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } nullout(i, i + 1) } - protected def tryMergeWithNext() = if (next != null && (size + next.size) < (array.length * waterline / waterlineDenom)) { + protected def tryMergeWithNext() = if (next != null && (size + next.nn.size) < (array.length * waterline / waterlineDenom)) { // copy the next array, then discard the next node - Array.copy(next.array, 0, array, size, next.size) - size = size + next.size - next = next.next + Array.copy(next.nn.array, 0, array, size, next.nn.size) + size = size + next.nn.size + next = next.nn.next if (next eq null) true else false // checks if last node was thrown out } else false - @tailrec final def insertAll(idx: Int, t: scala.collection.IterableOnce[T]^, buffer: UnrolledBuffer[T]): Int = { + @tailrec final def insertAll(idx: Int, t: scala.collection.IterableOnce[T], buffer: UnrolledBuffer[T]): Int = { if (idx < size) { // divide this node at the appropriate position and insert all into head // update new next @@ -417,7 +417,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } appended } - else next.insertAll(idx - size, t, buffer) + else next.nn.insertAll(idx - size, t, buffer) } private def nullout(from: Int, until: Int): Unit = { @@ -438,7 +438,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } override def toString: String = - array.take(size).mkString("Unrolled@%08x".format(System.identityHashCode(this)) + "[" + size + "/" + array.length + "](", ", ", ")") + " -> " + (if (next ne null) next.toString else "") + array.take(size).nn.mkString("Unrolled@%08x".format(System.identityHashCode(this)) + "[" + size + "/" + array.length + "](", ", ", ")") + " -> " + (if (next ne null) next.toString else "") } } diff --git a/library/src/scala/concurrent/BatchingExecutor.scala b/library/src/scala/concurrent/BatchingExecutor.scala index b108af7c3eca..198bd381744a 100644 --- a/library/src/scala/concurrent/BatchingExecutor.scala +++ b/library/src/scala/concurrent/BatchingExecutor.scala @@ -26,7 +26,7 @@ trait Batchable { } private[concurrent] object BatchingExecutorStatics { - final val emptyBatchArray: Array[Runnable] = new Array[Runnable](0) + final val emptyBatchArray: Array[Runnable | Null] = new Array[Runnable | Null](0) // Max number of Runnables executed nested before starting to batch (to prevent stack exhaustion) final val syncPreBatchDepth = 16 @@ -98,9 +98,13 @@ private[concurrent] trait BatchingExecutor extends Executor { * In order to conserve allocations, the first element in the batch is stored "unboxed" in * the `first` field. Subsequent Runnables are stored in the array called `other`. */ - private[this] sealed abstract class AbstractBatch protected (protected final var first: Runnable, protected final var other: Array[Runnable], protected final var size: Int) { + private[this] sealed abstract class AbstractBatch protected ( + @annotation.stableNull protected final var first: Runnable | Null, + @annotation.stableNull protected final var other: Array[Runnable | Null], + protected final var size: Int + ) { - private[this] final def ensureCapacity(curSize: Int): Array[Runnable] = { + private[this] final def ensureCapacity(curSize: Int): Array[Runnable | Null] = { val curOther = this.other val curLen = curOther.length if (curSize <= curLen) curOther @@ -108,7 +112,7 @@ private[concurrent] trait BatchingExecutor extends Executor { val newLen = if (curLen == 0) 4 else curLen << 1 if (newLen <= curLen) throw new StackOverflowError("Space limit of asynchronous stack reached: " + curLen) - val newOther = new Array[Runnable](newLen) + val newOther = new Array[Runnable | Null](newLen) System.arraycopy(curOther, 0, newOther, 0, curLen) this.other = newOther newOther @@ -129,14 +133,14 @@ private[concurrent] trait BatchingExecutor extends Executor { (this.size: @switch) match { case 0 => case 1 => - val next = this.first + val next = this.first.nn this.first = null this.size = 0 next.run() runN(n - 1) case sz => val o = this.other - val next = o(sz - 2) + val next = o(sz - 2).nn o(sz - 2) = null this.size = sz - 1 next.run() @@ -144,8 +148,8 @@ private[concurrent] trait BatchingExecutor extends Executor { } } - private[this] final class AsyncBatch private(_first: Runnable, _other: Array[Runnable], _size: Int) extends AbstractBatch(_first, _other, _size) with Runnable with BlockContext with (BlockContext => Throwable) { - private[this] final var parentBlockContext: BlockContext = BatchingExecutorStatics.MissingParentBlockContext + private[this] final class AsyncBatch private(_first: Runnable | Null, _other: Array[Runnable | Null], _size: Int) extends AbstractBatch(_first, _other, _size) with Runnable with BlockContext with (BlockContext => Throwable | Null) { + @annotation.stableNull private[this] final var parentBlockContext: BlockContext = BatchingExecutorStatics.MissingParentBlockContext final def this(runnable: Runnable) = this(runnable, BatchingExecutorStatics.emptyBatchArray, 1) @@ -155,11 +159,11 @@ private[concurrent] trait BatchingExecutor extends Executor { val f = resubmit(BlockContext.usingBlockContext(this)(this)) if (f != null) - throw f + throw f.nn } /* LOGIC FOR ASYNCHRONOUS BATCHES */ - override final def apply(prevBlockContext: BlockContext): Throwable = try { + override final def apply(prevBlockContext: BlockContext): Throwable | Null = try { parentBlockContext = prevBlockContext runN(BatchingExecutorStatics.runLimit) null @@ -175,7 +179,7 @@ private[concurrent] trait BatchingExecutor extends Executor { * Only attempt to resubmit when there are `Runnables` left to process. * Note that `cause` can be `null`. */ - private[this] final def resubmit(cause: Throwable): Throwable = + private[this] final def resubmit(cause: Throwable | Null): Throwable | Null = if (this.size > 0) { try { submitForExecution(this); cause } catch { case inner: Throwable => diff --git a/library/src/scala/concurrent/ExecutionContext.scala b/library/src/scala/concurrent/ExecutionContext.scala index 703b962a0f17..625a0c3cbeba 100644 --- a/library/src/scala/concurrent/ExecutionContext.scala +++ b/library/src/scala/concurrent/ExecutionContext.scala @@ -39,7 +39,7 @@ import scala.annotation.implicitNotFound * `scala.concurrent.ExecutionContext.Implicits.global`. * The recommended approach is to add `(implicit ec: ExecutionContext)` to methods, * or class constructor parameters, which need an `ExecutionContext`. - * + * * Then locally import a specific `ExecutionContext` in one place for the entire * application or module, passing it implicitly to individual methods. * Alternatively define a local implicit val with the required `ExecutionContext`. @@ -197,7 +197,7 @@ object ExecutionContext { * * @return the global [[ExecutionContext]] */ - final lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor) + final lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor | Null) /** * WARNING: Only ever execute logic which will quickly return control to the caller. @@ -212,7 +212,7 @@ object ExecutionContext { * * Do *not* call any blocking code in the `Runnable`s submitted to this `ExecutionContext` * as it will prevent progress by other enqueued `Runnable`s and the calling `Thread`. - * + * * Symptoms of misuse of this `ExecutionContext` include, but are not limited to, deadlocks * and severe performance problems. * @@ -253,7 +253,7 @@ object ExecutionContext { * @param reporter a function for error reporting * @return the `ExecutionContext` using the given `ExecutorService` */ - def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService = + def fromExecutorService(e: ExecutorService | Null, reporter: Throwable => Unit): ExecutionContextExecutorService = impl.ExecutionContextImpl.fromExecutorService(e, reporter) /** Creates an `ExecutionContext` from the given `ExecutorService` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. @@ -269,7 +269,7 @@ object ExecutionContext { * @param e the `ExecutorService` to use. If `null`, a new `ExecutorService` is created with [[scala.concurrent.ExecutionContext$.global default configuration]]. * @return the `ExecutionContext` using the given `ExecutorService` */ - def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter) + def fromExecutorService(e: ExecutorService | Null): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter) /** Creates an `ExecutionContext` from the given `Executor`. * @@ -277,7 +277,7 @@ object ExecutionContext { * @param reporter a function for error reporting * @return the `ExecutionContext` using the given `Executor` */ - def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor = + def fromExecutor(e: Executor | Null, reporter: Throwable => Unit): ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(e, reporter) /** Creates an `ExecutionContext` from the given `Executor` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]]. @@ -285,7 +285,7 @@ object ExecutionContext { * @param e the `Executor` to use. If `null`, a new `Executor` is created with [[scala.concurrent.ExecutionContext$.global default configuration]]. * @return the `ExecutionContext` using the given `Executor` */ - def fromExecutor(e: Executor): ExecutionContextExecutor = fromExecutor(e, defaultReporter) + def fromExecutor(e: Executor | Null): ExecutionContextExecutor = fromExecutor(e, defaultReporter) /** The default reporter simply prints the stack trace of the `Throwable` to [[java.lang.System#err System.err]]. * diff --git a/library/src/scala/concurrent/JavaConversions.scala b/library/src/scala/concurrent/JavaConversions.scala index eab15c2610b9..046c14ff063e 100644 --- a/library/src/scala/concurrent/JavaConversions.scala +++ b/library/src/scala/concurrent/JavaConversions.scala @@ -26,14 +26,14 @@ object JavaConversions { * Creates a new `ExecutionContext` which uses the provided `ExecutorService`. */ @deprecated("Use `ExecutionContext.fromExecutorService` instead", "2.13.0") - implicit def asExecutionContext(exec: ExecutorService): ExecutionContextExecutorService = + implicit def asExecutionContext(exec: ExecutorService | Null): ExecutionContextExecutorService = ExecutionContext.fromExecutorService(exec) /** * Creates a new `ExecutionContext` which uses the provided `Executor`. */ @deprecated("Use `ExecutionContext.fromExecutor` instead", "2.13.0") - implicit def asExecutionContext(exec: Executor): ExecutionContextExecutor = + implicit def asExecutionContext(exec: Executor | Null): ExecutionContextExecutor = ExecutionContext.fromExecutor(exec) } diff --git a/library/src/scala/concurrent/impl/ExecutionContextImpl.scala b/library/src/scala/concurrent/impl/ExecutionContextImpl.scala index 3096297f620a..55fc5354940b 100644 --- a/library/src/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/library/src/scala/concurrent/impl/ExecutionContextImpl.scala @@ -109,13 +109,13 @@ private[concurrent] object ExecutionContextImpl { } } - def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextExecutor = + def fromExecutor(e: Executor | Null, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextExecutor = e match { case null => createDefaultExecutorService(reporter) case some => new ExecutionContextImpl(some, reporter) } - def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter): + def fromExecutorService(es: ExecutorService | Null, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextExecutorService = es match { case null => createDefaultExecutorService(reporter) case some => diff --git a/library/src/scala/concurrent/impl/Promise.scala b/library/src/scala/concurrent/impl/Promise.scala index 983a82e7bb7c..b89575fbe69e 100644 --- a/library/src/scala/concurrent/impl/Promise.scala +++ b/library/src/scala/concurrent/impl/Promise.scala @@ -34,8 +34,8 @@ import java.io.{IOException, NotSerializableException, ObjectInputStream, Object */ private[impl] final class CompletionLatch[T] extends AbstractQueuedSynchronizer with (Try[T] => Unit) { //@volatie not needed since we use acquire/release - /*@volatile*/ private[this] var _result: Try[T] = null - final def result: Try[T] = _result + /*@volatile*/ @annotation.stableNull private[this] var _result: Try[T] | Null = null + final def result: Try[T] | Null = _result override protected def tryAcquireShared(ignored: Int): Int = if (getState != 0) 1 else -1 override protected def tryReleaseShared(ignore: Int): Boolean = { setState(1) @@ -238,7 +238,7 @@ private[concurrent] object Promise { else /*if (state.isInstanceOf[Callbacks[T]]) */ "Future()" } - private[this] final def tryAwait0(atMost: Duration): Try[T] = + private[this] final def tryAwait0(atMost: Duration): Try[T] | Null = if (atMost ne Duration.Undefined) { val v = value0 if (v ne null) v @@ -270,14 +270,14 @@ private[concurrent] object Promise { @throws(classOf[Exception]) final def result(atMost: Duration)(implicit permit: CanAwait): T = - tryAwait0(atMost).get // returns the value, or throws the contained exception + tryAwait0(atMost).nn.get // returns the value, or throws the contained exception override final def isCompleted: Boolean = value0 ne null - override final def value: Option[Try[T]] = Option(value0) + override final def value: Some[Try[T]] = Some(value0.asInstanceOf[Try[T]]) @tailrec // returns null if not completed - private final def value0: Try[T] = { + private final def value0: Try[T] | Null = { val state = get() if (state.isInstanceOf[Try[_]]) state.asInstanceOf[Try[T]] else if (state.isInstanceOf[Link[_]]) state.asInstanceOf[Link[T]].promise(this).value0 @@ -348,7 +348,7 @@ private[concurrent] object Promise { concatCallbacks(m.rest, new ManyCallbacks(m.first, right)) } - @tailrec private[this] final def removeCallback(cs: Callbacks[T], t: Transformation[_, _], result: Callbacks[T] = null): AnyRef = + @tailrec private[this] final def removeCallback(cs: Callbacks[T], t: Transformation[_, _], result: Callbacks[T] | Null = null): AnyRef = if (cs eq t) { if (result == null) Noop else result @@ -357,9 +357,9 @@ private[concurrent] object Promise { val m = cs.asInstanceOf[ManyCallbacks[T]] if (m.first eq t) { if (result == null) m.rest - else concatCallbacks(m.rest, result) + else concatCallbacks(m.rest, result.nn) } - else removeCallback(m.rest, t, if (result == null) m.first else new ManyCallbacks(m.first, result)) + else removeCallback(m.rest, t, if (result == null) m.first else new ManyCallbacks(m.first, result.nn)) } else cs // IMPORTANT: Noop should not be passed in here, `callbacks` cannot be null @@ -375,7 +375,7 @@ private[concurrent] object Promise { /** Link this promise to the root of another promise. */ - @tailrec private[concurrent] final def linkRootOf(target: DefaultPromise[T], link: Link[T]): Unit = + @tailrec private[concurrent] final def linkRootOf(target: DefaultPromise[T], link: Link[T] | Null): Unit = if (this ne target) { val state = get() if (state.isInstanceOf[Try[_]]) { @@ -383,8 +383,8 @@ private[concurrent] object Promise { throw new IllegalStateException("Cannot link completed promises together") } else if (state.isInstanceOf[Callbacks[_]]) { val l = if (link ne null) link else new Link(target) - val p = l.promise(this) - if ((this ne p) && compareAndSet(state, l)) { + val p = l.nn.promise(this) + if ((this ne p) && compareAndSet(state, l.nn)) { if (state ne Noop) p.dispatchOrAddCallbacks(p.get(), state.asInstanceOf[Callbacks[T]]) // Noop-check is important here } else linkRootOf(p, l) } else /* if (state.isInstanceOf[Link[T]]) */ @@ -435,7 +435,7 @@ private[concurrent] object Promise { override final def toString: String = "ManyCallbacks" } - private[this] final val Noop = new Transformation[Nothing, Nothing](Xform_noop, null, ExecutionContext.parasitic) + private[this] final val Noop = new Transformation[Nothing, Nothing](Xform_noop, null: (Any => Any) | Null, ExecutionContext.parasitic) /** * A Transformation[F, T] receives an F (it is a Callback[F]) and applies a transformation function to that F, @@ -444,13 +444,13 @@ private[concurrent] object Promise { * function's type parameters are erased, and the _xform tag will be used to reify them. **/ final class Transformation[-F, T] private[this] ( - private[this] final var _fun: Any => Any, - private[this] final var _ec: ExecutionContext, - private[this] final var _arg: Try[F], + @annotation.stableNull private[this] final var _fun: (Any => Any) | Null, + @annotation.stableNull private[this] final var _ec: ExecutionContext | Null, + @annotation.stableNull private[this] final var _arg: Try[F] | Null, private[this] final val _xform: Int ) extends DefaultPromise[T]() with Callbacks[F] with Runnable with Batchable { - final def this(xform: Int, f: _ => _, ec: ExecutionContext) = - this(f.asInstanceOf[Any => Any], ec.prepare(): @nowarn("cat=deprecation"), null, xform) + final def this(xform: Int, f: (_ => _) | Null, ec: ExecutionContext) = + this(f.asInstanceOf[(Any => Any) | Null], ec.prepare(): @nowarn("cat=deprecation"), null, xform) final def benefitsFromBatching: Boolean = _xform != Xform_onComplete && _xform != Xform_foreach @@ -461,13 +461,13 @@ private[concurrent] object Promise { final def submitWithValue(resolved: Try[F]): this.type = { _arg = resolved val e = _ec - try e.execute(this) /* Safe publication of _arg, _fun, _ec */ + try e.nn.execute(this) /* Safe publication of _arg, _fun, _ec */ catch { case t: Throwable => _fun = null // allow to GC _arg = null // see above _ec = null // see above again - handleFailure(t, e) + handleFailure(t, e.nn) } this @@ -487,14 +487,14 @@ private[concurrent] object Promise { // Gets invoked by the ExecutionContext, when we have a value to transform. override final def run(): Unit = { - val v = _arg - val fun = _fun - val ec = _ec + val v = _arg.nn + val fun = _fun.nn + val ec = _ec.nn _fun = null // allow to GC _arg = null // see above _ec = null // see above try { - val resolvedResult: Try[_] = + val resolvedResult: Try[_] | Null = (_xform: @switch) match { case Xform_noop => null diff --git a/library/src/scala/io/BufferedSource.scala b/library/src/scala/io/BufferedSource.scala index b569cce8d797..f2aa614107ec 100644 --- a/library/src/scala/io/BufferedSource.scala +++ b/library/src/scala/io/BufferedSource.scala @@ -67,7 +67,7 @@ class BufferedSource(inputStream: InputStream, bufferSize: Int)(implicit val cod class BufferedLineIterator extends AbstractIterator[String] with Iterator[String] { private[this] val lineReader = decachedReader - var nextLine: String = null + var nextLine: String | Null = null override def hasNext = { if (nextLine == null) @@ -78,10 +78,10 @@ class BufferedSource(inputStream: InputStream, bufferSize: Int)(implicit val cod override def next(): String = { val result = { if (nextLine == null) lineReader.readLine - else try nextLine finally nextLine = null + else try nextLine.nn finally nextLine = null } if (result == null) Iterator.empty.next() - else result + else result.nn } } diff --git a/library/src/scala/io/Codec.scala b/library/src/scala/io/Codec.scala index 44b5becd7d78..0f0e6a2de086 100644 --- a/library/src/scala/io/Codec.scala +++ b/library/src/scala/io/Codec.scala @@ -39,10 +39,10 @@ class Codec(val charSet: Charset) { // these variables allow configuring the Codec object, and then // all decoders and encoders retrieved from it will use these settings. - private[this] var _onMalformedInput: Action = null - private[this] var _onUnmappableCharacter: Action = null - private[this] var _encodingReplacement: Array[Byte] = null - private[this] var _decodingReplacement: String = null + private[this] var _onMalformedInput: Action | Null = null + private[this] var _onUnmappableCharacter: Action | Null = null + private[this] var _encodingReplacement: Array[Byte] | Null = null + private[this] var _decodingReplacement: String | Null = null private[this] var _onCodingException: Handler = e => throw e /** The name of the Codec. */ @@ -58,16 +58,16 @@ class Codec(val charSet: Charset) { def name = charSet.name def encoder: CharsetEncoder = { val enc = charSet.newEncoder() - if (_onMalformedInput ne null) enc onMalformedInput _onMalformedInput - if (_onUnmappableCharacter ne null) enc onUnmappableCharacter _onUnmappableCharacter - if (_encodingReplacement ne null) enc replaceWith _encodingReplacement + if (_onMalformedInput ne null) enc onMalformedInput _onMalformedInput.nn + if (_onUnmappableCharacter ne null) enc onUnmappableCharacter _onUnmappableCharacter.nn + if (_encodingReplacement ne null) enc replaceWith _encodingReplacement.nn enc } def decoder: CharsetDecoder = { val dec = charSet.newDecoder() - if (_onMalformedInput ne null) dec onMalformedInput _onMalformedInput - if (_onUnmappableCharacter ne null) dec onUnmappableCharacter _onUnmappableCharacter - if (_decodingReplacement ne null) dec replaceWith _decodingReplacement + if (_onMalformedInput ne null) dec onMalformedInput _onMalformedInput.nn + if (_onUnmappableCharacter ne null) dec onUnmappableCharacter _onUnmappableCharacter.nn + if (_decodingReplacement ne null) dec replaceWith _decodingReplacement.nn dec } diff --git a/library/src/scala/io/Source.scala b/library/src/scala/io/Source.scala index c66c12d3c8e1..4dd485982c97 100644 --- a/library/src/scala/io/Source.scala +++ b/library/src/scala/io/Source.scala @@ -158,11 +158,11 @@ object Source { def createBufferedSource( inputStream: InputStream, bufferSize: Int = DefaultBufSize, - reset: () => Source = null, - close: () => Unit = null + reset: (() => Source) | Null = null, + close: (() => Unit) | Null = null )(implicit codec: Codec): BufferedSource = { // workaround for default arguments being unable to refer to other parameters - val resetFn = if (reset == null) () => createBufferedSource(inputStream, bufferSize, reset, close)(codec) else reset + val resetFn = if (reset == null) () => createBufferedSource(inputStream, bufferSize, reset, close)(codec) else reset.nn new BufferedSource(inputStream, bufferSize)(codec) withReset resetFn withClose close } @@ -344,15 +344,15 @@ abstract class Source extends Iterator[Char] with Closeable { report(pos, "warning! " + msg, out) } - private[this] var resetFunction: () => Source = null - private[this] var closeFunction: () => Unit = null + private[this] var resetFunction: (() => Source) | Null = null + private[this] var closeFunction: (() => Unit) | Null = null private[this] var positioner: Positioner = RelaxedPositioner - def withReset(f: () => Source): this.type = { + def withReset(f: (() => Source) | Null): this.type = { resetFunction = f this } - def withClose(f: () => Unit): this.type = { + def withClose(f: (() => Unit) | Null): this.type = { closeFunction = f this } @@ -372,11 +372,11 @@ abstract class Source extends Iterator[Char] with Closeable { /** The close() method closes the underlying resource. */ def close(): Unit = { - if (closeFunction != null) closeFunction() + if (closeFunction != null) closeFunction.nn() } /** The reset() method creates a fresh copy of this Source. */ def reset(): Source = - if (resetFunction != null) resetFunction() + if (resetFunction != null) resetFunction.nn() else throw new UnsupportedOperationException("Source's reset() method was not set.") } diff --git a/library/src/scala/jdk/AnyAccumulator.scala b/library/src/scala/jdk/AnyAccumulator.scala index 94814594008c..f2aa79b82853 100644 --- a/library/src/scala/jdk/AnyAccumulator.scala +++ b/library/src/scala/jdk/AnyAccumulator.scala @@ -326,7 +326,7 @@ private[jdk] class AnyAccumulatorStepper[A](private[this] val acc: AnyAccumulato ans } - def trySplit(): AnyStepper[A] = + def trySplit(): AnyStepper[A] | Null = if (N <= 1) null else { val half = N >> 1 diff --git a/library/src/scala/jdk/DoubleAccumulator.scala b/library/src/scala/jdk/DoubleAccumulator.scala index 403f877364c4..8a1aa8c88c88 100644 --- a/library/src/scala/jdk/DoubleAccumulator.scala +++ b/library/src/scala/jdk/DoubleAccumulator.scala @@ -406,7 +406,7 @@ private[jdk] class DoubleAccumulatorStepper(private val acc: DoubleAccumulator) ans } - def trySplit(): DoubleStepper = + def trySplit(): DoubleStepper | Null = if (N <= 1) null else { val half = N >> 1 diff --git a/library/src/scala/jdk/FunctionExtensions.scala b/library/src/scala/jdk/FunctionExtensions.scala index 9f97426bbe12..88c4623ac8f8 100644 --- a/library/src/scala/jdk/FunctionExtensions.scala +++ b/library/src/scala/jdk/FunctionExtensions.scala @@ -20,7 +20,7 @@ import language.implicitConversions trait Priority3FunctionExtensions { import FunctionWrappers._ - + @inline implicit def enrichAsJavaBiFunction[T, U, R](sf: scala.Function2[T, U, R]): RichFunction2AsBiFunction[T, U, R] = new RichFunction2AsBiFunction[T, U, R](sf) } @@ -30,17 +30,17 @@ import language.implicitConversions trait Priority2FunctionExtensions extends Priority3FunctionExtensions { import FunctionWrappers._ - + @inline implicit def enrichAsJavaBiConsumer[T, U](sf: scala.Function2[T, U, Unit]): RichFunction2AsBiConsumer[T, U] = new RichFunction2AsBiConsumer[T, U](sf) - + @inline implicit def enrichAsJavaBiPredicate[T, U](sf: scala.Function2[T, U, Boolean]): RichFunction2AsBiPredicate[T, U] = new RichFunction2AsBiPredicate[T, U](sf) - + @inline implicit def enrichAsJavaFunction[T, R](sf: scala.Function1[T, R]): RichFunction1AsFunction[T, R] = new RichFunction1AsFunction[T, R](sf) - + @inline implicit def enrichAsJavaToDoubleBiFunction[T, U](sf: scala.Function2[T, U, Double]): RichFunction2AsToDoubleBiFunction[T, U] = new RichFunction2AsToDoubleBiFunction[T, U](sf) - + @inline implicit def enrichAsJavaToIntBiFunction[T, U](sf: scala.Function2[T, U, Int]): RichFunction2AsToIntBiFunction[T, U] = new RichFunction2AsToIntBiFunction[T, U](sf) - + @inline implicit def enrichAsJavaToLongBiFunction[T, U](sf: scala.Function2[T, U, Long]): RichFunction2AsToLongBiFunction[T, U] = new RichFunction2AsToLongBiFunction[T, U](sf) } @@ -50,33 +50,33 @@ import language.implicitConversions trait Priority1FunctionExtensions extends Priority2FunctionExtensions { import FunctionWrappers._ - + @inline implicit def enrichAsJavaBinaryOperator[T, A1, A2](sf: scala.Function2[T, A1, A2])(implicit evA1: =:=[A1, T], evA2: =:=[A2, T]): RichFunction2AsBinaryOperator[T] = new RichFunction2AsBinaryOperator[T](sf.asInstanceOf[scala.Function2[T, T, T]]) - + @inline implicit def enrichAsJavaConsumer[T](sf: scala.Function1[T, Unit]): RichFunction1AsConsumer[T] = new RichFunction1AsConsumer[T](sf) - + @inline implicit def enrichAsJavaDoubleFunction[A0, R](sf: scala.Function1[A0, R])(implicit evA0: =:=[A0, Double]): RichFunction1AsDoubleFunction[R] = new RichFunction1AsDoubleFunction[R](sf.asInstanceOf[scala.Function1[Double, R]]) - + @inline implicit def enrichAsJavaIntFunction[A0, R](sf: scala.Function1[A0, R])(implicit evA0: =:=[A0, Int]): RichFunction1AsIntFunction[R] = new RichFunction1AsIntFunction[R](sf.asInstanceOf[scala.Function1[Int, R]]) - + @inline implicit def enrichAsJavaLongFunction[A0, R](sf: scala.Function1[A0, R])(implicit evA0: =:=[A0, Long]): RichFunction1AsLongFunction[R] = new RichFunction1AsLongFunction[R](sf.asInstanceOf[scala.Function1[Long, R]]) - + @inline implicit def enrichAsJavaObjDoubleConsumer[T, A1](sf: scala.Function2[T, A1, Unit])(implicit evA1: =:=[A1, Double]): RichFunction2AsObjDoubleConsumer[T] = new RichFunction2AsObjDoubleConsumer[T](sf.asInstanceOf[scala.Function2[T, Double, Unit]]) - + @inline implicit def enrichAsJavaObjIntConsumer[T, A1](sf: scala.Function2[T, A1, Unit])(implicit evA1: =:=[A1, Int]): RichFunction2AsObjIntConsumer[T] = new RichFunction2AsObjIntConsumer[T](sf.asInstanceOf[scala.Function2[T, Int, Unit]]) - + @inline implicit def enrichAsJavaObjLongConsumer[T, A1](sf: scala.Function2[T, A1, Unit])(implicit evA1: =:=[A1, Long]): RichFunction2AsObjLongConsumer[T] = new RichFunction2AsObjLongConsumer[T](sf.asInstanceOf[scala.Function2[T, Long, Unit]]) - + @inline implicit def enrichAsJavaPredicate[T](sf: scala.Function1[T, Boolean]): RichFunction1AsPredicate[T] = new RichFunction1AsPredicate[T](sf) - + @inline implicit def enrichAsJavaSupplier[T](sf: scala.Function0[T]): RichFunction0AsSupplier[T] = new RichFunction0AsSupplier[T](sf) - + @inline implicit def enrichAsJavaToDoubleFunction[T](sf: scala.Function1[T, Double]): RichFunction1AsToDoubleFunction[T] = new RichFunction1AsToDoubleFunction[T](sf) - + @inline implicit def enrichAsJavaToIntFunction[T](sf: scala.Function1[T, Int]): RichFunction1AsToIntFunction[T] = new RichFunction1AsToIntFunction[T](sf) - + @inline implicit def enrichAsJavaToLongFunction[T](sf: scala.Function1[T, Long]): RichFunction1AsToLongFunction[T] = new RichFunction1AsToLongFunction[T](sf) - + @inline implicit def enrichAsJavaUnaryOperator[T, A1](sf: scala.Function1[T, A1])(implicit evA1: =:=[A1, T]): RichFunction1AsUnaryOperator[T] = new RichFunction1AsUnaryOperator[T](sf.asInstanceOf[scala.Function1[T, T]]) } @@ -86,136 +86,136 @@ import language.implicitConversions trait Priority0FunctionExtensions extends Priority1FunctionExtensions { import FunctionWrappers._ - + @inline implicit def enrichAsJavaBooleanSupplier(sf: scala.Function0[Boolean]): RichFunction0AsBooleanSupplier = new RichFunction0AsBooleanSupplier(sf) - + @inline implicit def enrichAsJavaDoubleBinaryOperator[A0, A1](sf: scala.Function2[A0, A1, Double])(implicit evA0: =:=[A0, Double], evA1: =:=[A1, Double]): RichFunction2AsDoubleBinaryOperator = new RichFunction2AsDoubleBinaryOperator(sf.asInstanceOf[scala.Function2[Double, Double, Double]]) - + @inline implicit def enrichAsJavaDoubleConsumer[A0](sf: scala.Function1[A0, Unit])(implicit evA0: =:=[A0, Double]): RichFunction1AsDoubleConsumer = new RichFunction1AsDoubleConsumer(sf.asInstanceOf[scala.Function1[Double, Unit]]) - + @inline implicit def enrichAsJavaDoublePredicate[A0](sf: scala.Function1[A0, Boolean])(implicit evA0: =:=[A0, Double]): RichFunction1AsDoublePredicate = new RichFunction1AsDoublePredicate(sf.asInstanceOf[scala.Function1[Double, Boolean]]) - + @inline implicit def enrichAsJavaDoubleSupplier(sf: scala.Function0[Double]): RichFunction0AsDoubleSupplier = new RichFunction0AsDoubleSupplier(sf) - + @inline implicit def enrichAsJavaDoubleToIntFunction[A0](sf: scala.Function1[A0, Int])(implicit evA0: =:=[A0, Double]): RichFunction1AsDoubleToIntFunction = new RichFunction1AsDoubleToIntFunction(sf.asInstanceOf[scala.Function1[Double, Int]]) - + @inline implicit def enrichAsJavaDoubleToLongFunction[A0](sf: scala.Function1[A0, Long])(implicit evA0: =:=[A0, Double]): RichFunction1AsDoubleToLongFunction = new RichFunction1AsDoubleToLongFunction(sf.asInstanceOf[scala.Function1[Double, Long]]) - + @inline implicit def enrichAsJavaDoubleUnaryOperator[A0](sf: scala.Function1[A0, Double])(implicit evA0: =:=[A0, Double]): RichFunction1AsDoubleUnaryOperator = new RichFunction1AsDoubleUnaryOperator(sf.asInstanceOf[scala.Function1[Double, Double]]) - + @inline implicit def enrichAsJavaIntBinaryOperator[A0, A1](sf: scala.Function2[A0, A1, Int])(implicit evA0: =:=[A0, Int], evA1: =:=[A1, Int]): RichFunction2AsIntBinaryOperator = new RichFunction2AsIntBinaryOperator(sf.asInstanceOf[scala.Function2[Int, Int, Int]]) - + @inline implicit def enrichAsJavaIntConsumer[A0](sf: scala.Function1[A0, Unit])(implicit evA0: =:=[A0, Int]): RichFunction1AsIntConsumer = new RichFunction1AsIntConsumer(sf.asInstanceOf[scala.Function1[Int, Unit]]) - + @inline implicit def enrichAsJavaIntPredicate[A0](sf: scala.Function1[A0, Boolean])(implicit evA0: =:=[A0, Int]): RichFunction1AsIntPredicate = new RichFunction1AsIntPredicate(sf.asInstanceOf[scala.Function1[Int, Boolean]]) - + @inline implicit def enrichAsJavaIntSupplier(sf: scala.Function0[Int]): RichFunction0AsIntSupplier = new RichFunction0AsIntSupplier(sf) - + @inline implicit def enrichAsJavaIntToDoubleFunction[A0](sf: scala.Function1[A0, Double])(implicit evA0: =:=[A0, Int]): RichFunction1AsIntToDoubleFunction = new RichFunction1AsIntToDoubleFunction(sf.asInstanceOf[scala.Function1[Int, Double]]) - + @inline implicit def enrichAsJavaIntToLongFunction[A0](sf: scala.Function1[A0, Long])(implicit evA0: =:=[A0, Int]): RichFunction1AsIntToLongFunction = new RichFunction1AsIntToLongFunction(sf.asInstanceOf[scala.Function1[Int, Long]]) - + @inline implicit def enrichAsJavaIntUnaryOperator[A0](sf: scala.Function1[A0, Int])(implicit evA0: =:=[A0, Int]): RichFunction1AsIntUnaryOperator = new RichFunction1AsIntUnaryOperator(sf.asInstanceOf[scala.Function1[Int, Int]]) - + @inline implicit def enrichAsJavaLongBinaryOperator[A0, A1](sf: scala.Function2[A0, A1, Long])(implicit evA0: =:=[A0, Long], evA1: =:=[A1, Long]): RichFunction2AsLongBinaryOperator = new RichFunction2AsLongBinaryOperator(sf.asInstanceOf[scala.Function2[Long, Long, Long]]) - + @inline implicit def enrichAsJavaLongConsumer[A0](sf: scala.Function1[A0, Unit])(implicit evA0: =:=[A0, Long]): RichFunction1AsLongConsumer = new RichFunction1AsLongConsumer(sf.asInstanceOf[scala.Function1[Long, Unit]]) - + @inline implicit def enrichAsJavaLongPredicate[A0](sf: scala.Function1[A0, Boolean])(implicit evA0: =:=[A0, Long]): RichFunction1AsLongPredicate = new RichFunction1AsLongPredicate(sf.asInstanceOf[scala.Function1[Long, Boolean]]) - + @inline implicit def enrichAsJavaLongSupplier(sf: scala.Function0[Long]): RichFunction0AsLongSupplier = new RichFunction0AsLongSupplier(sf) - + @inline implicit def enrichAsJavaLongToDoubleFunction[A0](sf: scala.Function1[A0, Double])(implicit evA0: =:=[A0, Long]): RichFunction1AsLongToDoubleFunction = new RichFunction1AsLongToDoubleFunction(sf.asInstanceOf[scala.Function1[Long, Double]]) - + @inline implicit def enrichAsJavaLongToIntFunction[A0](sf: scala.Function1[A0, Int])(implicit evA0: =:=[A0, Long]): RichFunction1AsLongToIntFunction = new RichFunction1AsLongToIntFunction(sf.asInstanceOf[scala.Function1[Long, Int]]) - + @inline implicit def enrichAsJavaLongUnaryOperator[A0](sf: scala.Function1[A0, Long])(implicit evA0: =:=[A0, Long]): RichFunction1AsLongUnaryOperator = new RichFunction1AsLongUnaryOperator(sf.asInstanceOf[scala.Function1[Long, Long]]) - - - + + + @inline implicit def enrichAsScalaFromBiConsumer[T, U](jf: java.util.function.BiConsumer[T, U]): RichBiConsumerAsFunction2[T, U] = new RichBiConsumerAsFunction2[T, U](jf) - + @inline implicit def enrichAsScalaFromBiFunction[T, U, R](jf: java.util.function.BiFunction[T, U, R]): RichBiFunctionAsFunction2[T, U, R] = new RichBiFunctionAsFunction2[T, U, R](jf) - + @inline implicit def enrichAsScalaFromBiPredicate[T, U](jf: java.util.function.BiPredicate[T, U]): RichBiPredicateAsFunction2[T, U] = new RichBiPredicateAsFunction2[T, U](jf) - + @inline implicit def enrichAsScalaFromBinaryOperator[T](jf: java.util.function.BinaryOperator[T]): RichBinaryOperatorAsFunction2[T] = new RichBinaryOperatorAsFunction2[T](jf) - + @inline implicit def enrichAsScalaFromBooleanSupplier(jf: java.util.function.BooleanSupplier): RichBooleanSupplierAsFunction0 = new RichBooleanSupplierAsFunction0(jf) - + @inline implicit def enrichAsScalaFromConsumer[T](jf: java.util.function.Consumer[T]): RichConsumerAsFunction1[T] = new RichConsumerAsFunction1[T](jf) - + @inline implicit def enrichAsScalaFromDoubleBinaryOperator(jf: java.util.function.DoubleBinaryOperator): RichDoubleBinaryOperatorAsFunction2 = new RichDoubleBinaryOperatorAsFunction2(jf) - + @inline implicit def enrichAsScalaFromDoubleConsumer(jf: java.util.function.DoubleConsumer): RichDoubleConsumerAsFunction1 = new RichDoubleConsumerAsFunction1(jf) - + @inline implicit def enrichAsScalaFromDoubleFunction[R](jf: java.util.function.DoubleFunction[R]): RichDoubleFunctionAsFunction1[R] = new RichDoubleFunctionAsFunction1[R](jf) - + @inline implicit def enrichAsScalaFromDoublePredicate(jf: java.util.function.DoublePredicate): RichDoublePredicateAsFunction1 = new RichDoublePredicateAsFunction1(jf) - + @inline implicit def enrichAsScalaFromDoubleSupplier(jf: java.util.function.DoubleSupplier): RichDoubleSupplierAsFunction0 = new RichDoubleSupplierAsFunction0(jf) - + @inline implicit def enrichAsScalaFromDoubleToIntFunction(jf: java.util.function.DoubleToIntFunction): RichDoubleToIntFunctionAsFunction1 = new RichDoubleToIntFunctionAsFunction1(jf) - + @inline implicit def enrichAsScalaFromDoubleToLongFunction(jf: java.util.function.DoubleToLongFunction): RichDoubleToLongFunctionAsFunction1 = new RichDoubleToLongFunctionAsFunction1(jf) - + @inline implicit def enrichAsScalaFromDoubleUnaryOperator(jf: java.util.function.DoubleUnaryOperator): RichDoubleUnaryOperatorAsFunction1 = new RichDoubleUnaryOperatorAsFunction1(jf) - + @inline implicit def enrichAsScalaFromFunction[T, R](jf: java.util.function.Function[T, R]): RichFunctionAsFunction1[T, R] = new RichFunctionAsFunction1[T, R](jf) - + @inline implicit def enrichAsScalaFromIntBinaryOperator(jf: java.util.function.IntBinaryOperator): RichIntBinaryOperatorAsFunction2 = new RichIntBinaryOperatorAsFunction2(jf) - + @inline implicit def enrichAsScalaFromIntConsumer(jf: java.util.function.IntConsumer): RichIntConsumerAsFunction1 = new RichIntConsumerAsFunction1(jf) - + @inline implicit def enrichAsScalaFromIntFunction[R](jf: java.util.function.IntFunction[R]): RichIntFunctionAsFunction1[R] = new RichIntFunctionAsFunction1[R](jf) - + @inline implicit def enrichAsScalaFromIntPredicate(jf: java.util.function.IntPredicate): RichIntPredicateAsFunction1 = new RichIntPredicateAsFunction1(jf) - + @inline implicit def enrichAsScalaFromIntSupplier(jf: java.util.function.IntSupplier): RichIntSupplierAsFunction0 = new RichIntSupplierAsFunction0(jf) - + @inline implicit def enrichAsScalaFromIntToDoubleFunction(jf: java.util.function.IntToDoubleFunction): RichIntToDoubleFunctionAsFunction1 = new RichIntToDoubleFunctionAsFunction1(jf) - + @inline implicit def enrichAsScalaFromIntToLongFunction(jf: java.util.function.IntToLongFunction): RichIntToLongFunctionAsFunction1 = new RichIntToLongFunctionAsFunction1(jf) - + @inline implicit def enrichAsScalaFromIntUnaryOperator(jf: java.util.function.IntUnaryOperator): RichIntUnaryOperatorAsFunction1 = new RichIntUnaryOperatorAsFunction1(jf) - + @inline implicit def enrichAsScalaFromLongBinaryOperator(jf: java.util.function.LongBinaryOperator): RichLongBinaryOperatorAsFunction2 = new RichLongBinaryOperatorAsFunction2(jf) - + @inline implicit def enrichAsScalaFromLongConsumer(jf: java.util.function.LongConsumer): RichLongConsumerAsFunction1 = new RichLongConsumerAsFunction1(jf) - + @inline implicit def enrichAsScalaFromLongFunction[R](jf: java.util.function.LongFunction[R]): RichLongFunctionAsFunction1[R] = new RichLongFunctionAsFunction1[R](jf) - + @inline implicit def enrichAsScalaFromLongPredicate(jf: java.util.function.LongPredicate): RichLongPredicateAsFunction1 = new RichLongPredicateAsFunction1(jf) - + @inline implicit def enrichAsScalaFromLongSupplier(jf: java.util.function.LongSupplier): RichLongSupplierAsFunction0 = new RichLongSupplierAsFunction0(jf) - + @inline implicit def enrichAsScalaFromLongToDoubleFunction(jf: java.util.function.LongToDoubleFunction): RichLongToDoubleFunctionAsFunction1 = new RichLongToDoubleFunctionAsFunction1(jf) - + @inline implicit def enrichAsScalaFromLongToIntFunction(jf: java.util.function.LongToIntFunction): RichLongToIntFunctionAsFunction1 = new RichLongToIntFunctionAsFunction1(jf) - + @inline implicit def enrichAsScalaFromLongUnaryOperator(jf: java.util.function.LongUnaryOperator): RichLongUnaryOperatorAsFunction1 = new RichLongUnaryOperatorAsFunction1(jf) - + @inline implicit def enrichAsScalaFromObjDoubleConsumer[T](jf: java.util.function.ObjDoubleConsumer[T]): RichObjDoubleConsumerAsFunction2[T] = new RichObjDoubleConsumerAsFunction2[T](jf) - + @inline implicit def enrichAsScalaFromObjIntConsumer[T](jf: java.util.function.ObjIntConsumer[T]): RichObjIntConsumerAsFunction2[T] = new RichObjIntConsumerAsFunction2[T](jf) - + @inline implicit def enrichAsScalaFromObjLongConsumer[T](jf: java.util.function.ObjLongConsumer[T]): RichObjLongConsumerAsFunction2[T] = new RichObjLongConsumerAsFunction2[T](jf) - + @inline implicit def enrichAsScalaFromPredicate[T](jf: java.util.function.Predicate[T]): RichPredicateAsFunction1[T] = new RichPredicateAsFunction1[T](jf) - + @inline implicit def enrichAsScalaFromSupplier[T](jf: java.util.function.Supplier[T]): RichSupplierAsFunction0[T] = new RichSupplierAsFunction0[T](jf) - + @inline implicit def enrichAsScalaFromToDoubleBiFunction[T, U](jf: java.util.function.ToDoubleBiFunction[T, U]): RichToDoubleBiFunctionAsFunction2[T, U] = new RichToDoubleBiFunctionAsFunction2[T, U](jf) - + @inline implicit def enrichAsScalaFromToDoubleFunction[T](jf: java.util.function.ToDoubleFunction[T]): RichToDoubleFunctionAsFunction1[T] = new RichToDoubleFunctionAsFunction1[T](jf) - + @inline implicit def enrichAsScalaFromToIntBiFunction[T, U](jf: java.util.function.ToIntBiFunction[T, U]): RichToIntBiFunctionAsFunction2[T, U] = new RichToIntBiFunctionAsFunction2[T, U](jf) - + @inline implicit def enrichAsScalaFromToIntFunction[T](jf: java.util.function.ToIntFunction[T]): RichToIntFunctionAsFunction1[T] = new RichToIntFunctionAsFunction1[T](jf) - + @inline implicit def enrichAsScalaFromToLongBiFunction[T, U](jf: java.util.function.ToLongBiFunction[T, U]): RichToLongBiFunctionAsFunction2[T, U] = new RichToLongBiFunctionAsFunction2[T, U](jf) - + @inline implicit def enrichAsScalaFromToLongFunction[T](jf: java.util.function.ToLongFunction[T]): RichToLongFunctionAsFunction1[T] = new RichToLongFunctionAsFunction1[T](jf) - + @inline implicit def enrichAsScalaFromUnaryOperator[T](jf: java.util.function.UnaryOperator[T]): RichUnaryOperatorAsFunction1[T] = new RichUnaryOperatorAsFunction1[T](jf) } diff --git a/library/src/scala/jdk/FunctionWrappers.scala b/library/src/scala/jdk/FunctionWrappers.scala index d6a4d071144d..e146d4b79325 100644 --- a/library/src/scala/jdk/FunctionWrappers.scala +++ b/library/src/scala/jdk/FunctionWrappers.scala @@ -21,18 +21,18 @@ object FunctionWrappers { case class FromJavaBiConsumer[T, U](jf: java.util.function.BiConsumer[T, U]) extends scala.Function2[T, U, Unit] { def apply(x1: T, x2: U) = jf.accept(x1, x2) } - + class RichBiConsumerAsFunction2[T, U](private val underlying: java.util.function.BiConsumer[T, U]) extends AnyVal { @inline def asScala: scala.Function2[T, U, Unit] = underlying match { case AsJavaBiConsumer((sf @ _)) => sf.asInstanceOf[scala.Function2[T, U, Unit]] case _ => new FromJavaBiConsumer[T, U](underlying) } } - + case class AsJavaBiConsumer[T, U](sf: scala.Function2[T, U, Unit]) extends java.util.function.BiConsumer[T, U] { def accept(x1: T, x2: U) = sf.apply(x1, x2) } - + class RichFunction2AsBiConsumer[T, U](private val underlying: scala.Function2[T, U, Unit]) extends AnyVal { @inline def asJava: java.util.function.BiConsumer[T, U] = underlying match { case FromJavaBiConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.BiConsumer[T, U]] @@ -43,23 +43,23 @@ object FunctionWrappers { case _ => new AsJavaBiConsumer[T, U](underlying) } } - - + + case class FromJavaBiFunction[T, U, R](jf: java.util.function.BiFunction[T, U, R]) extends scala.Function2[T, U, R] { def apply(x1: T, x2: U) = jf.apply(x1, x2) } - + class RichBiFunctionAsFunction2[T, U, R](private val underlying: java.util.function.BiFunction[T, U, R]) extends AnyVal { @inline def asScala: scala.Function2[T, U, R] = underlying match { case AsJavaBiFunction((sf @ _)) => sf.asInstanceOf[scala.Function2[T, U, R]] case _ => new FromJavaBiFunction[T, U, R](underlying) } } - + case class AsJavaBiFunction[T, U, R](sf: scala.Function2[T, U, R]) extends java.util.function.BiFunction[T, U, R] { def apply(x1: T, x2: U) = sf.apply(x1, x2) } - + class RichFunction2AsBiFunction[T, U, R](private val underlying: scala.Function2[T, U, R]) extends AnyVal { @inline def asJava: java.util.function.BiFunction[T, U, R] = underlying match { case FromJavaBiFunction((jf @ _)) => jf.asInstanceOf[java.util.function.BiFunction[T, U, R]] @@ -70,23 +70,23 @@ object FunctionWrappers { case _ => new AsJavaBiFunction[T, U, R](underlying) } } - - + + case class FromJavaBiPredicate[T, U](jf: java.util.function.BiPredicate[T, U]) extends scala.Function2[T, U, Boolean] { def apply(x1: T, x2: U) = jf.test(x1, x2) } - + class RichBiPredicateAsFunction2[T, U](private val underlying: java.util.function.BiPredicate[T, U]) extends AnyVal { @inline def asScala: scala.Function2[T, U, Boolean] = underlying match { case AsJavaBiPredicate((sf @ _)) => sf.asInstanceOf[scala.Function2[T, U, Boolean]] case _ => new FromJavaBiPredicate[T, U](underlying) } } - + case class AsJavaBiPredicate[T, U](sf: scala.Function2[T, U, Boolean]) extends java.util.function.BiPredicate[T, U] { def test(x1: T, x2: U) = sf.apply(x1, x2) } - + class RichFunction2AsBiPredicate[T, U](private val underlying: scala.Function2[T, U, Boolean]) extends AnyVal { @inline def asJava: java.util.function.BiPredicate[T, U] = underlying match { case FromJavaBiPredicate((jf @ _)) => jf.asInstanceOf[java.util.function.BiPredicate[T, U]] @@ -97,23 +97,23 @@ object FunctionWrappers { case _ => new AsJavaBiPredicate[T, U](underlying) } } - - + + case class FromJavaBinaryOperator[T](jf: java.util.function.BinaryOperator[T]) extends scala.Function2[T, T, T] { def apply(x1: T, x2: T) = jf.apply(x1, x2) } - + class RichBinaryOperatorAsFunction2[T](private val underlying: java.util.function.BinaryOperator[T]) extends AnyVal { @inline def asScala: scala.Function2[T, T, T] = underlying match { case AsJavaBinaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function2[T, T, T]] case _ => new FromJavaBinaryOperator[T](underlying) } } - + case class AsJavaBinaryOperator[T](sf: scala.Function2[T, T, T]) extends java.util.function.BinaryOperator[T] { def apply(x1: T, x2: T) = sf.apply(x1, x2) } - + class RichFunction2AsBinaryOperator[T](private val underlying: scala.Function2[T, T, T]) extends AnyVal { @inline def asJava: java.util.function.BinaryOperator[T] = underlying match { case FromJavaBinaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.BinaryOperator[T]] @@ -124,46 +124,46 @@ object FunctionWrappers { case _ => new AsJavaBinaryOperator[T](underlying) } } - - + + case class FromJavaBooleanSupplier(jf: java.util.function.BooleanSupplier) extends scala.Function0[Boolean] { def apply() = jf.getAsBoolean() } - + class RichBooleanSupplierAsFunction0(private val underlying: java.util.function.BooleanSupplier) extends AnyVal { @inline def asScala: scala.Function0[Boolean] = underlying match { case AsJavaBooleanSupplier((sf @ _)) => sf.asInstanceOf[scala.Function0[Boolean]] case _ => new FromJavaBooleanSupplier(underlying) } } - + case class AsJavaBooleanSupplier(sf: scala.Function0[Boolean]) extends java.util.function.BooleanSupplier { def getAsBoolean() = sf.apply() } - + class RichFunction0AsBooleanSupplier(private val underlying: scala.Function0[Boolean]) extends AnyVal { @inline def asJava: java.util.function.BooleanSupplier = underlying match { case FromJavaBooleanSupplier((jf @ _)) => jf.asInstanceOf[java.util.function.BooleanSupplier] case _ => new AsJavaBooleanSupplier(underlying) } } - - + + case class FromJavaConsumer[T](jf: java.util.function.Consumer[T]) extends scala.Function1[T, Unit] { def apply(x1: T) = jf.accept(x1) } - + class RichConsumerAsFunction1[T](private val underlying: java.util.function.Consumer[T]) extends AnyVal { @inline def asScala: scala.Function1[T, Unit] = underlying match { case AsJavaConsumer((sf @ _)) => sf.asInstanceOf[scala.Function1[T, Unit]] case _ => new FromJavaConsumer[T](underlying) } } - + case class AsJavaConsumer[T](sf: scala.Function1[T, Unit]) extends java.util.function.Consumer[T] { def accept(x1: T) = sf.apply(x1) } - + class RichFunction1AsConsumer[T](private val underlying: scala.Function1[T, Unit]) extends AnyVal { @inline def asJava: java.util.function.Consumer[T] = underlying match { case FromJavaConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.Consumer[T]] @@ -174,69 +174,69 @@ object FunctionWrappers { case _ => new AsJavaConsumer[T](underlying) } } - - + + case class FromJavaDoubleBinaryOperator(jf: java.util.function.DoubleBinaryOperator) extends scala.Function2[Double, Double, Double] { def apply(x1: scala.Double, x2: scala.Double) = jf.applyAsDouble(x1, x2) } - + class RichDoubleBinaryOperatorAsFunction2(private val underlying: java.util.function.DoubleBinaryOperator) extends AnyVal { @inline def asScala: scala.Function2[Double, Double, Double] = underlying match { case AsJavaDoubleBinaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function2[Double, Double, Double]] case _ => new FromJavaDoubleBinaryOperator(underlying) } } - + case class AsJavaDoubleBinaryOperator(sf: scala.Function2[Double, Double, Double]) extends java.util.function.DoubleBinaryOperator { def applyAsDouble(x1: scala.Double, x2: scala.Double) = sf.apply(x1, x2) } - + class RichFunction2AsDoubleBinaryOperator(private val underlying: scala.Function2[Double, Double, Double]) extends AnyVal { @inline def asJava: java.util.function.DoubleBinaryOperator = underlying match { case FromJavaDoubleBinaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleBinaryOperator] case _ => new AsJavaDoubleBinaryOperator(underlying) } } - - + + case class FromJavaDoubleConsumer(jf: java.util.function.DoubleConsumer) extends scala.Function1[Double, Unit] { def apply(x1: scala.Double) = jf.accept(x1) } - + class RichDoubleConsumerAsFunction1(private val underlying: java.util.function.DoubleConsumer) extends AnyVal { @inline def asScala: scala.Function1[Double, Unit] = underlying match { case AsJavaDoubleConsumer((sf @ _)) => sf.asInstanceOf[scala.Function1[Double, Unit]] case _ => new FromJavaDoubleConsumer(underlying) } } - + case class AsJavaDoubleConsumer(sf: scala.Function1[Double, Unit]) extends java.util.function.DoubleConsumer { def accept(x1: scala.Double) = sf.apply(x1) } - + class RichFunction1AsDoubleConsumer(private val underlying: scala.Function1[Double, Unit]) extends AnyVal { @inline def asJava: java.util.function.DoubleConsumer = underlying match { case FromJavaDoubleConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleConsumer] case _ => new AsJavaDoubleConsumer(underlying) } } - - + + case class FromJavaDoubleFunction[R](jf: java.util.function.DoubleFunction[R]) extends scala.Function1[Double, R] { def apply(x1: scala.Double) = jf.apply(x1) } - + class RichDoubleFunctionAsFunction1[R](private val underlying: java.util.function.DoubleFunction[R]) extends AnyVal { @inline def asScala: scala.Function1[Double, R] = underlying match { case AsJavaDoubleFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Double, R]] case _ => new FromJavaDoubleFunction[R](underlying) } } - + case class AsJavaDoubleFunction[R](sf: scala.Function1[Double, R]) extends java.util.function.DoubleFunction[R] { def apply(x1: scala.Double) = sf.apply(x1) } - + class RichFunction1AsDoubleFunction[R](private val underlying: scala.Function1[Double, R]) extends AnyVal { @inline def asJava: java.util.function.DoubleFunction[R] = underlying match { case FromJavaDoubleFunction((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleFunction[R]] @@ -247,138 +247,138 @@ object FunctionWrappers { case _ => new AsJavaDoubleFunction[R](underlying) } } - - + + case class FromJavaDoublePredicate(jf: java.util.function.DoublePredicate) extends scala.Function1[Double, Boolean] { def apply(x1: scala.Double) = jf.test(x1) } - + class RichDoublePredicateAsFunction1(private val underlying: java.util.function.DoublePredicate) extends AnyVal { @inline def asScala: scala.Function1[Double, Boolean] = underlying match { case AsJavaDoublePredicate((sf @ _)) => sf.asInstanceOf[scala.Function1[Double, Boolean]] case _ => new FromJavaDoublePredicate(underlying) } } - + case class AsJavaDoublePredicate(sf: scala.Function1[Double, Boolean]) extends java.util.function.DoublePredicate { def test(x1: scala.Double) = sf.apply(x1) } - + class RichFunction1AsDoublePredicate(private val underlying: scala.Function1[Double, Boolean]) extends AnyVal { @inline def asJava: java.util.function.DoublePredicate = underlying match { case FromJavaDoublePredicate((jf @ _)) => jf.asInstanceOf[java.util.function.DoublePredicate] case _ => new AsJavaDoublePredicate(underlying) } } - - + + case class FromJavaDoubleSupplier(jf: java.util.function.DoubleSupplier) extends scala.Function0[Double] { def apply() = jf.getAsDouble() } - + class RichDoubleSupplierAsFunction0(private val underlying: java.util.function.DoubleSupplier) extends AnyVal { @inline def asScala: scala.Function0[Double] = underlying match { case AsJavaDoubleSupplier((sf @ _)) => sf.asInstanceOf[scala.Function0[Double]] case _ => new FromJavaDoubleSupplier(underlying) } } - + case class AsJavaDoubleSupplier(sf: scala.Function0[Double]) extends java.util.function.DoubleSupplier { def getAsDouble() = sf.apply() } - + class RichFunction0AsDoubleSupplier(private val underlying: scala.Function0[Double]) extends AnyVal { @inline def asJava: java.util.function.DoubleSupplier = underlying match { case FromJavaDoubleSupplier((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleSupplier] case _ => new AsJavaDoubleSupplier(underlying) } } - - + + case class FromJavaDoubleToIntFunction(jf: java.util.function.DoubleToIntFunction) extends scala.Function1[Double, Int] { def apply(x1: scala.Double) = jf.applyAsInt(x1) } - + class RichDoubleToIntFunctionAsFunction1(private val underlying: java.util.function.DoubleToIntFunction) extends AnyVal { @inline def asScala: scala.Function1[Double, Int] = underlying match { case AsJavaDoubleToIntFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Double, Int]] case _ => new FromJavaDoubleToIntFunction(underlying) } } - + case class AsJavaDoubleToIntFunction(sf: scala.Function1[Double, Int]) extends java.util.function.DoubleToIntFunction { def applyAsInt(x1: scala.Double) = sf.apply(x1) } - + class RichFunction1AsDoubleToIntFunction(private val underlying: scala.Function1[Double, Int]) extends AnyVal { @inline def asJava: java.util.function.DoubleToIntFunction = underlying match { case FromJavaDoubleToIntFunction((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleToIntFunction] case _ => new AsJavaDoubleToIntFunction(underlying) } } - - + + case class FromJavaDoubleToLongFunction(jf: java.util.function.DoubleToLongFunction) extends scala.Function1[Double, Long] { def apply(x1: scala.Double) = jf.applyAsLong(x1) } - + class RichDoubleToLongFunctionAsFunction1(private val underlying: java.util.function.DoubleToLongFunction) extends AnyVal { @inline def asScala: scala.Function1[Double, Long] = underlying match { case AsJavaDoubleToLongFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Double, Long]] case _ => new FromJavaDoubleToLongFunction(underlying) } } - + case class AsJavaDoubleToLongFunction(sf: scala.Function1[Double, Long]) extends java.util.function.DoubleToLongFunction { def applyAsLong(x1: scala.Double) = sf.apply(x1) } - + class RichFunction1AsDoubleToLongFunction(private val underlying: scala.Function1[Double, Long]) extends AnyVal { @inline def asJava: java.util.function.DoubleToLongFunction = underlying match { case FromJavaDoubleToLongFunction((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleToLongFunction] case _ => new AsJavaDoubleToLongFunction(underlying) } } - - + + case class FromJavaDoubleUnaryOperator(jf: java.util.function.DoubleUnaryOperator) extends scala.Function1[Double, Double] { def apply(x1: scala.Double) = jf.applyAsDouble(x1) } - + class RichDoubleUnaryOperatorAsFunction1(private val underlying: java.util.function.DoubleUnaryOperator) extends AnyVal { @inline def asScala: scala.Function1[Double, Double] = underlying match { case AsJavaDoubleUnaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function1[Double, Double]] case _ => new FromJavaDoubleUnaryOperator(underlying) } } - + case class AsJavaDoubleUnaryOperator(sf: scala.Function1[Double, Double]) extends java.util.function.DoubleUnaryOperator { def applyAsDouble(x1: scala.Double) = sf.apply(x1) } - + class RichFunction1AsDoubleUnaryOperator(private val underlying: scala.Function1[Double, Double]) extends AnyVal { @inline def asJava: java.util.function.DoubleUnaryOperator = underlying match { case FromJavaDoubleUnaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.DoubleUnaryOperator] case _ => new AsJavaDoubleUnaryOperator(underlying) } } - - + + case class FromJavaFunction[T, R](jf: java.util.function.Function[T, R]) extends scala.Function1[T, R] { def apply(x1: T) = jf.apply(x1) } - + class RichFunctionAsFunction1[T, R](private val underlying: java.util.function.Function[T, R]) extends AnyVal { @inline def asScala: scala.Function1[T, R] = underlying match { case AsJavaFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[T, R]] case _ => new FromJavaFunction[T, R](underlying) } } - + case class AsJavaFunction[T, R](sf: scala.Function1[T, R]) extends java.util.function.Function[T, R] { def apply(x1: T) = sf.apply(x1) } - + class RichFunction1AsFunction[T, R](private val underlying: scala.Function1[T, R]) extends AnyVal { @inline def asJava: java.util.function.Function[T, R] = underlying match { case FromJavaFunction((jf @ _)) => jf.asInstanceOf[java.util.function.Function[T, R]] @@ -389,69 +389,69 @@ object FunctionWrappers { case _ => new AsJavaFunction[T, R](underlying) } } - - + + case class FromJavaIntBinaryOperator(jf: java.util.function.IntBinaryOperator) extends scala.Function2[Int, Int, Int] { def apply(x1: scala.Int, x2: scala.Int) = jf.applyAsInt(x1, x2) } - + class RichIntBinaryOperatorAsFunction2(private val underlying: java.util.function.IntBinaryOperator) extends AnyVal { @inline def asScala: scala.Function2[Int, Int, Int] = underlying match { case AsJavaIntBinaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function2[Int, Int, Int]] case _ => new FromJavaIntBinaryOperator(underlying) } } - + case class AsJavaIntBinaryOperator(sf: scala.Function2[Int, Int, Int]) extends java.util.function.IntBinaryOperator { def applyAsInt(x1: scala.Int, x2: scala.Int) = sf.apply(x1, x2) } - + class RichFunction2AsIntBinaryOperator(private val underlying: scala.Function2[Int, Int, Int]) extends AnyVal { @inline def asJava: java.util.function.IntBinaryOperator = underlying match { case FromJavaIntBinaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.IntBinaryOperator] case _ => new AsJavaIntBinaryOperator(underlying) } } - - + + case class FromJavaIntConsumer(jf: java.util.function.IntConsumer) extends scala.Function1[Int, Unit] { def apply(x1: scala.Int) = jf.accept(x1) } - + class RichIntConsumerAsFunction1(private val underlying: java.util.function.IntConsumer) extends AnyVal { @inline def asScala: scala.Function1[Int, Unit] = underlying match { case AsJavaIntConsumer((sf @ _)) => sf.asInstanceOf[scala.Function1[Int, Unit]] case _ => new FromJavaIntConsumer(underlying) } } - + case class AsJavaIntConsumer(sf: scala.Function1[Int, Unit]) extends java.util.function.IntConsumer { def accept(x1: scala.Int) = sf.apply(x1) } - + class RichFunction1AsIntConsumer(private val underlying: scala.Function1[Int, Unit]) extends AnyVal { @inline def asJava: java.util.function.IntConsumer = underlying match { case FromJavaIntConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.IntConsumer] case _ => new AsJavaIntConsumer(underlying) } } - - + + case class FromJavaIntFunction[R](jf: java.util.function.IntFunction[R]) extends scala.Function1[Int, R] { def apply(x1: scala.Int) = jf.apply(x1) } - + class RichIntFunctionAsFunction1[R](private val underlying: java.util.function.IntFunction[R]) extends AnyVal { @inline def asScala: scala.Function1[Int, R] = underlying match { case AsJavaIntFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Int, R]] case _ => new FromJavaIntFunction[R](underlying) } } - + case class AsJavaIntFunction[R](sf: scala.Function1[Int, R]) extends java.util.function.IntFunction[R] { def apply(x1: scala.Int) = sf.apply(x1) } - + class RichFunction1AsIntFunction[R](private val underlying: scala.Function1[Int, R]) extends AnyVal { @inline def asJava: java.util.function.IntFunction[R] = underlying match { case FromJavaIntFunction((jf @ _)) => jf.asInstanceOf[java.util.function.IntFunction[R]] @@ -462,184 +462,184 @@ object FunctionWrappers { case _ => new AsJavaIntFunction[R](underlying) } } - - + + case class FromJavaIntPredicate(jf: java.util.function.IntPredicate) extends scala.Function1[Int, Boolean] { def apply(x1: scala.Int) = jf.test(x1) } - + class RichIntPredicateAsFunction1(private val underlying: java.util.function.IntPredicate) extends AnyVal { @inline def asScala: scala.Function1[Int, Boolean] = underlying match { case AsJavaIntPredicate((sf @ _)) => sf.asInstanceOf[scala.Function1[Int, Boolean]] case _ => new FromJavaIntPredicate(underlying) } } - + case class AsJavaIntPredicate(sf: scala.Function1[Int, Boolean]) extends java.util.function.IntPredicate { def test(x1: scala.Int) = sf.apply(x1) } - + class RichFunction1AsIntPredicate(private val underlying: scala.Function1[Int, Boolean]) extends AnyVal { @inline def asJava: java.util.function.IntPredicate = underlying match { case FromJavaIntPredicate((jf @ _)) => jf.asInstanceOf[java.util.function.IntPredicate] case _ => new AsJavaIntPredicate(underlying) } } - - + + case class FromJavaIntSupplier(jf: java.util.function.IntSupplier) extends scala.Function0[Int] { def apply() = jf.getAsInt() } - + class RichIntSupplierAsFunction0(private val underlying: java.util.function.IntSupplier) extends AnyVal { @inline def asScala: scala.Function0[Int] = underlying match { case AsJavaIntSupplier((sf @ _)) => sf.asInstanceOf[scala.Function0[Int]] case _ => new FromJavaIntSupplier(underlying) } } - + case class AsJavaIntSupplier(sf: scala.Function0[Int]) extends java.util.function.IntSupplier { def getAsInt() = sf.apply() } - + class RichFunction0AsIntSupplier(private val underlying: scala.Function0[Int]) extends AnyVal { @inline def asJava: java.util.function.IntSupplier = underlying match { case FromJavaIntSupplier((jf @ _)) => jf.asInstanceOf[java.util.function.IntSupplier] case _ => new AsJavaIntSupplier(underlying) } } - - + + case class FromJavaIntToDoubleFunction(jf: java.util.function.IntToDoubleFunction) extends scala.Function1[Int, Double] { def apply(x1: scala.Int) = jf.applyAsDouble(x1) } - + class RichIntToDoubleFunctionAsFunction1(private val underlying: java.util.function.IntToDoubleFunction) extends AnyVal { @inline def asScala: scala.Function1[Int, Double] = underlying match { case AsJavaIntToDoubleFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Int, Double]] case _ => new FromJavaIntToDoubleFunction(underlying) } } - + case class AsJavaIntToDoubleFunction(sf: scala.Function1[Int, Double]) extends java.util.function.IntToDoubleFunction { def applyAsDouble(x1: scala.Int) = sf.apply(x1) } - + class RichFunction1AsIntToDoubleFunction(private val underlying: scala.Function1[Int, Double]) extends AnyVal { @inline def asJava: java.util.function.IntToDoubleFunction = underlying match { case FromJavaIntToDoubleFunction((jf @ _)) => jf.asInstanceOf[java.util.function.IntToDoubleFunction] case _ => new AsJavaIntToDoubleFunction(underlying) } } - - + + case class FromJavaIntToLongFunction(jf: java.util.function.IntToLongFunction) extends scala.Function1[Int, Long] { def apply(x1: scala.Int) = jf.applyAsLong(x1) } - + class RichIntToLongFunctionAsFunction1(private val underlying: java.util.function.IntToLongFunction) extends AnyVal { @inline def asScala: scala.Function1[Int, Long] = underlying match { case AsJavaIntToLongFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Int, Long]] case _ => new FromJavaIntToLongFunction(underlying) } } - + case class AsJavaIntToLongFunction(sf: scala.Function1[Int, Long]) extends java.util.function.IntToLongFunction { def applyAsLong(x1: scala.Int) = sf.apply(x1) } - + class RichFunction1AsIntToLongFunction(private val underlying: scala.Function1[Int, Long]) extends AnyVal { @inline def asJava: java.util.function.IntToLongFunction = underlying match { case FromJavaIntToLongFunction((jf @ _)) => jf.asInstanceOf[java.util.function.IntToLongFunction] case _ => new AsJavaIntToLongFunction(underlying) } } - - + + case class FromJavaIntUnaryOperator(jf: java.util.function.IntUnaryOperator) extends scala.Function1[Int, Int] { def apply(x1: scala.Int) = jf.applyAsInt(x1) } - + class RichIntUnaryOperatorAsFunction1(private val underlying: java.util.function.IntUnaryOperator) extends AnyVal { @inline def asScala: scala.Function1[Int, Int] = underlying match { case AsJavaIntUnaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function1[Int, Int]] case _ => new FromJavaIntUnaryOperator(underlying) } } - + case class AsJavaIntUnaryOperator(sf: scala.Function1[Int, Int]) extends java.util.function.IntUnaryOperator { def applyAsInt(x1: scala.Int) = sf.apply(x1) } - + class RichFunction1AsIntUnaryOperator(private val underlying: scala.Function1[Int, Int]) extends AnyVal { @inline def asJava: java.util.function.IntUnaryOperator = underlying match { case FromJavaIntUnaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.IntUnaryOperator] case _ => new AsJavaIntUnaryOperator(underlying) } } - - + + case class FromJavaLongBinaryOperator(jf: java.util.function.LongBinaryOperator) extends scala.Function2[Long, Long, Long] { def apply(x1: scala.Long, x2: scala.Long) = jf.applyAsLong(x1, x2) } - + class RichLongBinaryOperatorAsFunction2(private val underlying: java.util.function.LongBinaryOperator) extends AnyVal { @inline def asScala: scala.Function2[Long, Long, Long] = underlying match { case AsJavaLongBinaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function2[Long, Long, Long]] case _ => new FromJavaLongBinaryOperator(underlying) } } - + case class AsJavaLongBinaryOperator(sf: scala.Function2[Long, Long, Long]) extends java.util.function.LongBinaryOperator { def applyAsLong(x1: scala.Long, x2: scala.Long) = sf.apply(x1, x2) } - + class RichFunction2AsLongBinaryOperator(private val underlying: scala.Function2[Long, Long, Long]) extends AnyVal { @inline def asJava: java.util.function.LongBinaryOperator = underlying match { case FromJavaLongBinaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.LongBinaryOperator] case _ => new AsJavaLongBinaryOperator(underlying) } } - - + + case class FromJavaLongConsumer(jf: java.util.function.LongConsumer) extends scala.Function1[Long, Unit] { def apply(x1: scala.Long) = jf.accept(x1) } - + class RichLongConsumerAsFunction1(private val underlying: java.util.function.LongConsumer) extends AnyVal { @inline def asScala: scala.Function1[Long, Unit] = underlying match { case AsJavaLongConsumer((sf @ _)) => sf.asInstanceOf[scala.Function1[Long, Unit]] case _ => new FromJavaLongConsumer(underlying) } } - + case class AsJavaLongConsumer(sf: scala.Function1[Long, Unit]) extends java.util.function.LongConsumer { def accept(x1: scala.Long) = sf.apply(x1) } - + class RichFunction1AsLongConsumer(private val underlying: scala.Function1[Long, Unit]) extends AnyVal { @inline def asJava: java.util.function.LongConsumer = underlying match { case FromJavaLongConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.LongConsumer] case _ => new AsJavaLongConsumer(underlying) } } - - + + case class FromJavaLongFunction[R](jf: java.util.function.LongFunction[R]) extends scala.Function1[Long, R] { def apply(x1: scala.Long) = jf.apply(x1) } - + class RichLongFunctionAsFunction1[R](private val underlying: java.util.function.LongFunction[R]) extends AnyVal { @inline def asScala: scala.Function1[Long, R] = underlying match { case AsJavaLongFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Long, R]] case _ => new FromJavaLongFunction[R](underlying) } } - + case class AsJavaLongFunction[R](sf: scala.Function1[Long, R]) extends java.util.function.LongFunction[R] { def apply(x1: scala.Long) = sf.apply(x1) } - + class RichFunction1AsLongFunction[R](private val underlying: scala.Function1[Long, R]) extends AnyVal { @inline def asJava: java.util.function.LongFunction[R] = underlying match { case FromJavaLongFunction((jf @ _)) => jf.asInstanceOf[java.util.function.LongFunction[R]] @@ -650,138 +650,138 @@ object FunctionWrappers { case _ => new AsJavaLongFunction[R](underlying) } } - - + + case class FromJavaLongPredicate(jf: java.util.function.LongPredicate) extends scala.Function1[Long, Boolean] { def apply(x1: scala.Long) = jf.test(x1) } - + class RichLongPredicateAsFunction1(private val underlying: java.util.function.LongPredicate) extends AnyVal { @inline def asScala: scala.Function1[Long, Boolean] = underlying match { case AsJavaLongPredicate((sf @ _)) => sf.asInstanceOf[scala.Function1[Long, Boolean]] case _ => new FromJavaLongPredicate(underlying) } } - + case class AsJavaLongPredicate(sf: scala.Function1[Long, Boolean]) extends java.util.function.LongPredicate { def test(x1: scala.Long) = sf.apply(x1) } - + class RichFunction1AsLongPredicate(private val underlying: scala.Function1[Long, Boolean]) extends AnyVal { @inline def asJava: java.util.function.LongPredicate = underlying match { case FromJavaLongPredicate((jf @ _)) => jf.asInstanceOf[java.util.function.LongPredicate] case _ => new AsJavaLongPredicate(underlying) } } - - + + case class FromJavaLongSupplier(jf: java.util.function.LongSupplier) extends scala.Function0[Long] { def apply() = jf.getAsLong() } - + class RichLongSupplierAsFunction0(private val underlying: java.util.function.LongSupplier) extends AnyVal { @inline def asScala: scala.Function0[Long] = underlying match { case AsJavaLongSupplier((sf @ _)) => sf.asInstanceOf[scala.Function0[Long]] case _ => new FromJavaLongSupplier(underlying) } } - + case class AsJavaLongSupplier(sf: scala.Function0[Long]) extends java.util.function.LongSupplier { def getAsLong() = sf.apply() } - + class RichFunction0AsLongSupplier(private val underlying: scala.Function0[Long]) extends AnyVal { @inline def asJava: java.util.function.LongSupplier = underlying match { case FromJavaLongSupplier((jf @ _)) => jf.asInstanceOf[java.util.function.LongSupplier] case _ => new AsJavaLongSupplier(underlying) } } - - + + case class FromJavaLongToDoubleFunction(jf: java.util.function.LongToDoubleFunction) extends scala.Function1[Long, Double] { def apply(x1: scala.Long) = jf.applyAsDouble(x1) } - + class RichLongToDoubleFunctionAsFunction1(private val underlying: java.util.function.LongToDoubleFunction) extends AnyVal { @inline def asScala: scala.Function1[Long, Double] = underlying match { case AsJavaLongToDoubleFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Long, Double]] case _ => new FromJavaLongToDoubleFunction(underlying) } } - + case class AsJavaLongToDoubleFunction(sf: scala.Function1[Long, Double]) extends java.util.function.LongToDoubleFunction { def applyAsDouble(x1: scala.Long) = sf.apply(x1) } - + class RichFunction1AsLongToDoubleFunction(private val underlying: scala.Function1[Long, Double]) extends AnyVal { @inline def asJava: java.util.function.LongToDoubleFunction = underlying match { case FromJavaLongToDoubleFunction((jf @ _)) => jf.asInstanceOf[java.util.function.LongToDoubleFunction] case _ => new AsJavaLongToDoubleFunction(underlying) } } - - + + case class FromJavaLongToIntFunction(jf: java.util.function.LongToIntFunction) extends scala.Function1[Long, Int] { def apply(x1: scala.Long) = jf.applyAsInt(x1) } - + class RichLongToIntFunctionAsFunction1(private val underlying: java.util.function.LongToIntFunction) extends AnyVal { @inline def asScala: scala.Function1[Long, Int] = underlying match { case AsJavaLongToIntFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[Long, Int]] case _ => new FromJavaLongToIntFunction(underlying) } } - + case class AsJavaLongToIntFunction(sf: scala.Function1[Long, Int]) extends java.util.function.LongToIntFunction { def applyAsInt(x1: scala.Long) = sf.apply(x1) } - + class RichFunction1AsLongToIntFunction(private val underlying: scala.Function1[Long, Int]) extends AnyVal { @inline def asJava: java.util.function.LongToIntFunction = underlying match { case FromJavaLongToIntFunction((jf @ _)) => jf.asInstanceOf[java.util.function.LongToIntFunction] case _ => new AsJavaLongToIntFunction(underlying) } } - - + + case class FromJavaLongUnaryOperator(jf: java.util.function.LongUnaryOperator) extends scala.Function1[Long, Long] { def apply(x1: scala.Long) = jf.applyAsLong(x1) } - + class RichLongUnaryOperatorAsFunction1(private val underlying: java.util.function.LongUnaryOperator) extends AnyVal { @inline def asScala: scala.Function1[Long, Long] = underlying match { case AsJavaLongUnaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function1[Long, Long]] case _ => new FromJavaLongUnaryOperator(underlying) } } - + case class AsJavaLongUnaryOperator(sf: scala.Function1[Long, Long]) extends java.util.function.LongUnaryOperator { def applyAsLong(x1: scala.Long) = sf.apply(x1) } - + class RichFunction1AsLongUnaryOperator(private val underlying: scala.Function1[Long, Long]) extends AnyVal { @inline def asJava: java.util.function.LongUnaryOperator = underlying match { case FromJavaLongUnaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.LongUnaryOperator] case _ => new AsJavaLongUnaryOperator(underlying) } } - - + + case class FromJavaObjDoubleConsumer[T](jf: java.util.function.ObjDoubleConsumer[T]) extends scala.Function2[T, Double, Unit] { def apply(x1: T, x2: scala.Double) = jf.accept(x1, x2) } - + class RichObjDoubleConsumerAsFunction2[T](private val underlying: java.util.function.ObjDoubleConsumer[T]) extends AnyVal { @inline def asScala: scala.Function2[T, Double, Unit] = underlying match { case AsJavaObjDoubleConsumer((sf @ _)) => sf.asInstanceOf[scala.Function2[T, Double, Unit]] case _ => new FromJavaObjDoubleConsumer[T](underlying) } } - + case class AsJavaObjDoubleConsumer[T](sf: scala.Function2[T, Double, Unit]) extends java.util.function.ObjDoubleConsumer[T] { def accept(x1: T, x2: scala.Double) = sf.apply(x1, x2) } - + class RichFunction2AsObjDoubleConsumer[T](private val underlying: scala.Function2[T, Double, Unit]) extends AnyVal { @inline def asJava: java.util.function.ObjDoubleConsumer[T] = underlying match { case FromJavaObjDoubleConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.ObjDoubleConsumer[T]] @@ -792,23 +792,23 @@ object FunctionWrappers { case _ => new AsJavaObjDoubleConsumer[T](underlying) } } - - + + case class FromJavaObjIntConsumer[T](jf: java.util.function.ObjIntConsumer[T]) extends scala.Function2[T, Int, Unit] { def apply(x1: T, x2: scala.Int) = jf.accept(x1, x2) } - + class RichObjIntConsumerAsFunction2[T](private val underlying: java.util.function.ObjIntConsumer[T]) extends AnyVal { @inline def asScala: scala.Function2[T, Int, Unit] = underlying match { case AsJavaObjIntConsumer((sf @ _)) => sf.asInstanceOf[scala.Function2[T, Int, Unit]] case _ => new FromJavaObjIntConsumer[T](underlying) } } - + case class AsJavaObjIntConsumer[T](sf: scala.Function2[T, Int, Unit]) extends java.util.function.ObjIntConsumer[T] { def accept(x1: T, x2: scala.Int) = sf.apply(x1, x2) } - + class RichFunction2AsObjIntConsumer[T](private val underlying: scala.Function2[T, Int, Unit]) extends AnyVal { @inline def asJava: java.util.function.ObjIntConsumer[T] = underlying match { case FromJavaObjIntConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.ObjIntConsumer[T]] @@ -819,23 +819,23 @@ object FunctionWrappers { case _ => new AsJavaObjIntConsumer[T](underlying) } } - - + + case class FromJavaObjLongConsumer[T](jf: java.util.function.ObjLongConsumer[T]) extends scala.Function2[T, Long, Unit] { def apply(x1: T, x2: scala.Long) = jf.accept(x1, x2) } - + class RichObjLongConsumerAsFunction2[T](private val underlying: java.util.function.ObjLongConsumer[T]) extends AnyVal { @inline def asScala: scala.Function2[T, Long, Unit] = underlying match { case AsJavaObjLongConsumer((sf @ _)) => sf.asInstanceOf[scala.Function2[T, Long, Unit]] case _ => new FromJavaObjLongConsumer[T](underlying) } } - + case class AsJavaObjLongConsumer[T](sf: scala.Function2[T, Long, Unit]) extends java.util.function.ObjLongConsumer[T] { def accept(x1: T, x2: scala.Long) = sf.apply(x1, x2) } - + class RichFunction2AsObjLongConsumer[T](private val underlying: scala.Function2[T, Long, Unit]) extends AnyVal { @inline def asJava: java.util.function.ObjLongConsumer[T] = underlying match { case FromJavaObjLongConsumer((jf @ _)) => jf.asInstanceOf[java.util.function.ObjLongConsumer[T]] @@ -846,23 +846,23 @@ object FunctionWrappers { case _ => new AsJavaObjLongConsumer[T](underlying) } } - - + + case class FromJavaPredicate[T](jf: java.util.function.Predicate[T]) extends scala.Function1[T, Boolean] { def apply(x1: T) = jf.test(x1) } - + class RichPredicateAsFunction1[T](private val underlying: java.util.function.Predicate[T]) extends AnyVal { @inline def asScala: scala.Function1[T, Boolean] = underlying match { case AsJavaPredicate((sf @ _)) => sf.asInstanceOf[scala.Function1[T, Boolean]] case _ => new FromJavaPredicate[T](underlying) } } - + case class AsJavaPredicate[T](sf: scala.Function1[T, Boolean]) extends java.util.function.Predicate[T] { def test(x1: T) = sf.apply(x1) } - + class RichFunction1AsPredicate[T](private val underlying: scala.Function1[T, Boolean]) extends AnyVal { @inline def asJava: java.util.function.Predicate[T] = underlying match { case FromJavaPredicate((jf @ _)) => jf.asInstanceOf[java.util.function.Predicate[T]] @@ -873,23 +873,23 @@ object FunctionWrappers { case _ => new AsJavaPredicate[T](underlying) } } - - + + case class FromJavaSupplier[T](jf: java.util.function.Supplier[T]) extends scala.Function0[T] { def apply() = jf.get() } - + class RichSupplierAsFunction0[T](private val underlying: java.util.function.Supplier[T]) extends AnyVal { @inline def asScala: scala.Function0[T] = underlying match { case AsJavaSupplier((sf @ _)) => sf.asInstanceOf[scala.Function0[T]] case _ => new FromJavaSupplier[T](underlying) } } - + case class AsJavaSupplier[T](sf: scala.Function0[T]) extends java.util.function.Supplier[T] { def get() = sf.apply() } - + class RichFunction0AsSupplier[T](private val underlying: scala.Function0[T]) extends AnyVal { @inline def asJava: java.util.function.Supplier[T] = underlying match { case FromJavaSupplier((jf @ _)) => jf.asInstanceOf[java.util.function.Supplier[T]] @@ -900,23 +900,23 @@ object FunctionWrappers { case _ => new AsJavaSupplier[T](underlying) } } - - + + case class FromJavaToDoubleBiFunction[T, U](jf: java.util.function.ToDoubleBiFunction[T, U]) extends scala.Function2[T, U, Double] { def apply(x1: T, x2: U) = jf.applyAsDouble(x1, x2) } - + class RichToDoubleBiFunctionAsFunction2[T, U](private val underlying: java.util.function.ToDoubleBiFunction[T, U]) extends AnyVal { @inline def asScala: scala.Function2[T, U, Double] = underlying match { case AsJavaToDoubleBiFunction((sf @ _)) => sf.asInstanceOf[scala.Function2[T, U, Double]] case _ => new FromJavaToDoubleBiFunction[T, U](underlying) } } - + case class AsJavaToDoubleBiFunction[T, U](sf: scala.Function2[T, U, Double]) extends java.util.function.ToDoubleBiFunction[T, U] { def applyAsDouble(x1: T, x2: U) = sf.apply(x1, x2) } - + class RichFunction2AsToDoubleBiFunction[T, U](private val underlying: scala.Function2[T, U, Double]) extends AnyVal { @inline def asJava: java.util.function.ToDoubleBiFunction[T, U] = underlying match { case FromJavaToDoubleBiFunction((jf @ _)) => jf.asInstanceOf[java.util.function.ToDoubleBiFunction[T, U]] @@ -927,23 +927,23 @@ object FunctionWrappers { case _ => new AsJavaToDoubleBiFunction[T, U](underlying) } } - - + + case class FromJavaToDoubleFunction[T](jf: java.util.function.ToDoubleFunction[T]) extends scala.Function1[T, Double] { def apply(x1: T) = jf.applyAsDouble(x1) } - + class RichToDoubleFunctionAsFunction1[T](private val underlying: java.util.function.ToDoubleFunction[T]) extends AnyVal { @inline def asScala: scala.Function1[T, Double] = underlying match { case AsJavaToDoubleFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[T, Double]] case _ => new FromJavaToDoubleFunction[T](underlying) } } - + case class AsJavaToDoubleFunction[T](sf: scala.Function1[T, Double]) extends java.util.function.ToDoubleFunction[T] { def applyAsDouble(x1: T) = sf.apply(x1) } - + class RichFunction1AsToDoubleFunction[T](private val underlying: scala.Function1[T, Double]) extends AnyVal { @inline def asJava: java.util.function.ToDoubleFunction[T] = underlying match { case FromJavaToDoubleFunction((jf @ _)) => jf.asInstanceOf[java.util.function.ToDoubleFunction[T]] @@ -954,23 +954,23 @@ object FunctionWrappers { case _ => new AsJavaToDoubleFunction[T](underlying) } } - - + + case class FromJavaToIntBiFunction[T, U](jf: java.util.function.ToIntBiFunction[T, U]) extends scala.Function2[T, U, Int] { def apply(x1: T, x2: U) = jf.applyAsInt(x1, x2) } - + class RichToIntBiFunctionAsFunction2[T, U](private val underlying: java.util.function.ToIntBiFunction[T, U]) extends AnyVal { @inline def asScala: scala.Function2[T, U, Int] = underlying match { case AsJavaToIntBiFunction((sf @ _)) => sf.asInstanceOf[scala.Function2[T, U, Int]] case _ => new FromJavaToIntBiFunction[T, U](underlying) } } - + case class AsJavaToIntBiFunction[T, U](sf: scala.Function2[T, U, Int]) extends java.util.function.ToIntBiFunction[T, U] { def applyAsInt(x1: T, x2: U) = sf.apply(x1, x2) } - + class RichFunction2AsToIntBiFunction[T, U](private val underlying: scala.Function2[T, U, Int]) extends AnyVal { @inline def asJava: java.util.function.ToIntBiFunction[T, U] = underlying match { case FromJavaToIntBiFunction((jf @ _)) => jf.asInstanceOf[java.util.function.ToIntBiFunction[T, U]] @@ -981,23 +981,23 @@ object FunctionWrappers { case _ => new AsJavaToIntBiFunction[T, U](underlying) } } - - + + case class FromJavaToIntFunction[T](jf: java.util.function.ToIntFunction[T]) extends scala.Function1[T, Int] { def apply(x1: T) = jf.applyAsInt(x1) } - + class RichToIntFunctionAsFunction1[T](private val underlying: java.util.function.ToIntFunction[T]) extends AnyVal { @inline def asScala: scala.Function1[T, Int] = underlying match { case AsJavaToIntFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[T, Int]] case _ => new FromJavaToIntFunction[T](underlying) } } - + case class AsJavaToIntFunction[T](sf: scala.Function1[T, Int]) extends java.util.function.ToIntFunction[T] { def applyAsInt(x1: T) = sf.apply(x1) } - + class RichFunction1AsToIntFunction[T](private val underlying: scala.Function1[T, Int]) extends AnyVal { @inline def asJava: java.util.function.ToIntFunction[T] = underlying match { case FromJavaToIntFunction((jf @ _)) => jf.asInstanceOf[java.util.function.ToIntFunction[T]] @@ -1008,23 +1008,23 @@ object FunctionWrappers { case _ => new AsJavaToIntFunction[T](underlying) } } - - + + case class FromJavaToLongBiFunction[T, U](jf: java.util.function.ToLongBiFunction[T, U]) extends scala.Function2[T, U, Long] { def apply(x1: T, x2: U) = jf.applyAsLong(x1, x2) } - + class RichToLongBiFunctionAsFunction2[T, U](private val underlying: java.util.function.ToLongBiFunction[T, U]) extends AnyVal { @inline def asScala: scala.Function2[T, U, Long] = underlying match { case AsJavaToLongBiFunction((sf @ _)) => sf.asInstanceOf[scala.Function2[T, U, Long]] case _ => new FromJavaToLongBiFunction[T, U](underlying) } } - + case class AsJavaToLongBiFunction[T, U](sf: scala.Function2[T, U, Long]) extends java.util.function.ToLongBiFunction[T, U] { def applyAsLong(x1: T, x2: U) = sf.apply(x1, x2) } - + class RichFunction2AsToLongBiFunction[T, U](private val underlying: scala.Function2[T, U, Long]) extends AnyVal { @inline def asJava: java.util.function.ToLongBiFunction[T, U] = underlying match { case FromJavaToLongBiFunction((jf @ _)) => jf.asInstanceOf[java.util.function.ToLongBiFunction[T, U]] @@ -1035,23 +1035,23 @@ object FunctionWrappers { case _ => new AsJavaToLongBiFunction[T, U](underlying) } } - - + + case class FromJavaToLongFunction[T](jf: java.util.function.ToLongFunction[T]) extends scala.Function1[T, Long] { def apply(x1: T) = jf.applyAsLong(x1) } - + class RichToLongFunctionAsFunction1[T](private val underlying: java.util.function.ToLongFunction[T]) extends AnyVal { @inline def asScala: scala.Function1[T, Long] = underlying match { case AsJavaToLongFunction((sf @ _)) => sf.asInstanceOf[scala.Function1[T, Long]] case _ => new FromJavaToLongFunction[T](underlying) } } - + case class AsJavaToLongFunction[T](sf: scala.Function1[T, Long]) extends java.util.function.ToLongFunction[T] { def applyAsLong(x1: T) = sf.apply(x1) } - + class RichFunction1AsToLongFunction[T](private val underlying: scala.Function1[T, Long]) extends AnyVal { @inline def asJava: java.util.function.ToLongFunction[T] = underlying match { case FromJavaToLongFunction((jf @ _)) => jf.asInstanceOf[java.util.function.ToLongFunction[T]] @@ -1062,23 +1062,23 @@ object FunctionWrappers { case _ => new AsJavaToLongFunction[T](underlying) } } - - + + case class FromJavaUnaryOperator[T](jf: java.util.function.UnaryOperator[T]) extends scala.Function1[T, T] { def apply(x1: T) = jf.apply(x1) } - + class RichUnaryOperatorAsFunction1[T](private val underlying: java.util.function.UnaryOperator[T]) extends AnyVal { @inline def asScala: scala.Function1[T, T] = underlying match { case AsJavaUnaryOperator((sf @ _)) => sf.asInstanceOf[scala.Function1[T, T]] case _ => new FromJavaUnaryOperator[T](underlying) } } - + case class AsJavaUnaryOperator[T](sf: scala.Function1[T, T]) extends java.util.function.UnaryOperator[T] { def apply(x1: T) = sf.apply(x1) } - + class RichFunction1AsUnaryOperator[T](private val underlying: scala.Function1[T, T]) extends AnyVal { @inline def asJava: java.util.function.UnaryOperator[T] = underlying match { case FromJavaUnaryOperator((jf @ _)) => jf.asInstanceOf[java.util.function.UnaryOperator[T]] diff --git a/library/src/scala/jdk/IntAccumulator.scala b/library/src/scala/jdk/IntAccumulator.scala index 2b507940ec2e..0a85b519ae63 100644 --- a/library/src/scala/jdk/IntAccumulator.scala +++ b/library/src/scala/jdk/IntAccumulator.scala @@ -412,7 +412,7 @@ private[jdk] class IntAccumulatorStepper(private val acc: IntAccumulator) extend ans } - def trySplit(): IntStepper = + def trySplit(): IntStepper | Null = if (N <= 1) null else { val half = N >> 1 diff --git a/library/src/scala/jdk/LongAccumulator.scala b/library/src/scala/jdk/LongAccumulator.scala index dd39c6e05a4d..ee9ce79b0ba5 100644 --- a/library/src/scala/jdk/LongAccumulator.scala +++ b/library/src/scala/jdk/LongAccumulator.scala @@ -407,7 +407,7 @@ private[jdk] class LongAccumulatorStepper(private val acc: LongAccumulator) exte ans } - def trySplit(): LongStepper = + def trySplit(): LongStepper | Null = if (N <= 1) null else { val half = N >> 1 diff --git a/library/src/scala/math/BigDecimal.scala b/library/src/scala/math/BigDecimal.scala index 7e0cb6434401..283d7865f00b 100644 --- a/library/src/scala/math/BigDecimal.scala +++ b/library/src/scala/math/BigDecimal.scala @@ -305,7 +305,7 @@ object BigDecimal { implicit def double2bigDecimal(d: Double): BigDecimal = decimal(d) /** Implicit conversion from `java.math.BigDecimal` to `scala.BigDecimal`. */ - implicit def javaBigDecimal2bigDecimal(x: BigDec): BigDecimal = if (x == null) null else apply(x) + implicit def javaBigDecimal2bigDecimal(x: BigDec | Null): BigDecimal | Null = if (x == null) null else apply(x) } /** diff --git a/library/src/scala/math/BigInt.scala b/library/src/scala/math/BigInt.scala index cf7c45d5682a..ba19357dd613 100644 --- a/library/src/scala/math/BigInt.scala +++ b/library/src/scala/math/BigInt.scala @@ -124,7 +124,7 @@ object BigInt { /** Implicit conversion from `java.math.BigInteger` to `scala.BigInt`. */ - implicit def javaBigInteger2bigInt(x: BigInteger): BigInt = if (x eq null) null else apply(x) + implicit def javaBigInteger2bigInt(x: BigInteger | Null): BigInt | Null = if (x eq null) null else apply(x) // this method is adapted from Google Guava's version at // https://github.com/google/guava/blob/master/guava/src/com/google/common/math/LongMath.java @@ -177,8 +177,10 @@ object BigInt { * * It wraps `java.math.BigInteger`, with optimization for small values that can be encoded in a `Long`. */ -final class BigInt private (private var _bigInteger: BigInteger, private val _long: Long) - extends ScalaNumber +final class BigInt private ( + @annotation.stableNull private var _bigInteger: BigInteger | Null, + private val _long: Long +) extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[BigInt] @@ -295,9 +297,9 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo */ def compare(that: BigInt): Int = if (this.longEncoding) { - if (that.longEncoding) java.lang.Long.compare(this._long, that._long) else -that._bigInteger.signum() + if (that.longEncoding) java.lang.Long.compare(this._long, that._long) else -that._bigInteger.nn.signum() } else { - if (that.longEncoding) _bigInteger.signum() else this._bigInteger.compareTo(that._bigInteger) + if (that.longEncoding) _bigInteger.nn.signum() else this._bigInteger.nn.compareTo(that._bigInteger.nn) } /** Addition of BigInts @@ -426,7 +428,7 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo if (that.longEncoding) { if (that._long == 0) return this.abs // if (that._long == Long.MinValue) return this gcd (-that) - val red = (this._bigInteger mod BigInteger.valueOf(that._long.abs)).longValue() + val red = (this._bigInteger.nn mod BigInteger.valueOf(that._long.abs)).longValue() if (red == 0) return that.abs BigInt(BigInt.longGcd(that._long.abs, red)) } else BigInt(this.bigInteger.gcd(that.bigInteger)) @@ -479,7 +481,7 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo * +1 if it is greater than 0, * 0 if it is equal to 0. */ - def signum: Int = if (longEncoding) java.lang.Long.signum(_long) else _bigInteger.signum() + def signum: Int = if (longEncoding) java.lang.Long.signum(_long) else _bigInteger.nn.signum() /** Returns the sign of this BigInt; * -1 if it is less than 0, @@ -536,7 +538,7 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo if (longEncoding) { if (_long < 0) 64 - java.lang.Long.numberOfLeadingZeros(-(_long + 1)) // takes care of Long.MinValue else 64 - java.lang.Long.numberOfLeadingZeros(_long) - } else _bigInteger.bitLength() + } else _bigInteger.nn.bitLength() /** Returns the number of bits in the two's complement representation of this BigInt * that differ from its sign bit. @@ -590,7 +592,7 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo * overall magnitude of the BigInt value as well as return a result with * the opposite sign. */ - def longValue: Long = if (longEncoding) _long else _bigInteger.longValue + def longValue: Long = if (longEncoding) _long else _bigInteger.nn.longValue /** Converts this `BigInt` to a `float`. * If this `BigInt` has too great a magnitude to represent as a float, diff --git a/library/src/scala/ref/ReferenceQueue.scala b/library/src/scala/ref/ReferenceQueue.scala index 2fb8e646b444..339d26b05ae2 100644 --- a/library/src/scala/ref/ReferenceQueue.scala +++ b/library/src/scala/ref/ReferenceQueue.scala @@ -19,7 +19,7 @@ class ReferenceQueue[+T <: AnyRef] { private[ref] val underlying: java.lang.ref.ReferenceQueue[_ <: T] = new java.lang.ref.ReferenceQueue[T] override def toString: String = underlying.toString - protected def Wrapper(jref: java.lang.ref.Reference[_]): Option[Reference[T]] = + protected def Wrapper(jref: java.lang.ref.Reference[_] | Null): Option[Reference[T]] = jref match { case null => None case ref => Some(ref.asInstanceOf[ReferenceWithWrapper[T]].wrapper) diff --git a/library/src/scala/ref/SoftReference.scala b/library/src/scala/ref/SoftReference.scala index dd79863ff03b..fbe505d32314 100644 --- a/library/src/scala/ref/SoftReference.scala +++ b/library/src/scala/ref/SoftReference.scala @@ -14,7 +14,7 @@ package scala.ref import scala.language.`2.13` -class SoftReference[+T <: AnyRef](value : T, queue : ReferenceQueue[T]) extends ReferenceWrapper[T] { +class SoftReference[+T <: AnyRef](value : T, queue : ReferenceQueue[T] | Null) extends ReferenceWrapper[T] { def this(value : T) = this(value, null) val underlying: java.lang.ref.SoftReference[_ <: T] = @@ -33,5 +33,5 @@ object SoftReference { def unapply[T <: AnyRef](sr: SoftReference[T]): Option[T] = Option(sr.underlying.get) } -private class SoftReferenceWithWrapper[T <: AnyRef](value: T, queue: ReferenceQueue[T], val wrapper: SoftReference[T]) +private class SoftReferenceWithWrapper[T <: AnyRef](value: T, queue: ReferenceQueue[T] | Null, val wrapper: SoftReference[T]) extends java.lang.ref.SoftReference[T](value, if (queue == null) null else queue.underlying.asInstanceOf[java.lang.ref.ReferenceQueue[T]]) with ReferenceWithWrapper[T] diff --git a/library/src/scala/ref/WeakReference.scala b/library/src/scala/ref/WeakReference.scala index 196b79131a04..d18fa311e0ca 100644 --- a/library/src/scala/ref/WeakReference.scala +++ b/library/src/scala/ref/WeakReference.scala @@ -19,7 +19,7 @@ import scala.language.`2.13` * The new functionality is (1) results are Option values, instead of using null. * (2) There is an extractor that maps the weak reference itself into an option. */ -class WeakReference[+T <: AnyRef](value: T, queue: ReferenceQueue[T]) extends ReferenceWrapper[T] { +class WeakReference[+T <: AnyRef](value: T, queue: ReferenceQueue[T] | Null) extends ReferenceWrapper[T] { def this(value: T) = this(value, null) val underlying: java.lang.ref.WeakReference[_ <: T] = new WeakReferenceWithWrapper[T](value, queue, this) @@ -35,5 +35,5 @@ object WeakReference { def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = Option(wr.underlying.get) } -private class WeakReferenceWithWrapper[T <: AnyRef](value: T, queue: ReferenceQueue[T], val wrapper: WeakReference[T]) - extends java.lang.ref.WeakReference[T](value, if (queue == null) null else queue.underlying.asInstanceOf[java.lang.ref.ReferenceQueue[T]]) with ReferenceWithWrapper[T] +private class WeakReferenceWithWrapper[T <: AnyRef](value: T, queue: ReferenceQueue[T] | Null, val wrapper: WeakReference[T]) + extends java.lang.ref.WeakReference[T](value, if (queue == null) null else queue.nn.underlying.asInstanceOf[java.lang.ref.ReferenceQueue[T]]) with ReferenceWithWrapper[T] diff --git a/library/src/scala/reflect/ClassManifestDeprecatedApis.scala b/library/src/scala/reflect/ClassManifestDeprecatedApis.scala index 17e05050132a..2655dac38f54 100644 --- a/library/src/scala/reflect/ClassManifestDeprecatedApis.scala +++ b/library/src/scala/reflect/ClassManifestDeprecatedApis.scala @@ -32,7 +32,7 @@ trait ClassManifestDeprecatedApis[T] extends OptManifest[T] { def loop(left: Set[jClass[_]], seen: Set[jClass[_]]): Boolean = { left.nonEmpty && { val next = left.head - val supers = next.getInterfaces.toSet ++ Option(next.getSuperclass) + val supers = next.getInterfaces.nn.toSet ++ Option(next.getSuperclass) supers(sup) || { val xs = left ++ supers filterNot seen loop(xs - next, seen + next) @@ -137,7 +137,7 @@ trait ClassManifestDeprecatedApis[T] extends OptManifest[T] { protected def argString = if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]") - else if (runtimeClass.isArray) "["+ClassManifest.fromClass(runtimeClass.getComponentType)+"]" + else if (runtimeClass.isArray) "["+ClassManifest.fromClass(runtimeClass.getComponentType.nn)+"]" else "" } diff --git a/library/src/scala/reflect/NameTransformer.scala b/library/src/scala/reflect/NameTransformer.scala index 15d2af96f15e..01bb89b78870 100644 --- a/library/src/scala/reflect/NameTransformer.scala +++ b/library/src/scala/reflect/NameTransformer.scala @@ -33,10 +33,10 @@ object NameTransformer { private[this] val nops = 128 private[this] val ncodes = 26 * 26 - private class OpCodes(val op: Char, val code: String, val next: OpCodes) + private class OpCodes(val op: Char, val code: String, val next: OpCodes | Null) - private[this] val op2code = new Array[String](nops) - private[this] val code2op = new Array[OpCodes](ncodes) + private[this] val op2code = new Array[String | Null](nops) + private[this] val code2op = new Array[OpCodes | Null](ncodes) private def enterOp(op: Char, code: String) = { op2code(op.toInt) = code val c = (code.charAt(1) - 'a') * 26 + code.charAt(2) - 'a' @@ -69,7 +69,7 @@ object NameTransformer { * @return the string with all recognized opchars replaced with their encoding */ def encode(name: String): String = { - var buf: StringBuilder = null + var buf: StringBuilder | Null = null val len = name.length() var i = 0 while (i < len) { @@ -79,7 +79,7 @@ object NameTransformer { buf = new StringBuilder() buf.append(name.substring(0, i)) } - buf.append(op2code(c.toInt)) + buf.append(op2code(c.toInt).nn) /* Handle glyphs that are not valid Java/JVM identifiers */ } else if (!Character.isJavaIdentifierPart(c)) { @@ -106,11 +106,11 @@ object NameTransformer { //System.out.println("decode: " + name);//DEBUG val name = if (name0.endsWith("")) name0.stripSuffix("") + "this" else name0 - var buf: StringBuilder = null + var buf: StringBuilder | Null = null val len = name.length() var i = 0 while (i < len) { - var ops: OpCodes = null + var ops: OpCodes | Null = null var unicode = false val c = name charAt i if (c == '$' && i + 2 < len) { @@ -119,14 +119,14 @@ object NameTransformer { val ch2 = name.charAt(i+2) if ('a' <= ch2 && ch2 <= 'z') { ops = code2op((ch1 - 'a') * 26 + ch2 - 'a') - while ((ops ne null) && !name.startsWith(ops.code, i)) ops = ops.next + while ((ops ne null) && !name.startsWith(ops.nn.code, i)) ops = ops.nn.next if (ops ne null) { if (buf eq null) { buf = new StringBuilder() buf.append(name.substring(0, i)) } - buf.append(ops.op) - i += ops.code.length() + buf.append(ops.nn.op) + i += ops.nn.code.length() } /* Handle the decoding of Unicode glyphs that are * not valid Java/JVM identifiers */ diff --git a/library/src/scala/runtime/LambdaDeserializer.scala b/library/src/scala/runtime/LambdaDeserializer.scala index fa2a038f1f3f..98ba8a3da983 100644 --- a/library/src/scala/runtime/LambdaDeserializer.scala +++ b/library/src/scala/runtime/LambdaDeserializer.scala @@ -51,14 +51,14 @@ object LambdaDeserializer { } def deserializeLambdaOrNull(lookup: MethodHandles.Lookup, cache: java.util.Map[String, MethodHandle], - targetMethodMap: java.util.Map[String, MethodHandle], serialized: SerializedLambda): AnyRef = { + targetMethodMap: java.util.Map[String, MethodHandle], serialized: SerializedLambda): AnyRef | Null = { assert(targetMethodMap != null) def slashDot(name: String) = name.replaceAll("/", ".") val loader = lookup.lookupClass().getClassLoader val implClass = loader.loadClass(slashDot(serialized.getImplClass)) val key = LambdaDeserialize.nameAndDescriptorKey(serialized.getImplMethodName, serialized.getImplMethodSignature) - def makeCallSite: CallSite = { + def makeCallSite: CallSite | Null = { import serialized._ def parseDescriptor(s: String) = MethodType.fromMethodDescriptorString(s, loader) diff --git a/library/src/scala/runtime/MethodCache.scala b/library/src/scala/runtime/MethodCache.scala index 9cd59a1cf4d3..d50daa770cd0 100644 --- a/library/src/scala/runtime/MethodCache.scala +++ b/library/src/scala/runtime/MethodCache.scala @@ -32,13 +32,13 @@ private[scala] sealed abstract class MethodCache { * `null` is returned. If `null` is returned, find's caller should look- * up the right method using whichever means it prefers, and add it to * the cache for later use. */ - def find(forReceiver: JClass[_]): JMethod + def find(forReceiver: JClass[_]): JMethod | Null def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache } private[scala] final class EmptyMethodCache extends MethodCache { - def find(forReceiver: JClass[_]): JMethod = null + def find(forReceiver: JClass[_]): JMethod | Null = null def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache = new PolyMethodCache(this, forReceiver, forMethod, 1) @@ -50,7 +50,7 @@ private[scala] final class MegaMethodCache( private[this] val forParameterTypes: Array[JClass[_]] ) extends MethodCache { - def find(forReceiver: JClass[_]): JMethod = + def find(forReceiver: JClass[_]): JMethod | Null = forReceiver.getMethod(forName, forParameterTypes:_*) def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache = this @@ -67,14 +67,14 @@ private[scala] final class PolyMethodCache( /** To achieve tail recursion this must be a separate method * from `find`, because the type of next is not `PolyMethodCache`. */ - @tailrec private def findInternal(forReceiver: JClass[_]): JMethod = + @tailrec private def findInternal(forReceiver: JClass[_]): JMethod | Null = if (forReceiver eq receiver) method else next match { case x: PolyMethodCache => x findInternal forReceiver case _ => next find forReceiver } - def find(forReceiver: JClass[_]): JMethod = findInternal(forReceiver) + def find(forReceiver: JClass[_]): JMethod | Null = findInternal(forReceiver) // TODO: come up with a more realistic number final private val MaxComplexity = 160 diff --git a/library/src/scala/runtime/ScalaRunTime.scala b/library/src/scala/runtime/ScalaRunTime.scala index d63056b372c0..8bafd7598205 100644 --- a/library/src/scala/runtime/ScalaRunTime.scala +++ b/library/src/scala/runtime/ScalaRunTime.scala @@ -54,7 +54,7 @@ object ScalaRunTime { classTag[T].runtimeClass.asInstanceOf[jClass[T]] /** Retrieve generic array element */ - def array_apply(xs: AnyRef, idx: Int): Any = { + def array_apply(xs: AnyRef | Null, idx: Int): Any = { (xs: @unchecked) match { case x: Array[AnyRef] => x(idx).asInstanceOf[Any] case x: Array[Int] => x(idx).asInstanceOf[Any] @@ -70,7 +70,7 @@ object ScalaRunTime { } /** update generic array element */ - def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + def array_update(xs: AnyRef | Null, idx: Int, value: Any): Unit = { (xs: @unchecked) match { case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] case x: Array[Int] => x(idx) = value.asInstanceOf[Int] @@ -86,11 +86,11 @@ object ScalaRunTime { } /** Get generic array length */ - @inline def array_length(xs: AnyRef): Int = java.lang.reflect.Array.getLength(xs) + @inline def array_length(xs: AnyRef | Null): Int = java.lang.reflect.Array.getLength(xs) // TODO: bytecode Object.clone() will in fact work here and avoids // the type switch. See Array_clone comment in BCodeBodyBuilder. - def array_clone(xs: AnyRef): AnyRef = (xs: @unchecked) match { + def array_clone(xs: AnyRef | Null): AnyRef = (xs: @unchecked) match { case x: Array[AnyRef] => x.clone() case x: Array[Int] => x.clone() case x: Array[Double] => x.clone() @@ -107,7 +107,7 @@ object ScalaRunTime { * Needed to deal with vararg arguments of primitive types that are passed * to a generic Java vararg parameter T ... */ - def toObjectArray(src: AnyRef): Array[Object] = { + def toObjectArray(src: AnyRef | Null): Array[Object] = { def copy[@specialized T <: AnyVal](src: Array[T]): Array[Object] = { val length = src.length if (length == 0) Array.emptyObjectArray @@ -286,8 +286,8 @@ object ScalaRunTime { // In cases where an empty array would appear, the compiler uses a direct reference to Nil instead. // Synthetic Java varargs forwarders (@annotation.varargs or varargs bridges when overriding) may pass // `null` to these methods; but returning `null` or `ArraySeq(null)` makes little difference in practice. - def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = ArraySeq.unsafeWrapArray(xs) - def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = new ArraySeq.ofRef[T](xs) + def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = ArraySeq.unsafeWrapArray(xs).asInstanceOf[ArraySeq[T]] + def wrapRefArray[T <: AnyRef | Null](xs: Array[T]): ArraySeq[T] = new ArraySeq.ofRef[T](xs) def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = new ArraySeq.ofInt(xs) def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = new ArraySeq.ofDouble(xs) def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = new ArraySeq.ofLong(xs) diff --git a/library/src/scala/runtime/StructuralCallSite.scala b/library/src/scala/runtime/StructuralCallSite.scala index 29a0febec3f0..26e51c518cd4 100644 --- a/library/src/scala/runtime/StructuralCallSite.scala +++ b/library/src/scala/runtime/StructuralCallSite.scala @@ -31,7 +31,7 @@ final class StructuralCallSite private (callType: MethodType) { cache } - def find(receiver: Class[_]): Method = get.find(receiver) + def find(receiver: Class[_]): Method | Null = get.find(receiver) def add(receiver: Class[_], m: Method): Method = { cache = new SoftReference(get.add(receiver, m)) diff --git a/library/src/scala/sys/PropImpl.scala b/library/src/scala/sys/PropImpl.scala index 37f0bac5c02a..7f2f1b96b153 100644 --- a/library/src/scala/sys/PropImpl.scala +++ b/library/src/scala/sys/PropImpl.scala @@ -21,8 +21,8 @@ import scala.collection.mutable private[sys] class PropImpl[+T](val key: String, valueFn: String => T) extends Prop[T] { def value: T = if (isSet) valueFn(get) else zero def isSet = underlying contains key - def set(newValue: String): String = { - val old = if (isSet) get else null + def set(newValue: String | Null): String | Null = { + val old: String | Null = if (isSet) get else null underlying(key) = newValue old } @@ -33,7 +33,7 @@ private[sys] class PropImpl[+T](val key: String, valueFn: String => T) extends P old } def get: String = - if (isSet) underlying.getOrElse(key, "") + if (isSet) underlying.getOrElse(key, "").nn else "" def clear(): Unit = underlying -= key @@ -41,7 +41,7 @@ private[sys] class PropImpl[+T](val key: String, valueFn: String => T) extends P def or[T1 >: T](alt: => T1): T1 = if (isSet) value else alt /** The underlying property map, in our case always sys.props */ - protected def underlying: mutable.Map[String, String] = scala.sys.props + protected def underlying: mutable.Map[String, String | Null] = scala.sys.props protected def zero: T = null.asInstanceOf[T] private def getString = if (isSet) "currently: " + get else "unset" override def toString = "%s (%s)".format(key, getString) @@ -50,4 +50,3 @@ private[sys] class PropImpl[+T](val key: String, valueFn: String => T) extends P private[sys] abstract class CreatorImpl[+T](f: String => T) extends Prop.Creator[T] { def apply(key: String): Prop[T] = new PropImpl[T](key, f) } - diff --git a/library/src/scala/sys/SystemProperties.scala b/library/src/scala/sys/SystemProperties.scala index d1a5326e66f7..6daac4493a78 100644 --- a/library/src/scala/sys/SystemProperties.scala +++ b/library/src/scala/sys/SystemProperties.scala @@ -29,19 +29,19 @@ import scala.language.implicitConversions * @define coll mutable map */ class SystemProperties -extends mutable.AbstractMap[String, String] { +extends mutable.AbstractMap[String, String | Null] { - override def empty: mutable.Map[String, String] = mutable.Map[String, String]() - override def default(key: String): String = null + override def empty: mutable.Map[String, String | Null] = mutable.Map[String, String | Null]() + override def default(key: String): String | Null = null - def iterator: Iterator[(String, String)] = wrapAccess { + def iterator: Iterator[(String, String | Null)] = wrapAccess { val ps = System.getProperties() names map (k => (k, ps getProperty k)) filter (_._2 ne null) } getOrElse Iterator.empty override def isEmpty: Boolean = iterator.isEmpty def names: Iterator[String] = wrapAccess ( - System.getProperties().stringPropertyNames().asScala.iterator + System.getProperties().stringPropertyNames().asScala.nn.iterator ) getOrElse Iterator.empty def get(key: String): Option[String] = @@ -51,7 +51,7 @@ extends mutable.AbstractMap[String, String] { override def clear(): Unit = wrapAccess(System.getProperties().clear()) def subtractOne (key: String): this.type = { wrapAccess(System.clearProperty(key)) ; this } - def addOne (kv: (String, String)): this.type = { wrapAccess(System.setProperty(kv._1, kv._2)) ; this } + def addOne (kv: (String, String | Null)): this.type = { wrapAccess(System.setProperty(kv._1, kv._2)) ; this } @annotation.nowarn("cat=deprecation") // AccessControlException is deprecated on JDK 17 def wrapAccess[T](body: => T): Option[T] = @@ -90,4 +90,3 @@ object SystemProperties { lazy val preferIPv6Addresses: BooleanProp = BooleanProp.keyExists(PreferIPv6AddressesKey) lazy val noTraceSuppression: BooleanProp = BooleanProp.valueIsTrue(NoTraceSuppressionKey) } - diff --git a/library/src/scala/sys/package.scala b/library/src/scala/sys/package.scala index 3329e53e0d0b..252d5205d59e 100644 --- a/library/src/scala/sys/package.scala +++ b/library/src/scala/sys/package.scala @@ -65,7 +65,7 @@ package object sys { * * @return a Map containing the system environment variables. */ - def env: Map[String, String] = Map.from(System.getenv().asScala).withDefault { v => + def env: Map[String, String] = Map.from(System.getenv().asScala.nn).withDefault { v => val s = System.getenv(v) if (s == null) throw new NoSuchElementException(v) s @@ -93,6 +93,6 @@ package object sys { val tarray = new Array[Thread](num) val got = Thread.enumerate(tarray) - ArraySeq.unsafeWrapArray(tarray).take(got) + ArraySeq.unsafeWrapArray(tarray).nn.take(got) } } diff --git a/library/src/scala/sys/process/ProcessBuilderImpl.scala b/library/src/scala/sys/process/ProcessBuilderImpl.scala index 41b284dbd0bb..7dd74c67bbec 100644 --- a/library/src/scala/sys/process/ProcessBuilderImpl.scala +++ b/library/src/scala/sys/process/ProcessBuilderImpl.scala @@ -86,7 +86,7 @@ private[process] trait ProcessBuilderImpl { val process = p.start() // start the external process // spawn threads that process the input, output, and error streams using the functions defined in `io` - val inThread = + val inThread: Thread | Null = if (inherit || (writeInput eq BasicIO.connectNoOp)) null else Spawn("Simple-input", daemon = true)(writeInput(process.getOutputStream)) val outThread = Spawn("Simple-output", daemonizeThreads)(processOutput(process.getInputStream())) diff --git a/library/src/scala/sys/process/ProcessImpl.scala b/library/src/scala/sys/process/ProcessImpl.scala index 7e5a742d9b5b..a87f4bf3fb27 100644 --- a/library/src/scala/sys/process/ProcessImpl.scala +++ b/library/src/scala/sys/process/ProcessImpl.scala @@ -261,7 +261,7 @@ private[process] trait ProcessImpl { * The implementation of `exitValue` interrupts `inputThread` * and then waits until all I/O threads die before returning. */ - private[process] class SimpleProcess(p: JProcess, inputThread: Thread, outputThreads: List[Thread]) extends Process { + private[process] class SimpleProcess(p: JProcess, inputThread: Thread | Null, outputThreads: List[Thread]) extends Process { override def isAlive() = p.isAlive() override def exitValue() = { try p.waitFor() // wait for the process to terminate @@ -278,7 +278,7 @@ private[process] trait ProcessImpl { finally interrupt() } // we interrupt the input thread to notify it that it can terminate - private[this] def interrupt(): Unit = if (inputThread != null) inputThread.interrupt() + private[this] def interrupt(): Unit = if (inputThread != null) inputThread.nn.interrupt() } private[process] final class ThreadProcess(thread: Thread, success: LinkedBlockingQueue[Boolean]) extends Process { override def isAlive() = thread.isAlive() diff --git a/library/src/scala/util/Properties.scala b/library/src/scala/util/Properties.scala index 364a66caa1e8..aae9358f50ac 100644 --- a/library/src/scala/util/Properties.scala +++ b/library/src/scala/util/Properties.scala @@ -54,11 +54,11 @@ private[scala] trait PropertiesTrait { def propIsSet(name: String) = System.getProperty(name) != null def propIsSetTo(name: String, value: String) = propOrNull(name) == value - def propOrElse(name: String, alt: => String) = Option(System.getProperty(name)).getOrElse(alt) + def propOrElse(name: String, alt: => String | Null) = Option(System.getProperty(name)).getOrElse(alt) def propOrEmpty(name: String) = propOrElse(name, "") - def propOrNull(name: String) = propOrElse(name, null) + def propOrNull(name: String): String | Null = propOrElse(name, null) def propOrNone(name: String) = Option(propOrNull(name)) - def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.toLowerCase) + def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.nn.toLowerCase) def setProp(name: String, value: String) = System.setProperty(name, value) def clearProp(name: String) = System.clearProperty(name) diff --git a/library/src/scala/util/Sorting.scala b/library/src/scala/util/Sorting.scala index b1083664b336..19c8ae111f09 100644 --- a/library/src/scala/util/Sorting.scala +++ b/library/src/scala/util/Sorting.scala @@ -178,11 +178,11 @@ object Sorting { } // Caller is required to pass iN >= i0, else math will fail. Also, i0 >= 0. - private def mergeSort[@specialized T: ClassTag](a: Array[T], i0: Int, iN: Int, ord: Ordering[T], scratch: Array[T] = null): Unit = { + private def mergeSort[@specialized T: ClassTag](a: Array[T], i0: Int, iN: Int, ord: Ordering[T], scratch: Array[T] | Null = null): Unit = { if (iN - i0 < mergeThreshold) insertionSort(a, i0, iN, ord) else { val iK = (i0 + iN) >>> 1 // Bit shift equivalent to unsigned math, no overflow - val sc = if (scratch eq null) new Array[T](iK - i0) else scratch + val sc = if (scratch eq null) new Array[T](iK - i0) else scratch.nn mergeSort(a, i0, iK, ord, sc) mergeSort(a, iK, iN, ord, sc) mergeSorted(a, i0, iK, iN, ord, sc) @@ -234,10 +234,10 @@ object Sorting { // TODO: add upper bound: T <: AnyRef, propagate to callers below (not binary compatible) // Maybe also rename all these methods to `sort`. - @inline private def sort[T](a: Array[T], from: Int, until: Int, ord: Ordering[T]): Unit = (a: @unchecked) match { + @inline private def sort[T](a: Array[T] | Null, from: Int, until: Int, ord: Ordering[T]): Unit = (a: @unchecked) match { case _: Array[AnyRef] => // Note that runtime matches are covariant, so could actually be any Array[T] s.t. T is not primitive (even boxed value classes) - if (a.length > 1 && (ord eq null)) throw new NullPointerException("Ordering") + if (a.nn.length > 1 && (ord eq null)) throw new NullPointerException("Ordering") java.util.Arrays.sort(a, from, until, ord) case a: Array[Int] => if (ord eq Ordering.Int) java.util.Arrays.sort(a, from, until) else mergeSort[Int](a, from, until, ord) case a: Array[Double] => mergeSort[Double](a, from, until, ord) // Because not all NaNs are identical, stability is meaningful! diff --git a/library/src/scala/util/Using.scala b/library/src/scala/util/Using.scala index 90ec6dc71d40..1e02ed615600 100644 --- a/library/src/scala/util/Using.scala +++ b/library/src/scala/util/Using.scala @@ -177,7 +177,8 @@ object Using { import Manager._ private var closed = false - private[this] var resources: List[Resource[_]] = Nil + @annotation.stableNull + private[this] var resources: List[Resource[_]] | Null = Nil /** Registers the specified resource with this manager, so that * the resource is released when the manager is closed, and then @@ -194,11 +195,11 @@ object Using { def acquire[R: Releasable](resource: R): Unit = { if (resource == null) throw new NullPointerException("null resource") if (closed) throw new IllegalStateException("Manager has already been closed") - resources = new Resource(resource) :: resources + resources = new Resource(resource) :: resources.nn } private def manage[A](op: Manager => A): A = { - var toThrow: Throwable = null + var toThrow: Throwable | Null = null try { op(this) } catch { @@ -209,14 +210,14 @@ object Using { closed = true var rs = resources resources = null // allow GC, in case something is holding a reference to `this` - while (rs.nonEmpty) { + while (rs != null && rs.nonEmpty) { val resource = rs.head rs = rs.tail try resource.release() catch { case t: Throwable => if (toThrow == null) toThrow = t - else toThrow = preferentiallySuppress(toThrow, t) + else toThrow = preferentiallySuppress(toThrow.nn, t) } } if (toThrow != null) throw toThrow @@ -292,7 +293,7 @@ object Using { def resource[R, A](resource: R)(body: R => A)(implicit releasable: Releasable[R]): A = { if (resource == null) throw new NullPointerException("null resource") - var toThrow: Throwable = null + var toThrow: Throwable | Null = null try { body(resource) } catch { diff --git a/library/src/scala/util/control/ControlThrowable.scala b/library/src/scala/util/control/ControlThrowable.scala index b3a3bf1006e2..dee0b5dae168 100644 --- a/library/src/scala/util/control/ControlThrowable.scala +++ b/library/src/scala/util/control/ControlThrowable.scala @@ -42,7 +42,7 @@ import scala.language.`2.13` * Instances of `ControlThrowable` should not normally have a cause. * Legacy subclasses may set a cause using `initCause`. */ -abstract class ControlThrowable(message: String) extends Throwable( +abstract class ControlThrowable(message: String | Null) extends Throwable( message, /*cause*/ null, /*enableSuppression=*/ false, /*writableStackTrace*/ false) { def this() = this(message = null) diff --git a/library/src/scala/util/hashing/MurmurHash3.scala b/library/src/scala/util/hashing/MurmurHash3.scala index e828ff771819..a65a0e2c2771 100644 --- a/library/src/scala/util/hashing/MurmurHash3.scala +++ b/library/src/scala/util/hashing/MurmurHash3.scala @@ -83,7 +83,7 @@ private[hashing] class MurmurHash3 { } /** See the [[MurmurHash3.caseClassHash(x:Product,caseClassName:String)]] overload */ - final def caseClassHash(x: Product, seed: Int, caseClassName: String): Int = { + final def caseClassHash(x: Product, seed: Int, caseClassName: String | Null): Int = { val arr = x.productArity val aye = (if (caseClassName != null) caseClassName else x.productPrefix).hashCode if (arr == 0) aye @@ -395,7 +395,7 @@ object MurmurHash3 extends MurmurHash3 { * val res2: Int = -668012062 * }}} */ - def caseClassHash(x: Product, caseClassName: String = null): Int = caseClassHash(x, productSeed, caseClassName) + def caseClassHash(x: Product, caseClassName: String | Null = null): Int = caseClassHash(x, productSeed, caseClassName) private[scala] def arraySeqHash[@specialized T](a: Array[T]): Int = arrayHash(a, seqSeed) private[scala] def tuple2Hash(x: Any, y: Any): Int = tuple2Hash(x.##, y.##, productSeed) diff --git a/library/src/scala/util/matching/Regex.scala b/library/src/scala/util/matching/Regex.scala index 8e86234ebdb8..3fda32432035 100644 --- a/library/src/scala/util/matching/Regex.scala +++ b/library/src/scala/util/matching/Regex.scala @@ -341,7 +341,7 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends def unapplySeq(m: Match): Option[List[String]] = if (m.matched == null) None else if (m.matcher.pattern == this.pattern) Regex.extractGroupsFromMatch(m) - else unapplySeq(m.matched) + else unapplySeq(m.matched.nn) // @see UnanchoredRegex protected def runMatcher(m: Matcher): Boolean = m.matches() @@ -650,45 +650,45 @@ object Regex { def end(i: Int): Int /** The matched string, or `null` if nothing was matched. */ - def matched: String = + def matched: String | Null = if (start >= 0) source.subSequence(start, end).toString else null /** The matched string in group `i`, * or `null` if nothing was matched. */ - def group(i: Int): String = + def group(i: Int): String | Null = if (start(i) >= 0) source.subSequence(start(i), end(i)).toString else null /** All capturing groups, i.e., not including group(0). */ - def subgroups: List[String] = (1 to groupCount).toList map group + def subgroups: List[String | Null] = (1 to groupCount).toList map group /** The char sequence before first character of match, * or `null` if nothing was matched. */ - def before: CharSequence = + def before: CharSequence | Null = if (start >= 0) source.subSequence(0, start) else null /** The char sequence before first character of match in group `i`, * or `null` if nothing was matched for that group. */ - def before(i: Int): CharSequence = + def before(i: Int): CharSequence | Null = if (start(i) >= 0) source.subSequence(0, start(i)) else null /** Returns char sequence after last character of match, * or `null` if nothing was matched. */ - def after: CharSequence = + def after: CharSequence | Null = if (end >= 0) source.subSequence(end, source.length) else null /** The char sequence after last character of match in group `i`, * or `null` if nothing was matched for that group. */ - def after(i: Int): CharSequence = + def after(i: Int): CharSequence | Null = if (end(i) >= 0) source.subSequence(end(i), source.length) else null @@ -708,7 +708,7 @@ object Regex { * @return The requested group * @throws IllegalArgumentException if the requested group name is not defined */ - def group(id: String): String = ( + def group(id: String): String | Null = ( if (groupNamesNowarn.isEmpty) matcher group id else @@ -719,7 +719,7 @@ object Regex { ) /** The matched string; equivalent to `matched.toString`. */ - override def toString: String = matched + override def toString: String = matched.nn } /** Provides information about a successful match. */ @@ -768,7 +768,7 @@ object Regex { * */ object Match { - def unapply(m: Match): Some[String] = Some(m.matched) + def unapply(m: Match): Some[String] = Some(m.matched.nn) } /** An extractor object that yields the groups in the match. Using this extractor @@ -789,7 +789,7 @@ object Regex { } @inline private def extractGroupsFromMatch(m: Match): Option[List[String]] = - Some(List.tabulate(m.groupCount) { i => m.group(i + 1) }) + Some(List.tabulate(m.groupCount) { i => m.group(i + 1).nn }) /** A class to step through a sequence of regex matches. * diff --git a/project/Build.scala b/project/Build.scala index c79bc2522d9c..a0ca95c73783 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1676,7 +1676,8 @@ object Build { // NOTE: The only difference here is that we drop `-Werror` and semanticDB for now Compile / scalacOptions := Seq("-deprecation", "-feature", "-unchecked", "-encoding", "UTF8", "-language:implicitConversions"), Compile / scalacOptions += "-Yno-stdlib-patches", - Compile / scalacOptions ++= Seq( + Compile / scalacOptions += "-Yexplicit-nulls", + (Compile / scalacOptions) ++= Seq( // Needed so that the library sources are visible when `dotty.tools.dotc.core.Definitions#init` is called "-sourcepath", (Compile / sourceDirectories).value.map(_.getCanonicalPath).distinct.mkString(File.pathSeparator), ), @@ -1758,6 +1759,7 @@ object Build { // NOTE: The only difference here is that we drop `-Werror` and semanticDB for now Compile / scalacOptions := Seq("-deprecation", "-feature", "-unchecked", "-encoding", "UTF8", "-language:implicitConversions"), Compile / scalacOptions += "-Yno-stdlib-patches", + Compile / scalacOptions += "-Yexplicit-nulls", Compile / scalacOptions ++= Seq( // Needed so that the library sources are visible when `dotty.tools.dotc.core.Definitions#init` is called "-sourcepath", (Compile / sourceDirectories).value.map(_.getCanonicalPath).distinct.mkString(File.pathSeparator),