From 9fd71cb0f474307d1c958c622538c9316f859f7f Mon Sep 17 00:00:00 2001 From: Hamza Remmal Date: Fri, 18 Jul 2025 20:18:11 +0100 Subject: [PATCH 01/46] chore: enable explicit-nulls in the stdlib --- project/Build.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 1222613de823..91cc669e2c38 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1796,7 +1796,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), ), @@ -1890,6 +1891,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), From 6f7c217cd529afc5d2c4dc14dcef712a39595758 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 26 Aug 2025 16:16:40 +0200 Subject: [PATCH 02/46] Port stdlib to explicit nulls --- library/src/scala/Enumeration.scala | 12 +- library/src/scala/Predef.scala | 28 +- library/src/scala/Specializable.scala | 22 +- library/src/scala/collection/Iterator.scala | 66 +-- .../src/scala/collection/JavaConverters.scala | 107 +++-- library/src/scala/collection/LazyZipOps.scala | 6 +- library/src/scala/collection/Stepper.scala | 38 +- library/src/scala/collection/View.scala | 6 +- .../scala/collection/concurrent/TrieMap.scala | 1 + .../collection/convert/AsJavaConverters.scala | 52 +-- .../collection/convert/AsJavaExtensions.scala | 46 +- .../convert/AsScalaConverters.scala | 48 +- .../convert/AsScalaExtensions.scala | 40 +- .../convert/ImplicitConversions.scala | 46 +- .../convert/JavaCollectionWrappers.scala | 14 +- .../collection/convert/StreamExtensions.scala | 14 +- .../convert/impl/BinaryTreeStepper.scala | 18 +- .../convert/impl/BitSetStepper.scala | 16 +- .../convert/impl/ChampStepper.scala | 18 +- .../convert/impl/IteratorStepper.scala | 54 +-- .../convert/impl/StringStepper.scala | 2 +- .../convert/impl/TableStepper.scala | 10 +- .../convert/impl/VectorStepper.scala | 10 +- .../scala/collection/immutable/ArraySeq.scala | 10 +- .../scala/collection/immutable/HashMap.scala | 47 +- .../scala/collection/immutable/HashSet.scala | 13 +- .../scala/collection/immutable/LazyList.scala | 14 +- .../immutable/LazyListIterable.scala | 6 +- .../src/scala/collection/immutable/List.scala | 28 +- .../scala/collection/immutable/ListMap.scala | 18 +- .../collection/immutable/RedBlackTree.scala | 1 + .../scala/collection/immutable/Stream.scala | 8 +- .../scala/collection/immutable/TreeMap.scala | 1 + .../collection/immutable/TreeSeqMap.scala | 15 +- .../scala/collection/immutable/TreeSet.scala | 2 +- .../scala/collection/immutable/Vector.scala | 271 ++++++----- .../collection/immutable/VectorMap.scala | 3 +- .../scala/collection/mutable/AnyRefMap.scala | 144 +++--- .../collection/mutable/ArrayBuilder.scala | 22 +- .../scala/collection/mutable/ArrayDeque.scala | 12 +- .../src/scala/collection/mutable/BitSet.scala | 6 +- .../mutable/CollisionProofHashMap.scala | 1 + .../scala/collection/mutable/HashMap.scala | 20 +- .../scala/collection/mutable/HashSet.scala | 14 +- .../scala/collection/mutable/HashTable.scala | 57 +-- .../scala/collection/mutable/IndexedSeq.scala | 2 +- .../collection/mutable/LinkedHashMap.scala | 82 ++-- .../collection/mutable/LinkedHashSet.scala | 58 +-- .../scala/collection/mutable/ListBuffer.scala | 43 +- .../scala/collection/mutable/LongMap.scala | 145 +++--- .../collection/mutable/PriorityQueue.scala | 8 +- .../src/scala/collection/mutable/Queue.scala | 4 +- .../collection/mutable/RedBlackTree.scala | 1 + .../src/scala/collection/mutable/Stack.scala | 2 +- .../collection/mutable/UnrolledBuffer.scala | 54 +-- .../scala/concurrent/BatchingExecutor.scala | 26 +- .../scala/concurrent/ExecutionContext.scala | 14 +- .../scala/concurrent/JavaConversions.scala | 4 +- .../impl/ExecutionContextImpl.scala | 4 +- .../src/scala/concurrent/impl/Promise.scala | 42 +- library/src/scala/io/BufferedSource.scala | 6 +- library/src/scala/io/Codec.scala | 20 +- library/src/scala/io/Source.scala | 18 +- library/src/scala/jdk/AnyAccumulator.scala | 2 +- library/src/scala/jdk/DoubleAccumulator.scala | 2 +- .../src/scala/jdk/FunctionExtensions.scala | 176 ++++---- library/src/scala/jdk/FunctionWrappers.scala | 426 +++++++++--------- library/src/scala/jdk/IntAccumulator.scala | 2 +- library/src/scala/jdk/LongAccumulator.scala | 2 +- library/src/scala/math/BigDecimal.scala | 2 +- library/src/scala/math/BigInt.scala | 20 +- library/src/scala/ref/ReferenceQueue.scala | 2 +- library/src/scala/ref/SoftReference.scala | 4 +- library/src/scala/ref/WeakReference.scala | 6 +- .../reflect/ClassManifestDeprecatedApis.scala | 2 +- .../src/scala/reflect/NameTransformer.scala | 20 +- .../scala/runtime/LambdaDeserializer.scala | 4 +- library/src/scala/runtime/MethodCache.scala | 10 +- library/src/scala/runtime/ScalaRunTime.scala | 10 +- .../scala/runtime/StructuralCallSite.scala | 2 +- library/src/scala/sys/PropImpl.scala | 4 +- library/src/scala/sys/SystemProperties.scala | 5 +- .../sys/process/ProcessBuilderImpl.scala | 2 +- .../src/scala/sys/process/ProcessImpl.scala | 4 +- library/src/scala/util/Properties.scala | 6 +- library/src/scala/util/Sorting.scala | 6 +- library/src/scala/util/Using.scala | 13 +- .../scala/util/control/ControlThrowable.scala | 2 +- .../src/scala/util/hashing/MurmurHash3.scala | 4 +- library/src/scala/util/matching/Regex.scala | 20 +- 90 files changed, 1350 insertions(+), 1328 deletions(-) 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/Predef.scala b/library/src/scala/Predef.scala index 552a491470ae..e613f47b9ea1 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. @@ -657,7 +657,7 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2 @inline implicit def booleanWrapper(x: Boolean): runtime.RichBoolean = new runtime.RichBoolean(x) /** @group conversions-array-to-wrapped-array */ - implicit def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = + implicit def genericWrapArray[T](xs: Array[T] | Null): ArraySeq[T] | Null = if (xs eq null) null else ArraySeq.make(xs) @@ -665,38 +665,38 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2 // is as good as another for all T <: AnyRef. Instead of creating 100,000,000 // unique ones by way of this implicit, let's share one. /** @group conversions-array-to-wrapped-array */ - implicit def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq.ofRef[T] = { + implicit def wrapRefArray[T <: AnyRef](xs: Array[T] | Null): ArraySeq.ofRef[T] | Null = { if (xs eq null) null else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]] else new ArraySeq.ofRef[T](xs) } /** @group conversions-array-to-wrapped-array */ - implicit def wrapIntArray(xs: Array[Int]): ArraySeq.ofInt = if (xs ne null) new ArraySeq.ofInt(xs) else null + implicit def wrapIntArray(xs: Array[Int] | Null): ArraySeq.ofInt | Null = if (xs ne null) new ArraySeq.ofInt(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapDoubleArray(xs: Array[Double]): ArraySeq.ofDouble = if (xs ne null) new ArraySeq.ofDouble(xs) else null + implicit def wrapDoubleArray(xs: Array[Double] | Null): ArraySeq.ofDouble | Null = if (xs ne null) new ArraySeq.ofDouble(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapLongArray(xs: Array[Long]): ArraySeq.ofLong = if (xs ne null) new ArraySeq.ofLong(xs) else null + implicit def wrapLongArray(xs: Array[Long] | Null): ArraySeq.ofLong | Null = if (xs ne null) new ArraySeq.ofLong(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapFloatArray(xs: Array[Float]): ArraySeq.ofFloat = if (xs ne null) new ArraySeq.ofFloat(xs) else null + implicit def wrapFloatArray(xs: Array[Float] | Null): ArraySeq.ofFloat | Null = if (xs ne null) new ArraySeq.ofFloat(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapCharArray(xs: Array[Char]): ArraySeq.ofChar = if (xs ne null) new ArraySeq.ofChar(xs) else null + implicit def wrapCharArray(xs: Array[Char] | Null): ArraySeq.ofChar | Null = if (xs ne null) new ArraySeq.ofChar(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapByteArray(xs: Array[Byte]): ArraySeq.ofByte = if (xs ne null) new ArraySeq.ofByte(xs) else null + implicit def wrapByteArray(xs: Array[Byte] | Null): ArraySeq.ofByte | Null = if (xs ne null) new ArraySeq.ofByte(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapShortArray(xs: Array[Short]): ArraySeq.ofShort = if (xs ne null) new ArraySeq.ofShort(xs) else null + implicit def wrapShortArray(xs: Array[Short] | Null): ArraySeq.ofShort | Null = if (xs ne null) new ArraySeq.ofShort(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapBooleanArray(xs: Array[Boolean]): ArraySeq.ofBoolean = if (xs ne null) new ArraySeq.ofBoolean(xs) else null + implicit def wrapBooleanArray(xs: Array[Boolean] | Null): ArraySeq.ofBoolean | Null = if (xs ne null) new ArraySeq.ofBoolean(xs) else null /** @group conversions-array-to-wrapped-array */ - implicit def wrapUnitArray(xs: Array[Unit]): ArraySeq.ofUnit = if (xs ne null) new ArraySeq.ofUnit(xs) else null + implicit def wrapUnitArray(xs: Array[Unit] | Null): ArraySeq.ofUnit | Null = if (xs ne null) new ArraySeq.ofUnit(xs) else null /** @group conversions-string */ - implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null + implicit def wrapString(s: String | Null): WrappedString | Null = if (s ne null) new WrappedString(s) else null } private[scala] abstract class LowPriorityImplicits2 { @deprecated("implicit conversions from Array to immutable.IndexedSeq are implemented by copying; use `toIndexedSeq` explicitly if you want to copy, or use the more efficient non-copying ArraySeq.unsafeWrapArray", since="2.13.0") - implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T]): IndexedSeq[T] = + implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T] | Null): IndexedSeq[T] | Null = if (xs eq null) null else new ArrayOps(xs).toIndexedSeq } 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/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 4ddef7dcb18f..9ab7cb787027 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -124,7 +124,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() @@ -161,12 +160,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] @@ -189,7 +188,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 @@ -230,7 +229,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 @@ -251,7 +250,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 } } @@ -275,11 +274,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 @@ -702,7 +701,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 @@ -713,10 +712,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) { @@ -730,7 +729,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() } @@ -757,7 +756,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 @@ -772,13 +771,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 { @@ -873,7 +872,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 @@ -1149,10 +1148,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 = @@ -1171,7 +1173,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() @@ -1186,9 +1188,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) { @@ -1203,7 +1205,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} = { @@ -1213,7 +1215,7 @@ object Iterator extends IterableFactory[Iterator] { last = c } else { - last.tail = c + last.nn.tail = c last = c } if (current == null) current = Iterator.empty @@ -1221,7 +1223,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 } @@ -1289,7 +1291,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) { @@ -1300,12 +1302,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 5849de61448b..7e2e6a5ed66f 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/Stepper.scala b/library/src/scala/collection/Stepper.scala index 7685c2304c7c..d3f8c0d84518 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 78a3f49b1f24..56a63fe97529 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -452,7 +452,8 @@ 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 @@ -507,7 +508,8 @@ 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) { 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 28b762b425f0..c132962ce97f 100644 --- a/library/src/scala/collection/convert/StreamExtensions.scala +++ b/library/src/scala/collection/convert/StreamExtensions.scala @@ -272,7 +272,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 @@ -450,31 +450,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/BinaryTreeStepper.scala b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala index 87823ced9cee..830646f43bb7 100644 --- a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala +++ b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala @@ -45,7 +45,7 @@ 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, _, _]]( +private[collection] abstract class BinaryTreeStepperBase[A, T >: Null <: AnyRef | Null, 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, protected val left: T => T, protected val right: T => T ) @@ -126,7 +126,7 @@ extends EfficientSplit { 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 @@ -160,7 +160,7 @@ with AnyStepper[A] { 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 >: Null <: AnyRef | Null](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,7 +168,7 @@ private[collection] object AnyBinaryTreeStepper { } -private[collection] final class DoubleBinaryTreeStepper[T >: Null <: AnyRef]( +private[collection] final class DoubleBinaryTreeStepper[T >: Null <: AnyRef | Null]( _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _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) @@ -186,7 +186,7 @@ with DoubleStepper { 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 >: Null <: AnyRef | Null](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,7 +194,7 @@ private [collection] object DoubleBinaryTreeStepper { } -private[collection] final class IntBinaryTreeStepper[T >: Null <: AnyRef]( +private[collection] final class IntBinaryTreeStepper[T >: Null <: AnyRef | Null]( _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _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) @@ -212,7 +212,7 @@ with IntStepper { 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 >: Null <: AnyRef | Null](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,7 +221,7 @@ private [collection] object IntBinaryTreeStepper { -private[collection] final class LongBinaryTreeStepper[T >: Null <: AnyRef]( +private[collection] final class LongBinaryTreeStepper[T >: Null <: AnyRef | Null]( _maxLength: Int, _myCurrent: T, _stack: Array[AnyRef], _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) @@ -239,7 +239,7 @@ with LongStepper { 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 >: Null <: AnyRef | Null](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..94908c5dc7dc 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] | Null, Sub >: Null, Semi <: Sub with ChampStepperBase[A, T, _, _] ](protected var maxSize: Int) extends EfficientSplit { import Node.MaxDepth @@ -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 >: Null <: Node[T] | Null](_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 >: Null <: Node[T] | Null](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 >: Null <: Node[T] | Null](_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 >: Null <: Node[T] | Null](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 >: Null <: Node[T] | Null](_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 >: Null <: Node[T] | Null](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 >: Null <: Node[T] | Null](_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 >: Null <: Node[T] | Null](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/IteratorStepper.scala b/library/src/scala/collection/convert/impl/IteratorStepper.scala index 9f8aab9c2165..8ccf95bd439e 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,11 @@ 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 >: Null <: Stepper[A] | Null, Semi <: SP](final protected val underlying: Iterator[A] | Null) { final protected var nextChunkSize = 16 final protected var proxied: SP = 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/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..1fd4c7860dd5 100644 --- a/library/src/scala/collection/convert/impl/TableStepper.scala +++ b/library/src/scala/collection/convert/impl/TableStepper.scala @@ -17,7 +17,7 @@ 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 >: Null <: AnyRef | Null, Sub >: Null, 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 { @@ -70,7 +70,7 @@ extends EfficientSplit { } -private[collection] final class AnyTableStepper[A, I >: Null <: AnyRef]( +private[collection] final class AnyTableStepper[A, I >: Null <: AnyRef | Null]( _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) @@ -87,7 +87,7 @@ with AnyStepper[A] { } -private[collection] final class DoubleTableStepper[I >: Null <: AnyRef]( +private[collection] final class DoubleTableStepper[I >: Null <: AnyRef | Null]( _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) @@ -104,7 +104,7 @@ with DoubleStepper { } -private[collection] final class IntTableStepper[I >: Null <: AnyRef]( +private[collection] final class IntTableStepper[I >: Null <: AnyRef | Null]( _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) @@ -121,7 +121,7 @@ with IntStepper { } -private[collection] final class LongTableStepper[I >: Null <: AnyRef]( +private[collection] final class LongTableStepper[I >: Null <: AnyRef | Null]( _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) diff --git a/library/src/scala/collection/convert/impl/VectorStepper.scala b/library/src/scala/collection/convert/impl/VectorStepper.scala index 85f349922f48..6485c49c8de9 100644 --- a/library/src/scala/collection/convert/impl/VectorStepper.scala +++ b/library/src/scala/collection/convert/impl/VectorStepper.scala @@ -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 d3e21515b95e..81d172a90d44 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) diff --git a/library/src/scala/collection/immutable/HashMap.scala b/library/src/scala/collection/immutable/HashMap.scala index 63f8b8a97006..787715ef97f3 100644 --- a/library/src/scala/collection/immutable/HashMap.scala +++ b/library/src/scala/collection/immutable/HashMap.scala @@ -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 @@ -1720,7 +1720,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 @@ -1730,7 +1730,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 @@ -1770,18 +1770,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 @@ -1828,14 +1828,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) { @@ -2010,16 +2010,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()) @@ -2033,7 +2033,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 @@ -2206,7 +2206,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() @@ -2231,7 +2231,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 @@ -2338,11 +2339,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..07e95a4b52e1 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 @@ -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]] = _ var newDataMap = 0 var newNodeMap = 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..745d2cc3c3f2 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,7 +1134,7 @@ 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) { diff --git a/library/src/scala/collection/immutable/List.scala b/library/src/scala/collection/immutable/List.scala index 66c2ce524f3e..8265c5c4caa2 100644 --- a/library/src/scala/collection/immutable/List.scala +++ b/library/src/scala/collection/immutable/List.scala @@ -254,16 +254,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) @@ -275,14 +275,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) { @@ -290,7 +290,7 @@ sealed abstract class List[+A] if (t eq null) { h = nx } else { - t.next = nx + t.nn.next = nx } t = nx } @@ -453,12 +453,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 { @@ -469,18 +469,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..ec3543a1bc70 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 } diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 973c64826993..b2b68dbcf57b 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 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..5607b81b0c75 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -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) diff --git a/library/src/scala/collection/immutable/Vector.scala b/library/src/scala/collection/immutable/Vector.scala index 78768577b99b..31ab1125b9b8 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 protected[immutable] def vectorSlicePrefixLength(idx: Int): Int = 0 override def equals(o: Any): Boolean = { @@ -1153,7 +1153,7 @@ private final class Vector6[+A](_prefix1: Arr1, private[immutable] val len1: Int ) } - override protected[this] def appendedAll0[B >: A](suffix: collection.IterableOnce[B]^, k: Int): Vector[B] = { + override protected[this] def appendedAll0[B >: A](suffix: collection.IterableOnce[B], k: Int): Vector[B] = { val suffix1b = append1IfSpace(suffix1, suffix) if(suffix1b ne null) copy(suffix1 = suffix1b, length0 = length0-suffix1.length+suffix1b.length) else super.appendedAll0(suffix, k) @@ -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,17 +1393,17 @@ 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 } final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { - private[this] var a6: Arr6 = _ - private[this] var a5: Arr5 = _ - private[this] var a4: Arr4 = _ - private[this] var a3: Arr3 = _ - private[this] var a2: Arr2 = _ + @annotation.stableNull private[this] var a6: Arr6 | Null = _ + @annotation.stableNull private[this] var a5: Arr5 | Null = _ + @annotation.stableNull private[this] var a4: Arr4 | Null = _ + @annotation.stableNull private[this] var a3: Arr3 | Null = _ + @annotation.stableNull private[this] var a2: Arr2 | Null = _ private[this] var a1: Arr1 = new Arr1(WIDTH) private[this] var len1, lenRest, offset = 0 private[this] var prefixIsRightAligned = false @@ -1487,9 +1487,9 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH - v2.len1 setLen(v2.length0 + offset) a2 = new Arr2(WIDTH) - a2(0) = v2.prefix1 + a2.nn(0) = v2.prefix1 System.arraycopy(d2, 0, a2, 1, d2.length) - a2(d2.length+1) = a1 + a2.nn(d2.length+1) = a1.nn case 5 => val v3 = v.asInstanceOf[Vector3[_]] val d3 = v3.data3 @@ -1499,11 +1499,11 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH2 - v3.len12 setLen(v3.length0 + offset) a3 = new Arr3(WIDTH) - a3(0) = copyPrepend(v3.prefix1, v3.prefix2) + a3.nn(0) = copyPrepend(v3.prefix1, v3.prefix2) System.arraycopy(d3, 0, a3, 1, d3.length) a2 = copyOf(s2, WIDTH) - a3(d3.length+1) = a2 - a2(s2.length) = a1 + a3.nn(d3.length+1) = a2.nn + a2.nn(s2.length) = a1.nn case 7 => val v4 = v.asInstanceOf[Vector4[_]] val d4 = v4.data4 @@ -1514,13 +1514,13 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH3 - v4.len123 setLen(v4.length0 + offset) a4 = new Arr4(WIDTH) - a4(0) = copyPrepend(copyPrepend(v4.prefix1, v4.prefix2), v4.prefix3) + a4.nn(0) = copyPrepend(copyPrepend(v4.prefix1, v4.prefix2), v4.prefix3) System.arraycopy(d4, 0, a4, 1, d4.length) a3 = copyOf(s3, WIDTH) a2 = copyOf(s2, WIDTH) - a4(d4.length+1) = a3 - a3(s3.length) = a2 - a2(s2.length) = a1 + a4.nn(d4.length+1) = a3.nn + a3.nn(s3.length) = a2.nn + a2.nn(s2.length) = a1.nn case 9 => val v5 = v.asInstanceOf[Vector5[_]] val d5 = v5.data5 @@ -1532,15 +1532,15 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH4 - v5.len1234 setLen(v5.length0 + offset) a5 = new Arr5(WIDTH) - a5(0) = copyPrepend(copyPrepend(copyPrepend(v5.prefix1, v5.prefix2), v5.prefix3), v5.prefix4) + a5.nn(0) = copyPrepend(copyPrepend(copyPrepend(v5.prefix1, v5.prefix2), v5.prefix3), v5.prefix4) System.arraycopy(d5, 0, a5, 1, d5.length) a4 = copyOf(s4, WIDTH) a3 = copyOf(s3, WIDTH) a2 = copyOf(s2, WIDTH) - a5(d5.length+1) = a4 - a4(s4.length) = a3 - a3(s3.length) = a2 - a2(s2.length) = a1 + a5.nn(d5.length+1) = a4.nn + a4.nn(s4.length) = a3.nn + a3.nn(s3.length) = a2.nn + a2.nn(s2.length) = a1.nn case 11 => val v6 = v.asInstanceOf[Vector6[_]] val d6 = v6.data6 @@ -1553,17 +1553,17 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH5 - v6.len12345 setLen(v6.length0 + offset) a6 = new Arr6(LASTWIDTH) - a6(0) = copyPrepend(copyPrepend(copyPrepend(copyPrepend(v6.prefix1, v6.prefix2), v6.prefix3), v6.prefix4), v6.prefix5) + a6.nn(0) = copyPrepend(copyPrepend(copyPrepend(copyPrepend(v6.prefix1, v6.prefix2), v6.prefix3), v6.prefix4), v6.prefix5) System.arraycopy(d6, 0, a6, 1, d6.length) a5 = copyOf(s5, WIDTH) a4 = copyOf(s4, WIDTH) a3 = copyOf(s3, WIDTH) a2 = copyOf(s2, WIDTH) - a6(d6.length+1) = a5 - a5(s5.length) = a4 - a4(s4.length) = a3 - a3(s3.length) = a2 - a2(s2.length) = a1 + a6.nn(d6.length+1) = a5.nn + a5.nn(s5.length) = a4.nn + a4.nn(s4.length) = a3.nn + a3.nn(s3.length) = a2.nn + a2.nn(s2.length) = a1.nn } if(len1 == 0 && lenRest > 0) { // force advance() on next addition: @@ -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 = null // the array we modify + var aParent: Array[AnyRef] | Null = null // a's parent, so aParent(0) == a if (depth >= 6) { a = a6.asInstanceOf[Array[AnyRef]] val i = offset >>> BITS5 @@ -1623,7 +1623,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { shrinkOffsetIfToLarge(WIDTH5) if ((lenRest >>> BITS5) == 0) depth = 5 aParent = a - a = a(0).asInstanceOf[Array[AnyRef]] + a = a.nn(0).asInstanceOf[Array[AnyRef]] } if (depth >= 5) { if (a == null) a = a5.asInstanceOf[Array[AnyRef]] @@ -1635,10 +1635,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS4) == 0) depth = 4 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent(0) = a + aParent.nn(0) = a.nn } aParent = a - a = a(0).asInstanceOf[Array[AnyRef]] + a = a.nn(0).asInstanceOf[Array[AnyRef]] } if (depth >= 4) { if (a == null) a = a4.asInstanceOf[Array[AnyRef]] @@ -1650,10 +1650,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS3) == 0) depth = 3 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent(0) = a + aParent.nn(0) = a.nn } aParent = a - a = a(0).asInstanceOf[Array[AnyRef]] + a = a.nn(0).asInstanceOf[Array[AnyRef]] } if (depth >= 3) { if (a == null) a = a3.asInstanceOf[Array[AnyRef]] @@ -1665,10 +1665,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS2) == 0) depth = 2 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent(0) = a + aParent.nn(0) = a.nn } aParent = a - a = a(0).asInstanceOf[Array[AnyRef]] + a = a.nn(0).asInstanceOf[Array[AnyRef]] } if (depth >= 2) { if (a == null) a = a2.asInstanceOf[Array[AnyRef]] @@ -1680,10 +1680,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS) == 0) depth = 1 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent(0) = a + aParent.nn(0) = a.nn } aParent = a - a = a(0).asInstanceOf[Array[AnyRef]] + a = a.nn(0).asInstanceOf[Array[AnyRef]] } if (depth >= 1) { if (a == null) a = a1.asInstanceOf[Array[AnyRef]] @@ -1695,7 +1695,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = 0 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent(0) = a + aParent.nn(0) = a.nn } } prefixIsRightAligned = false @@ -1703,7 +1703,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { def addOne(elem: A): this.type = { if(len1 == WIDTH) advance() - a1(len1) = elem.asInstanceOf[AnyRef] + a1.nn(len1) = elem.asInstanceOf[AnyRef] len1 += 1 this } @@ -1849,45 +1849,45 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if (xor <= 0) { // level = 6 or something very unexpected happened throw new IllegalArgumentException(s"advance1($idx, $xor): a1=$a1, a2=$a2, a3=$a3, a4=$a4, a5=$a5, a6=$a6, depth=$depth") } else if (xor < WIDTH2) { // level = 1 - if (depth <= 1) { a2 = new Array(WIDTH); a2(0) = a1; depth = 2 } + if (depth <= 1) { a2 = new Array(WIDTH); a2.nn(0) = a1; depth = 2 } a1 = new Array(WIDTH) - a2((idx >>> BITS) & MASK) = a1 + a2.nn((idx >>> BITS) & MASK) = a1 } else if (xor < WIDTH3) { // level = 2 - if (depth <= 2) { a3 = new Array(WIDTH); a3(0) = a2; depth = 3 } + if (depth <= 2) { a3 = new Array(WIDTH); a3.nn(0) = a2.nn; depth = 3 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) - a2((idx >>> BITS) & MASK) = a1 - a3((idx >>> BITS2) & MASK) = a2 + a2.nn((idx >>> BITS) & MASK) = a1 + a3.nn((idx >>> BITS2) & MASK) = a2 } else if (xor < WIDTH4) { // level = 3 - if (depth <= 3) { a4 = new Array(WIDTH); a4(0) = a3; depth = 4 } + if (depth <= 3) { a4 = new Array(WIDTH); a4.nn(0) = a3.nn; depth = 4 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) a3 = new Array(WIDTH) - a2((idx >>> BITS) & MASK) = a1 - a3((idx >>> BITS2) & MASK) = a2 - a4((idx >>> BITS3) & MASK) = a3 - } else if (xor < WIDTH5) { // level = 4 - if (depth <= 4) { a5 = new Array(WIDTH); a5(0) = a4; depth = 5 } + a2.nn((idx >>> BITS) & MASK) = a1.nn + a3.nn((idx >>> BITS2) & MASK) = a2.nn + a4.nn((idx >>> BITS3) & MASK) = a3.nn + } else if (xor < WIDTH5) { + if (depth <= 4) { a5 = new Array(WIDTH); a5.nn(0) = a4.nn; depth = 5 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) a3 = new Array(WIDTH) a4 = new Array(WIDTH) - a2((idx >>> BITS) & MASK) = a1 - a3((idx >>> BITS2) & MASK) = a2 - a4((idx >>> BITS3) & MASK) = a3 - a5((idx >>> BITS4) & MASK) = a4 - } else { // level = 5 - if (depth <= 5) { a6 = new Array(LASTWIDTH); a6(0) = a5; depth = 6 } + a2.nn((idx >>> BITS) & MASK) = a1.nn + a3.nn((idx >>> BITS2) & MASK) = a2.nn + a4.nn((idx >>> BITS3) & MASK) = a3.nn + a5.nn((idx >>> BITS4) & MASK) = a4.nn + } else { + if (depth <= 5) { a6 = new Array(LASTWIDTH); a6.nn(0) = a5.nn; depth = 6 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) a3 = new Array(WIDTH) a4 = new Array(WIDTH) a5 = new Array(WIDTH) - a2((idx >>> BITS) & MASK) = a1 - a3((idx >>> BITS2) & MASK) = a2 - a4((idx >>> BITS3) & MASK) = a3 - a5((idx >>> BITS4) & MASK) = a4 - a6(idx >>> BITS5) = a5 + a2.nn((idx >>> BITS) & MASK) = a1.nn + a3.nn((idx >>> BITS2) & MASK) = a2.nn + a4.nn((idx >>> BITS3) & MASK) = a3.nn + a5.nn((idx >>> BITS4) & MASK) = a4.nn + a6.nn(idx >>> BITS5) = a5.nn } } @@ -1903,18 +1903,18 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i1 = (len-1) & MASK val i2 = (len-1) >>> BITS val data = copyOfRange(a2, 1, i2) - val prefix1 = a2(0) - val suffix1 = copyIfDifferentSize(a2(i2), i1+1) + val prefix1 = a2.nn(0) + val suffix1 = copyIfDifferentSize(a2.nn(i2), i1+1) new Vector2(prefix1, WIDTH-offset, data, suffix1, realLen) } else if(len <= WIDTH3) { val i1 = (len-1) & MASK val i2 = ((len-1) >>> BITS) & MASK val i3 = ((len-1) >>> BITS2) val data = copyOfRange(a3, 1, i3) - val prefix2 = copyTail(a3(0)) - val prefix1 = a3(0)(0) - val suffix2 = copyOf(a3(i3), i2) - val suffix1 = copyIfDifferentSize(a3(i3)(i2), i1+1) + val prefix2 = copyTail(a3.nn(0)) + val prefix1 = a3.nn(0).nn(0) + val suffix2 = copyOf(a3.nn(i3), i2) + val suffix1 = copyIfDifferentSize(a3.nn(i3).nn(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH new Vector3(prefix1, len1, prefix2, len12, data, suffix2, suffix1, realLen) @@ -1924,12 +1924,12 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i3 = ((len-1) >>> BITS2) & MASK val i4 = ((len-1) >>> BITS3) val data = copyOfRange(a4, 1, i4) - val prefix3 = copyTail(a4(0)) - val prefix2 = copyTail(a4(0)(0)) - val prefix1 = a4(0)(0)(0) - val suffix3 = copyOf(a4(i4), i3) - val suffix2 = copyOf(a4(i4)(i3), i2) - val suffix1 = copyIfDifferentSize(a4(i4)(i3)(i2), i1+1) + val prefix3 = copyTail(a4.nn(0)) + val prefix2 = copyTail(a4.nn(0).nn(0)) + val prefix1 = a4.nn(0).nn(0).nn(0) + val suffix3 = copyOf(a4.nn(i4), i3) + val suffix2 = copyOf(a4.nn(i4).nn(i3), i2) + val suffix1 = copyIfDifferentSize(a4.nn(i4).nn(i3).nn(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH val len123 = len12 + prefix3.length*WIDTH2 @@ -1941,14 +1941,14 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i4 = ((len-1) >>> BITS3) & MASK val i5 = ((len-1) >>> BITS4) val data = copyOfRange(a5, 1, i5) - val prefix4 = copyTail(a5(0)) - val prefix3 = copyTail(a5(0)(0)) - val prefix2 = copyTail(a5(0)(0)(0)) - val prefix1 = a5(0)(0)(0)(0) - val suffix4 = copyOf(a5(i5), i4) - val suffix3 = copyOf(a5(i5)(i4), i3) - val suffix2 = copyOf(a5(i5)(i4)(i3), i2) - val suffix1 = copyIfDifferentSize(a5(i5)(i4)(i3)(i2), i1+1) + val prefix4 = copyTail(a5.nn(0)) + val prefix3 = copyTail(a5.nn(0).nn(0)) + val prefix2 = copyTail(a5.nn(0).nn(0).nn(0)) + val prefix1 = a5.nn(0).nn(0).nn(0).nn(0) + val suffix4 = copyOf(a5.nn(i5), i4) + val suffix3 = copyOf(a5.nn(i5).nn(i4), i3) + val suffix2 = copyOf(a5.nn(i5).nn(i4).nn(i3), i2) + val suffix1 = copyIfDifferentSize(a5.nn(i5).nn(i4).nn(i3).nn(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH val len123 = len12 + prefix3.length*WIDTH2 @@ -1962,16 +1962,15 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i5 = ((len-1) >>> BITS4) & MASK val i6 = ((len-1) >>> BITS5) val data = copyOfRange(a6, 1, i6) - val prefix5 = copyTail(a6(0)) - val prefix4 = copyTail(a6(0)(0)) - val prefix3 = copyTail(a6(0)(0)(0)) - val prefix2 = copyTail(a6(0)(0)(0)(0)) - val prefix1 = a6(0)(0)(0)(0)(0) - val suffix5 = copyOf(a6(i6), i5) - val suffix4 = copyOf(a6(i6)(i5), i4) - val suffix3 = copyOf(a6(i6)(i5)(i4), i3) - val suffix2 = copyOf(a6(i6)(i5)(i4)(i3), i2) - val suffix1 = copyIfDifferentSize(a6(i6)(i5)(i4)(i3)(i2), i1+1) + val prefix5 = copyTail(a6.nn(0)) + val prefix4 = copyTail(a6.nn(0).nn(0)) + val prefix3 = copyTail(a6.nn(0).nn(0).nn(0)) + val prefix2 = copyTail(a6.nn(0).nn(0).nn(0).nn(0)) + val suffix5 = copyOf(a6.nn(i6), i5) + val suffix4 = copyOf(a6.nn(i6).nn(i5), i4) + val suffix3 = copyOf(a6.nn(i6).nn(i5).nn(i4), i3) + val suffix2 = copyOf(a6.nn(i6).nn(i5).nn(i4).nn(i3), i2) + val suffix1 = copyIfDifferentSize(a6.nn(i6).nn(i5).nn(i4).nn(i3).nn(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH val len123 = len12 + prefix3.length*WIDTH2 @@ -2189,7 +2188,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 +2213,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 { @@ -2242,11 +2241,11 @@ private object VectorStatics { private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLength: Int, private[this] val sliceCount: Int) extends AbstractIterator[A] with java.lang.Cloneable { private[this] var a1: Arr1 = v.prefix1 - private[this] var a2: Arr2 = _ - private[this] var a3: Arr3 = _ - private[this] var a4: Arr4 = _ - private[this] var a5: Arr5 = _ - private[this] var a6: Arr6 = _ + @annotation.stableNull private[this] var a2: Arr2 | Null = _ + @annotation.stableNull private[this] var a3: Arr3 | Null = _ + @annotation.stableNull private[this] var a4: Arr4 | Null = _ + @annotation.stableNull private[this] var a5: Arr5 | Null = _ + @annotation.stableNull private[this] var a6: Arr6 | Null = _ private[this] var a1len = a1.length private[this] var i1 = 0 // current index in a1 private[this] var oldPos = 0 @@ -2310,49 +2309,49 @@ private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLe private[this] def advanceA(io: Int, xor: Int): Unit = { if(xor < WIDTH2) { - a1 = a2((io >>> BITS) & MASK) + a1 = a2.nn((io >>> BITS) & MASK) } else if(xor < WIDTH3) { - a2 = a3((io >>> BITS2) & MASK) - a1 = a2(0) + a2 = a3.nn((io >>> BITS2) & MASK) + a1 = a2.nn(0) } else if(xor < WIDTH4) { - a3 = a4((io >>> BITS3) & MASK) - a2 = a3(0) - a1 = a2(0) + a3 = a4.nn((io >>> BITS3) & MASK) + a2 = a3.nn(0) + a1 = a2.nn(0) } else if(xor < WIDTH5) { - a4 = a5((io >>> BITS4) & MASK) - a3 = a4(0) - a2 = a3(0) - a1 = a2(0) + a4 = a5.nn((io >>> BITS4) & MASK) + a3 = a4.nn(0) + a2 = a3.nn(0) + a1 = a2.nn(0) } else { - a5 = a6(io >>> BITS5) - a4 = a5(0) - a3 = a4(0) - a2 = a3(0) - a1 = a2(0) + a5 = a6.nn(io >>> BITS5) + a4 = a5.nn(0) + a3 = a4.nn(0) + a2 = a3.nn(0) + a1 = a2.nn(0) } } private[this] def setA(io: Int, xor: Int): Unit = { if(xor < WIDTH2) { - a1 = a2((io >>> BITS) & MASK) + a1 = a2.nn((io >>> BITS) & MASK) } else if(xor < WIDTH3) { - a2 = a3((io >>> BITS2) & MASK) - a1 = a2((io >>> BITS) & MASK) + a2 = a3.nn((io >>> BITS2) & MASK) + a1 = a2.nn((io >>> BITS) & MASK) } else if(xor < WIDTH4) { - a3 = a4((io >>> BITS3) & MASK) - a2 = a3((io >>> BITS2) & MASK) - a1 = a2((io >>> BITS) & MASK) + a3 = a4.nn((io >>> BITS3) & MASK) + a2 = a3.nn((io >>> BITS2) & MASK) + a1 = a2.nn((io >>> BITS) & MASK) } else if(xor < WIDTH5) { - a4 = a5((io >>> BITS4) & MASK) - a3 = a4((io >>> BITS3) & MASK) - a2 = a3((io >>> BITS2) & MASK) - a1 = a2((io >>> BITS) & MASK) + a4 = a5.nn((io >>> BITS4) & MASK) + a3 = a4.nn((io >>> BITS3) & MASK) + a2 = a3.nn((io >>> BITS2) & MASK) + a1 = a2.nn((io >>> BITS) & MASK) } else { - a5 = a6(io >>> BITS5) - a4 = a5((io >>> BITS4) & MASK) - a3 = a4((io >>> BITS3) & MASK) - a2 = a3((io >>> BITS2) & MASK) - a1 = a2((io >>> BITS) & MASK) + a5 = a6.nn(io >>> BITS5) + a4 = a5.nn((io >>> BITS4) & MASK) + a3 = a4.nn((io >>> BITS3) & MASK) + a2 = a3.nn((io >>> BITS2) & MASK) + a1 = a2.nn((io >>> BITS) & MASK) } } @@ -2431,7 +2430,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 >: Null <: Stepper[A] | Null, Semi <: Sub](it: NewVectorIterator[A]) extends Stepper[A] with EfficientSplit { protected[this] def build(it: NewVectorIterator[A]): Semi 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..27f2d07d55cd 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 } @@ -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,10 +422,10 @@ 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]) @@ -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..57c90aa2c639 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) @@ -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) @@ -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/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..739cc33fed51 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -83,7 +83,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,13 +137,13 @@ 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 @@ -223,13 +223,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,7 +237,7 @@ 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) @@ -260,7 +260,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) 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 +268,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 +296,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 diff --git a/library/src/scala/collection/mutable/HashSet.scala b/library/src/scala/collection/mutable/HashSet.scala index a92db177c110..21bea07d3913 100644 --- a/library/src/scala/collection/mutable/HashSet.scala +++ b/library/src/scala/collection/mutable/HashSet.scala @@ -74,7 +74,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,7 +158,7 @@ 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 @@ -204,7 +204,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 @@ -435,14 +435,14 @@ 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) diff --git a/library/src/scala/collection/mutable/HashTable.scala b/library/src/scala/collection/mutable/HashTable.scala index 5d0d1f35bdca..e322818e575a 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 @@ -264,8 +265,8 @@ private[collection] trait HashTable[A, B, Entry >: Null <: HashEntry[A, Entry]] var e = oldTable(i) while (e != null) { val h = index(elemHashCode(e.key)) - val e1 = e.next - e.next = table(h).asInstanceOf[Entry] + val e1 = e.nn.next + e.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/IndexedSeq.scala b/library/src/scala/collection/mutable/IndexedSeq.scala index 0f2c7b457613..a787eb60c76b 100644 --- a/library/src/scala/collection/mutable/IndexedSeq.scala +++ b/library/src/scala/collection/mutable/IndexedSeq.scala @@ -27,7 +27,7 @@ trait IndexedSeq[T] extends Seq[T] @SerialVersionUID(3L) object IndexedSeq extends SeqFactory.Delegate[IndexedSeq](ArrayBuffer) -transparent trait IndexedSeqOps[A, +CC[_] <: caps.Pure, +C <: AnyRef] +trait IndexedSeqOps[A, +CC[_], +C <: AnyRef] extends scala.collection.IndexedSeqOps[A, CC, C] with SeqOps[A, CC, C] with caps.Pure { 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 c81dae108427..15a6fb7cb29e 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 = ::[A] /*| Null*/ + private type Predecessor = ::[A] | 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 } @@ -210,7 +211,7 @@ class ListBuffer[A] 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 @@ -218,7 +219,7 @@ class ListBuffer[A] // `p` can not be `null` because the case where `idx == 0` is handled above val p = predecessor(idx) 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 @@ -232,7 +233,7 @@ class ListBuffer[A] else { val p = predecessor(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 } } @@ -246,14 +247,14 @@ class ListBuffer[A] private def insertAfter(prev: Predecessor, 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) { @@ -275,8 +276,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 @@ -295,7 +296,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 } @@ -320,23 +321,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 } @@ -354,7 +355,7 @@ class ListBuffer[A] 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] 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..a0ed6618b3c2 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 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 87f922be4ef0..23c8e01bfec1 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..5018744220cc 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]] diff --git a/library/src/scala/collection/mutable/UnrolledBuffer.scala b/library/src/scala/collection/mutable/UnrolledBuffer.scala index aee908369f0f..edad79d8b1b8 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 = { 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 58cb130a6603..3c0713674155 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: Option[Try[T]] = Option.fromNullable(value0) @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]]) */ @@ -444,9 +444,9 @@ 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) = @@ -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..b68de40978e1 100644 --- a/library/src/scala/reflect/ClassManifestDeprecatedApis.scala +++ b/library/src/scala/reflect/ClassManifestDeprecatedApis.scala @@ -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..f79ce8095142 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 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..2b017bbc42c3 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 } diff --git a/library/src/scala/sys/SystemProperties.scala b/library/src/scala/sys/SystemProperties.scala index d1a5326e66f7..63ce4e2fe034 100644 --- a/library/src/scala/sys/SystemProperties.scala +++ b/library/src/scala/sys/SystemProperties.scala @@ -32,7 +32,7 @@ class SystemProperties extends mutable.AbstractMap[String, String] { override def empty: mutable.Map[String, String] = mutable.Map[String, String]() - override def default(key: String): String = null + override def default(key: String): String | Null = null def iterator: Iterator[(String, String)] = wrapAccess { val ps = System.getProperties() @@ -41,7 +41,7 @@ extends mutable.AbstractMap[String, String] { 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] = @@ -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/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..88c27a5c2c6b 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,7 +234,7 @@ 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") 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 25cb2f86dea3..4a8507b1da95 100644 --- a/library/src/scala/util/matching/Regex.scala +++ b/library/src/scala/util/matching/Regex.scala @@ -650,14 +650,14 @@ 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 @@ -667,28 +667,28 @@ object Regex { /** 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] = Option.fromNullable(m.matched) } /** 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. * From 27bc67d79f635f078b91eb4268a3ea296acb1236 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 29 Aug 2025 03:36:59 +0200 Subject: [PATCH 03/46] Adjust some type parameters --- library/src/scala/Array.scala | 2 +- library/src/scala/IArray.scala | 12 +- library/src/scala/Predef.scala | 42 +-- library/src/scala/StringContext.scala | 3 +- library/src/scala/Symbol.scala | 4 +- library/src/scala/collection/ArrayOps.scala | 8 +- library/src/scala/collection/SeqView.scala | 10 +- library/src/scala/collection/View.scala | 14 +- .../collection/convert/StreamExtensions.scala | 6 +- .../convert/impl/ArrayStepper.scala | 2 +- .../convert/impl/BinaryTreeStepper.scala | 52 ++-- .../convert/impl/ChampStepper.scala | 20 +- .../convert/impl/InOrderStepperBase.scala | 4 +- .../convert/impl/IndexedStepperBase.scala | 4 +- .../convert/impl/IteratorStepper.scala | 5 +- .../convert/impl/RangeStepper.scala | 4 +- .../convert/impl/TableStepper.scala | 30 +- .../convert/impl/VectorStepper.scala | 2 +- .../scala/collection/immutable/ArraySeq.scala | 2 +- .../scala/collection/immutable/HashMap.scala | 4 +- .../scala/collection/immutable/HashSet.scala | 18 +- .../immutable/LazyListIterable.scala | 6 +- .../scala/collection/immutable/ListMap.scala | 2 +- .../collection/immutable/RedBlackTree.scala | 62 ++-- .../scala/collection/immutable/TreeSet.scala | 74 ++--- .../scala/collection/immutable/Vector.scala | 267 +++++++++--------- .../scala/collection/mutable/AnyRefMap.scala | 6 +- .../collection/mutable/ArrayBuilder.scala | 4 +- .../scala/collection/mutable/ArraySeq.scala | 2 +- .../scala/collection/mutable/HashMap.scala | 95 ++++--- .../scala/collection/mutable/HashSet.scala | 38 +-- .../scala/collection/mutable/HashTable.scala | 4 +- .../scala/collection/mutable/IndexedSeq.scala | 2 +- .../collection/mutable/PriorityQueue.scala | 2 +- .../src/scala/collection/mutable/Stack.scala | 2 +- .../collection/mutable/UnrolledBuffer.scala | 2 +- .../src/scala/concurrent/impl/Promise.scala | 8 +- .../reflect/ClassManifestDeprecatedApis.scala | 2 +- library/src/scala/runtime/ScalaRunTime.scala | 4 +- library/src/scala/sys/PropImpl.scala | 5 +- library/src/scala/sys/SystemProperties.scala | 8 +- library/src/scala/sys/package.scala | 4 +- library/src/scala/util/Sorting.scala | 2 +- library/src/scala/util/matching/Regex.scala | 6 +- 44 files changed, 433 insertions(+), 422 deletions(-) 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/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 e613f47b9ea1..8ea81f8b2ae2 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -656,47 +656,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] | Null): ArraySeq[T] | Null = - if (xs eq null) null - else ArraySeq.make(xs) + implicit def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = + 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] | Null): ArraySeq.ofRef[T] | Null = { - if (xs eq null) null - else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]] - else new ArraySeq.ofRef[T](xs) - } + 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] | Null): ArraySeq.ofInt | Null = 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] | Null): ArraySeq.ofDouble | Null = 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] | Null): ArraySeq.ofLong | Null = 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] | Null): ArraySeq.ofFloat | Null = 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] | Null): ArraySeq.ofChar | Null = 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] | Null): ArraySeq.ofByte | Null = 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] | Null): ArraySeq.ofShort | Null = 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] | Null): ArraySeq.ofBoolean | Null = 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] | Null): ArraySeq.ofUnit | Null = 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 | Null): WrappedString | Null = 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] | Null): IndexedSeq[T] | Null = - if (xs eq null) null + implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T]): IndexedSeq[T] = + if (xs eq null) null.asInstanceOf[IndexedSeq[T]] else new ArrayOps(xs).toIndexedSeq } 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/SeqView.scala b/library/src/scala/collection/SeqView.scala index 3928a20aef70..9879efb91d91 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/View.scala b/library/src/scala/collection/View.scala index 56a63fe97529..9697a31dbbc4 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -459,13 +459,13 @@ object View extends IterableFactory[View] { 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 @@ -479,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 @@ -513,7 +513,7 @@ object View extends IterableFactory[View] { 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 @@ -527,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/convert/StreamExtensions.scala b/library/src/scala/collection/convert/StreamExtensions.scala index c132962ce97f..f601feca9e13 100644 --- a/library/src/scala/collection/convert/StreamExtensions.scala +++ b/library/src/scala/collection/convert/StreamExtensions.scala @@ -304,7 +304,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) } } @@ -331,7 +331,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) } } @@ -358,7 +358,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) } } } 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 830646f43bb7..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 | Null, 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,7 +124,7 @@ 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] @@ -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 | Null](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 | Null]( - _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 | Null](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 | Null]( - _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 | Null](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 | Null]( - _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 | Null](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/ChampStepper.scala b/library/src/scala/collection/convert/impl/ChampStepper.scala index 94908c5dc7dc..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] | Null, 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] | Null](_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] | Null](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] | Null](_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] | Null](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] | Null](_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] | Null](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] | Null](_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] | Null](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 8ccf95bd439e..7e42f9bb75f3 100644 --- a/library/src/scala/collection/convert/impl/IteratorStepper.scala +++ b/library/src/scala/collection/convert/impl/IteratorStepper.scala @@ -120,9 +120,10 @@ private[collection] class LongIteratorStepper(_underlying: Iterator[Long] | Null } /** 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] | Null, Semi <: SP](final protected val underlying: Iterator[A] | Null) { +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.nn.estimateSize else Long.MaxValue 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/TableStepper.scala b/library/src/scala/collection/convert/impl/TableStepper.scala index 1fd4c7860dd5..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 | Null, 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 | Null]( +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 | Null]( +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 | Null]( +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 | Null]( +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 6485c49c8de9..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, diff --git a/library/src/scala/collection/immutable/ArraySeq.scala b/library/src/scala/collection/immutable/ArraySeq.scala index 81d172a90d44..1ef38604435a 100644 --- a/library/src/scala/collection/immutable/ArraySeq.scala +++ b/library/src/scala/collection/immutable/ArraySeq.scala @@ -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 787715ef97f3..aa1aa7ad714d 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 { @@ -2182,7 +2182,7 @@ private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) keyHash = improve(originalHash), originalHash = originalHash, shift = 0 - ) + ).nn currentValueCursor += 1 } curr diff --git a/library/src/scala/collection/immutable/HashSet.scala b/library/src/scala/collection/immutable/HashSet.scala index 07e95a4b52e1..ea2bd788606c 100644 --- a/library/src/scala/collection/immutable/HashSet.scala +++ b/library/src/scala/collection/immutable/HashSet.scala @@ -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 @@ -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]] = _ + 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) { diff --git a/library/src/scala/collection/immutable/LazyListIterable.scala b/library/src/scala/collection/immutable/LazyListIterable.scala index 745d2cc3c3f2..f0fddc2fb543 100644 --- a/library/src/scala/collection/immutable/LazyListIterable.scala +++ b/library/src/scala/collection/immutable/LazyListIterable.scala @@ -1139,17 +1139,17 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { 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/ListMap.scala b/library/src/scala/collection/immutable/ListMap.scala index ec3543a1bc70..0780e9d99eb7 100644 --- a/library/src/scala/collection/immutable/ListMap.scala +++ b/library/src/scala/collection/immutable/ListMap.scala @@ -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 b2b68dbcf57b..edbb2186da4f 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -160,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]) { @@ -175,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]) { @@ -190,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 { @@ -208,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 @@ -233,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 { @@ -329,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. @@ -424,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) @@ -440,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 @@ -451,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) @@ -459,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) @@ -467,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) @@ -476,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) @@ -488,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 { @@ -498,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 { @@ -508,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 { @@ -783,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 @@ -1052,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) @@ -1126,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 @@ -1170,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) @@ -1186,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) @@ -1207,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 { @@ -1215,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 { @@ -1225,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 { @@ -1236,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/TreeSet.scala b/library/src/scala/collection/immutable/TreeSet.scala index 5607b81b0c75..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) } @@ -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 31ab1125b9b8..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 = 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 = { @@ -1153,7 +1153,7 @@ private final class Vector6[+A](_prefix1: Arr1, private[immutable] val len1: Int ) } - override protected[this] def appendedAll0[B >: A](suffix: collection.IterableOnce[B], k: Int): Vector[B] = { + override protected[this] def appendedAll0[B >: A](suffix: collection.IterableOnce[B]^, k: Int): Vector[B] = { val suffix1b = append1IfSpace(suffix1, suffix) if(suffix1b ne null) copy(suffix1 = suffix1b, length0 = length0-suffix1.length+suffix1b.length) else super.appendedAll0(suffix, k) @@ -1399,11 +1399,11 @@ private final class VectorSliceBuilder(lo: Int, hi: Int) { final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { - @annotation.stableNull private[this] var a6: Arr6 | Null = _ - @annotation.stableNull private[this] var a5: Arr5 | Null = _ - @annotation.stableNull private[this] var a4: Arr4 | Null = _ - @annotation.stableNull private[this] var a3: Arr3 | Null = _ - @annotation.stableNull private[this] var a2: Arr2 | Null = _ + private[this] var a6: Arr6 = _ + private[this] var a5: Arr5 = _ + private[this] var a4: Arr4 = _ + private[this] var a3: Arr3 = _ + private[this] var a2: Arr2 = _ private[this] var a1: Arr1 = new Arr1(WIDTH) private[this] var len1, lenRest, offset = 0 private[this] var prefixIsRightAligned = false @@ -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 @@ -1487,9 +1487,9 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH - v2.len1 setLen(v2.length0 + offset) a2 = new Arr2(WIDTH) - a2.nn(0) = v2.prefix1 + a2(0) = v2.prefix1 System.arraycopy(d2, 0, a2, 1, d2.length) - a2.nn(d2.length+1) = a1.nn + a2(d2.length+1) = a1 case 5 => val v3 = v.asInstanceOf[Vector3[_]] val d3 = v3.data3 @@ -1499,11 +1499,11 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH2 - v3.len12 setLen(v3.length0 + offset) a3 = new Arr3(WIDTH) - a3.nn(0) = copyPrepend(v3.prefix1, v3.prefix2) + a3(0) = copyPrepend(v3.prefix1, v3.prefix2) System.arraycopy(d3, 0, a3, 1, d3.length) a2 = copyOf(s2, WIDTH) - a3.nn(d3.length+1) = a2.nn - a2.nn(s2.length) = a1.nn + a3(d3.length+1) = a2 + a2(s2.length) = a1 case 7 => val v4 = v.asInstanceOf[Vector4[_]] val d4 = v4.data4 @@ -1514,13 +1514,13 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH3 - v4.len123 setLen(v4.length0 + offset) a4 = new Arr4(WIDTH) - a4.nn(0) = copyPrepend(copyPrepend(v4.prefix1, v4.prefix2), v4.prefix3) + a4(0) = copyPrepend(copyPrepend(v4.prefix1, v4.prefix2), v4.prefix3) System.arraycopy(d4, 0, a4, 1, d4.length) a3 = copyOf(s3, WIDTH) a2 = copyOf(s2, WIDTH) - a4.nn(d4.length+1) = a3.nn - a3.nn(s3.length) = a2.nn - a2.nn(s2.length) = a1.nn + a4(d4.length+1) = a3 + a3(s3.length) = a2 + a2(s2.length) = a1 case 9 => val v5 = v.asInstanceOf[Vector5[_]] val d5 = v5.data5 @@ -1532,15 +1532,15 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH4 - v5.len1234 setLen(v5.length0 + offset) a5 = new Arr5(WIDTH) - a5.nn(0) = copyPrepend(copyPrepend(copyPrepend(v5.prefix1, v5.prefix2), v5.prefix3), v5.prefix4) + a5(0) = copyPrepend(copyPrepend(copyPrepend(v5.prefix1, v5.prefix2), v5.prefix3), v5.prefix4) System.arraycopy(d5, 0, a5, 1, d5.length) a4 = copyOf(s4, WIDTH) a3 = copyOf(s3, WIDTH) a2 = copyOf(s2, WIDTH) - a5.nn(d5.length+1) = a4.nn - a4.nn(s4.length) = a3.nn - a3.nn(s3.length) = a2.nn - a2.nn(s2.length) = a1.nn + a5(d5.length+1) = a4 + a4(s4.length) = a3 + a3(s3.length) = a2 + a2(s2.length) = a1 case 11 => val v6 = v.asInstanceOf[Vector6[_]] val d6 = v6.data6 @@ -1553,17 +1553,17 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = WIDTH5 - v6.len12345 setLen(v6.length0 + offset) a6 = new Arr6(LASTWIDTH) - a6.nn(0) = copyPrepend(copyPrepend(copyPrepend(copyPrepend(v6.prefix1, v6.prefix2), v6.prefix3), v6.prefix4), v6.prefix5) + a6(0) = copyPrepend(copyPrepend(copyPrepend(copyPrepend(v6.prefix1, v6.prefix2), v6.prefix3), v6.prefix4), v6.prefix5) System.arraycopy(d6, 0, a6, 1, d6.length) a5 = copyOf(s5, WIDTH) a4 = copyOf(s4, WIDTH) a3 = copyOf(s3, WIDTH) a2 = copyOf(s2, WIDTH) - a6.nn(d6.length+1) = a5.nn - a5.nn(s5.length) = a4.nn - a4.nn(s4.length) = a3.nn - a3.nn(s3.length) = a2.nn - a2.nn(s2.length) = a1.nn + a6(d6.length+1) = a5 + a5(s5.length) = a4 + a4(s4.length) = a3 + a3(s3.length) = a2 + a2(s2.length) = a1 } if(len1 == 0 && lenRest > 0) { // force advance() on next addition: @@ -1614,8 +1614,8 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { lenRest -= offset - newOffset offset = newOffset } - var a: Array[AnyRef] | Null = null // the array we modify - var aParent: Array[AnyRef] | Null = 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 @@ -1623,7 +1623,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { shrinkOffsetIfToLarge(WIDTH5) if ((lenRest >>> BITS5) == 0) depth = 5 aParent = a - a = a.nn(0).asInstanceOf[Array[AnyRef]] + a = a(0).asInstanceOf[Array[AnyRef]] } if (depth >= 5) { if (a == null) a = a5.asInstanceOf[Array[AnyRef]] @@ -1635,10 +1635,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS4) == 0) depth = 4 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent.nn(0) = a.nn + aParent(0) = a } aParent = a - a = a.nn(0).asInstanceOf[Array[AnyRef]] + a = a(0).asInstanceOf[Array[AnyRef]] } if (depth >= 4) { if (a == null) a = a4.asInstanceOf[Array[AnyRef]] @@ -1650,10 +1650,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS3) == 0) depth = 3 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent.nn(0) = a.nn + aParent(0) = a } aParent = a - a = a.nn(0).asInstanceOf[Array[AnyRef]] + a = a(0).asInstanceOf[Array[AnyRef]] } if (depth >= 3) { if (a == null) a = a3.asInstanceOf[Array[AnyRef]] @@ -1665,10 +1665,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS2) == 0) depth = 2 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent.nn(0) = a.nn + aParent(0) = a } aParent = a - a = a.nn(0).asInstanceOf[Array[AnyRef]] + a = a(0).asInstanceOf[Array[AnyRef]] } if (depth >= 2) { if (a == null) a = a2.asInstanceOf[Array[AnyRef]] @@ -1680,10 +1680,10 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if ((lenRest >>> BITS) == 0) depth = 1 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent.nn(0) = a.nn + aParent(0) = a } aParent = a - a = a.nn(0).asInstanceOf[Array[AnyRef]] + a = a(0).asInstanceOf[Array[AnyRef]] } if (depth >= 1) { if (a == null) a = a1.asInstanceOf[Array[AnyRef]] @@ -1695,7 +1695,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { offset = 0 } else { if (i > 0) a = copyOfRange(a, i, WIDTH) - aParent.nn(0) = a.nn + aParent(0) = a } } prefixIsRightAligned = false @@ -1703,7 +1703,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { def addOne(elem: A): this.type = { if(len1 == WIDTH) advance() - a1.nn(len1) = elem.asInstanceOf[AnyRef] + a1(len1) = elem.asInstanceOf[AnyRef] len1 += 1 this } @@ -1849,45 +1849,45 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { if (xor <= 0) { // level = 6 or something very unexpected happened throw new IllegalArgumentException(s"advance1($idx, $xor): a1=$a1, a2=$a2, a3=$a3, a4=$a4, a5=$a5, a6=$a6, depth=$depth") } else if (xor < WIDTH2) { // level = 1 - if (depth <= 1) { a2 = new Array(WIDTH); a2.nn(0) = a1; depth = 2 } + if (depth <= 1) { a2 = new Array(WIDTH); a2(0) = a1; depth = 2 } a1 = new Array(WIDTH) - a2.nn((idx >>> BITS) & MASK) = a1 + a2((idx >>> BITS) & MASK) = a1 } else if (xor < WIDTH3) { // level = 2 - if (depth <= 2) { a3 = new Array(WIDTH); a3.nn(0) = a2.nn; depth = 3 } + if (depth <= 2) { a3 = new Array(WIDTH); a3(0) = a2; depth = 3 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) - a2.nn((idx >>> BITS) & MASK) = a1 - a3.nn((idx >>> BITS2) & MASK) = a2 + a2((idx >>> BITS) & MASK) = a1 + a3((idx >>> BITS2) & MASK) = a2 } else if (xor < WIDTH4) { // level = 3 - if (depth <= 3) { a4 = new Array(WIDTH); a4.nn(0) = a3.nn; depth = 4 } + if (depth <= 3) { a4 = new Array(WIDTH); a4(0) = a3; depth = 4 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) a3 = new Array(WIDTH) - a2.nn((idx >>> BITS) & MASK) = a1.nn - a3.nn((idx >>> BITS2) & MASK) = a2.nn - a4.nn((idx >>> BITS3) & MASK) = a3.nn - } else if (xor < WIDTH5) { - if (depth <= 4) { a5 = new Array(WIDTH); a5.nn(0) = a4.nn; depth = 5 } + a2((idx >>> BITS) & MASK) = a1 + a3((idx >>> BITS2) & MASK) = a2 + a4((idx >>> BITS3) & MASK) = a3 + } else if (xor < WIDTH5) { // level = 4 + if (depth <= 4) { a5 = new Array(WIDTH); a5(0) = a4; depth = 5 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) a3 = new Array(WIDTH) a4 = new Array(WIDTH) - a2.nn((idx >>> BITS) & MASK) = a1.nn - a3.nn((idx >>> BITS2) & MASK) = a2.nn - a4.nn((idx >>> BITS3) & MASK) = a3.nn - a5.nn((idx >>> BITS4) & MASK) = a4.nn - } else { - if (depth <= 5) { a6 = new Array(LASTWIDTH); a6.nn(0) = a5.nn; depth = 6 } + a2((idx >>> BITS) & MASK) = a1 + a3((idx >>> BITS2) & MASK) = a2 + a4((idx >>> BITS3) & MASK) = a3 + a5((idx >>> BITS4) & MASK) = a4 + } else { // level = 5 + if (depth <= 5) { a6 = new Array(LASTWIDTH); a6(0) = a5; depth = 6 } a1 = new Array(WIDTH) a2 = new Array(WIDTH) a3 = new Array(WIDTH) a4 = new Array(WIDTH) a5 = new Array(WIDTH) - a2.nn((idx >>> BITS) & MASK) = a1.nn - a3.nn((idx >>> BITS2) & MASK) = a2.nn - a4.nn((idx >>> BITS3) & MASK) = a3.nn - a5.nn((idx >>> BITS4) & MASK) = a4.nn - a6.nn(idx >>> BITS5) = a5.nn + a2((idx >>> BITS) & MASK) = a1 + a3((idx >>> BITS2) & MASK) = a2 + a4((idx >>> BITS3) & MASK) = a3 + a5((idx >>> BITS4) & MASK) = a4 + a6(idx >>> BITS5) = a5 } } @@ -1903,18 +1903,18 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i1 = (len-1) & MASK val i2 = (len-1) >>> BITS val data = copyOfRange(a2, 1, i2) - val prefix1 = a2.nn(0) - val suffix1 = copyIfDifferentSize(a2.nn(i2), i1+1) + val prefix1 = a2(0) + val suffix1 = copyIfDifferentSize(a2(i2), i1+1) new Vector2(prefix1, WIDTH-offset, data, suffix1, realLen) } else if(len <= WIDTH3) { val i1 = (len-1) & MASK val i2 = ((len-1) >>> BITS) & MASK val i3 = ((len-1) >>> BITS2) val data = copyOfRange(a3, 1, i3) - val prefix2 = copyTail(a3.nn(0)) - val prefix1 = a3.nn(0).nn(0) - val suffix2 = copyOf(a3.nn(i3), i2) - val suffix1 = copyIfDifferentSize(a3.nn(i3).nn(i2), i1+1) + val prefix2 = copyTail(a3(0)) + val prefix1 = a3(0)(0) + val suffix2 = copyOf(a3(i3), i2) + val suffix1 = copyIfDifferentSize(a3(i3)(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH new Vector3(prefix1, len1, prefix2, len12, data, suffix2, suffix1, realLen) @@ -1924,12 +1924,12 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i3 = ((len-1) >>> BITS2) & MASK val i4 = ((len-1) >>> BITS3) val data = copyOfRange(a4, 1, i4) - val prefix3 = copyTail(a4.nn(0)) - val prefix2 = copyTail(a4.nn(0).nn(0)) - val prefix1 = a4.nn(0).nn(0).nn(0) - val suffix3 = copyOf(a4.nn(i4), i3) - val suffix2 = copyOf(a4.nn(i4).nn(i3), i2) - val suffix1 = copyIfDifferentSize(a4.nn(i4).nn(i3).nn(i2), i1+1) + val prefix3 = copyTail(a4(0)) + val prefix2 = copyTail(a4(0)(0)) + val prefix1 = a4(0)(0)(0) + val suffix3 = copyOf(a4(i4), i3) + val suffix2 = copyOf(a4(i4)(i3), i2) + val suffix1 = copyIfDifferentSize(a4(i4)(i3)(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH val len123 = len12 + prefix3.length*WIDTH2 @@ -1941,14 +1941,14 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i4 = ((len-1) >>> BITS3) & MASK val i5 = ((len-1) >>> BITS4) val data = copyOfRange(a5, 1, i5) - val prefix4 = copyTail(a5.nn(0)) - val prefix3 = copyTail(a5.nn(0).nn(0)) - val prefix2 = copyTail(a5.nn(0).nn(0).nn(0)) - val prefix1 = a5.nn(0).nn(0).nn(0).nn(0) - val suffix4 = copyOf(a5.nn(i5), i4) - val suffix3 = copyOf(a5.nn(i5).nn(i4), i3) - val suffix2 = copyOf(a5.nn(i5).nn(i4).nn(i3), i2) - val suffix1 = copyIfDifferentSize(a5.nn(i5).nn(i4).nn(i3).nn(i2), i1+1) + val prefix4 = copyTail(a5(0)) + val prefix3 = copyTail(a5(0)(0)) + val prefix2 = copyTail(a5(0)(0)(0)) + val prefix1 = a5(0)(0)(0)(0) + val suffix4 = copyOf(a5(i5), i4) + val suffix3 = copyOf(a5(i5)(i4), i3) + val suffix2 = copyOf(a5(i5)(i4)(i3), i2) + val suffix1 = copyIfDifferentSize(a5(i5)(i4)(i3)(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH val len123 = len12 + prefix3.length*WIDTH2 @@ -1962,15 +1962,16 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { val i5 = ((len-1) >>> BITS4) & MASK val i6 = ((len-1) >>> BITS5) val data = copyOfRange(a6, 1, i6) - val prefix5 = copyTail(a6.nn(0)) - val prefix4 = copyTail(a6.nn(0).nn(0)) - val prefix3 = copyTail(a6.nn(0).nn(0).nn(0)) - val prefix2 = copyTail(a6.nn(0).nn(0).nn(0).nn(0)) - val suffix5 = copyOf(a6.nn(i6), i5) - val suffix4 = copyOf(a6.nn(i6).nn(i5), i4) - val suffix3 = copyOf(a6.nn(i6).nn(i5).nn(i4), i3) - val suffix2 = copyOf(a6.nn(i6).nn(i5).nn(i4).nn(i3), i2) - val suffix1 = copyIfDifferentSize(a6.nn(i6).nn(i5).nn(i4).nn(i3).nn(i2), i1+1) + val prefix5 = copyTail(a6(0)) + val prefix4 = copyTail(a6(0)(0)) + val prefix3 = copyTail(a6(0)(0)(0)) + val prefix2 = copyTail(a6(0)(0)(0)(0)) + val prefix1 = a6(0)(0)(0)(0)(0) + val suffix5 = copyOf(a6(i6), i5) + val suffix4 = copyOf(a6(i6)(i5), i4) + val suffix3 = copyOf(a6(i6)(i5)(i4), i3) + val suffix2 = copyOf(a6(i6)(i5)(i4)(i3), i2) + val suffix1 = copyIfDifferentSize(a6(i6)(i5)(i4)(i3)(i2), i1+1) val len1 = prefix1.length val len12 = len1 + prefix2.length*WIDTH val len123 = len12 + prefix3.length*WIDTH2 @@ -2241,11 +2242,11 @@ private object VectorStatics { private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLength: Int, private[this] val sliceCount: Int) extends AbstractIterator[A] with java.lang.Cloneable { private[this] var a1: Arr1 = v.prefix1 - @annotation.stableNull private[this] var a2: Arr2 | Null = _ - @annotation.stableNull private[this] var a3: Arr3 | Null = _ - @annotation.stableNull private[this] var a4: Arr4 | Null = _ - @annotation.stableNull private[this] var a5: Arr5 | Null = _ - @annotation.stableNull private[this] var a6: Arr6 | Null = _ + private[this] var a2: Arr2 = _ + private[this] var a3: Arr3 = _ + private[this] var a4: Arr4 = _ + private[this] var a5: Arr5 = _ + private[this] var a6: Arr6 = _ private[this] var a1len = a1.length private[this] var i1 = 0 // current index in a1 private[this] var oldPos = 0 @@ -2309,49 +2310,49 @@ private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLe private[this] def advanceA(io: Int, xor: Int): Unit = { if(xor < WIDTH2) { - a1 = a2.nn((io >>> BITS) & MASK) + a1 = a2((io >>> BITS) & MASK) } else if(xor < WIDTH3) { - a2 = a3.nn((io >>> BITS2) & MASK) - a1 = a2.nn(0) + a2 = a3((io >>> BITS2) & MASK) + a1 = a2(0) } else if(xor < WIDTH4) { - a3 = a4.nn((io >>> BITS3) & MASK) - a2 = a3.nn(0) - a1 = a2.nn(0) + a3 = a4((io >>> BITS3) & MASK) + a2 = a3(0) + a1 = a2(0) } else if(xor < WIDTH5) { - a4 = a5.nn((io >>> BITS4) & MASK) - a3 = a4.nn(0) - a2 = a3.nn(0) - a1 = a2.nn(0) + a4 = a5((io >>> BITS4) & MASK) + a3 = a4(0) + a2 = a3(0) + a1 = a2(0) } else { - a5 = a6.nn(io >>> BITS5) - a4 = a5.nn(0) - a3 = a4.nn(0) - a2 = a3.nn(0) - a1 = a2.nn(0) + a5 = a6(io >>> BITS5) + a4 = a5(0) + a3 = a4(0) + a2 = a3(0) + a1 = a2(0) } } private[this] def setA(io: Int, xor: Int): Unit = { if(xor < WIDTH2) { - a1 = a2.nn((io >>> BITS) & MASK) + a1 = a2((io >>> BITS) & MASK) } else if(xor < WIDTH3) { - a2 = a3.nn((io >>> BITS2) & MASK) - a1 = a2.nn((io >>> BITS) & MASK) + a2 = a3((io >>> BITS2) & MASK) + a1 = a2((io >>> BITS) & MASK) } else if(xor < WIDTH4) { - a3 = a4.nn((io >>> BITS3) & MASK) - a2 = a3.nn((io >>> BITS2) & MASK) - a1 = a2.nn((io >>> BITS) & MASK) + a3 = a4((io >>> BITS3) & MASK) + a2 = a3((io >>> BITS2) & MASK) + a1 = a2((io >>> BITS) & MASK) } else if(xor < WIDTH5) { - a4 = a5.nn((io >>> BITS4) & MASK) - a3 = a4.nn((io >>> BITS3) & MASK) - a2 = a3.nn((io >>> BITS2) & MASK) - a1 = a2.nn((io >>> BITS) & MASK) + a4 = a5((io >>> BITS4) & MASK) + a3 = a4((io >>> BITS3) & MASK) + a2 = a3((io >>> BITS2) & MASK) + a1 = a2((io >>> BITS) & MASK) } else { - a5 = a6.nn(io >>> BITS5) - a4 = a5.nn((io >>> BITS4) & MASK) - a3 = a4.nn((io >>> BITS3) & MASK) - a2 = a3.nn((io >>> BITS2) & MASK) - a1 = a2.nn((io >>> BITS) & MASK) + a5 = a6(io >>> BITS5) + a4 = a5((io >>> BITS4) & MASK) + a3 = a4((io >>> BITS3) & MASK) + a2 = a3((io >>> BITS2) & MASK) + a1 = a2((io >>> BITS) & MASK) } } @@ -2430,7 +2431,7 @@ private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLe } -private abstract class VectorStepperBase[A, Sub >: Null <: Stepper[A] | Null, 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 @@ -2441,7 +2442,7 @@ private abstract class VectorStepperBase[A, Sub >: Null <: Stepper[A] | Null, Se 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/mutable/AnyRefMap.scala b/library/src/scala/collection/mutable/AnyRefMap.scala index 27f2d07d55cd..0c361f31b847 100644 --- a/library/src/scala/collection/mutable/AnyRefMap.scala +++ b/library/src/scala/collection/mutable/AnyRefMap.scala @@ -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 @@ -428,7 +428,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi val h = _hashes.nn(i) if (h+h != 0) { j += 1 - f(elems(i).asInstanceOf[A]) + f(elems.nn(i).asInstanceOf[A]) } i += 1 } diff --git a/library/src/scala/collection/mutable/ArrayBuilder.scala b/library/src/scala/collection/mutable/ArrayBuilder.scala index 57c90aa2c639..f3f007e8569b 100644 --- a/library/src/scala/collection/mutable/ArrayBuilder.scala +++ b/library/src/scala/collection/mutable/ArrayBuilder.scala @@ -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] = _ @@ -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) diff --git a/library/src/scala/collection/mutable/ArraySeq.scala b/library/src/scala/collection/mutable/ArraySeq.scala index 9f74959232eb..695c9567b597 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/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index 739cc33fed51..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) @@ -149,7 +151,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) 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 } @@ -242,8 +244,8 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) 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,7 +256,7 @@ 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 @@ -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 21bea07d3913..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) @@ -163,12 +165,12 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) 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 } @@ -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 } } @@ -445,12 +447,12 @@ object HashSet extends IterableFactory[HashSet] { 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 e322818e575a..508402d7a684 100644 --- a/library/src/scala/collection/mutable/HashTable.scala +++ b/library/src/scala/collection/mutable/HashTable.scala @@ -264,9 +264,9 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends while (i >= 0) { var e = oldTable(i) while (e != null) { - val h = index(elemHashCode(e.key)) + val h = index(elemHashCode(e.nn.key)) val e1 = e.nn.next - e.next = table(h).asInstanceOf[Entry | Null] + e.nn.next = table(h).asInstanceOf[Entry | Null] table(h) = e e = e1 nnSizeMapAdd(h) diff --git a/library/src/scala/collection/mutable/IndexedSeq.scala b/library/src/scala/collection/mutable/IndexedSeq.scala index a787eb60c76b..0f2c7b457613 100644 --- a/library/src/scala/collection/mutable/IndexedSeq.scala +++ b/library/src/scala/collection/mutable/IndexedSeq.scala @@ -27,7 +27,7 @@ trait IndexedSeq[T] extends Seq[T] @SerialVersionUID(3L) object IndexedSeq extends SeqFactory.Delegate[IndexedSeq](ArrayBuffer) -trait IndexedSeqOps[A, +CC[_], +C <: AnyRef] +transparent trait IndexedSeqOps[A, +CC[_] <: caps.Pure, +C <: AnyRef] extends scala.collection.IndexedSeqOps[A, CC, C] with SeqOps[A, CC, C] with caps.Pure { diff --git a/library/src/scala/collection/mutable/PriorityQueue.scala b/library/src/scala/collection/mutable/PriorityQueue.scala index a0ed6618b3c2..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[AnyRef | Null] = 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 = { diff --git a/library/src/scala/collection/mutable/Stack.scala b/library/src/scala/collection/mutable/Stack.scala index 5018744220cc..26cda88ecd4f 100644 --- a/library/src/scala/collection/mutable/Stack.scala +++ b/library/src/scala/collection/mutable/Stack.scala @@ -122,7 +122,7 @@ class Stack[A] protected (array: Array[AnyRef | Null], 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 edad79d8b1b8..f27f87249d36 100644 --- a/library/src/scala/collection/mutable/UnrolledBuffer.scala +++ b/library/src/scala/collection/mutable/UnrolledBuffer.scala @@ -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/impl/Promise.scala b/library/src/scala/concurrent/impl/Promise.scala index 3c0713674155..ce254542ec60 100644 --- a/library/src/scala/concurrent/impl/Promise.scala +++ b/library/src/scala/concurrent/impl/Promise.scala @@ -274,7 +274,7 @@ private[concurrent] object Promise { override final def isCompleted: Boolean = value0 ne null - override final def value: Option[Try[T]] = Option.fromNullable(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] | Null = { @@ -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, @@ -449,8 +449,8 @@ private[concurrent] object Promise { @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 diff --git a/library/src/scala/reflect/ClassManifestDeprecatedApis.scala b/library/src/scala/reflect/ClassManifestDeprecatedApis.scala index b68de40978e1..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) diff --git a/library/src/scala/runtime/ScalaRunTime.scala b/library/src/scala/runtime/ScalaRunTime.scala index f79ce8095142..8bafd7598205 100644 --- a/library/src/scala/runtime/ScalaRunTime.scala +++ b/library/src/scala/runtime/ScalaRunTime.scala @@ -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/sys/PropImpl.scala b/library/src/scala/sys/PropImpl.scala index 2b017bbc42c3..7f2f1b96b153 100644 --- a/library/src/scala/sys/PropImpl.scala +++ b/library/src/scala/sys/PropImpl.scala @@ -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 63ce4e2fe034..6daac4493a78 100644 --- a/library/src/scala/sys/SystemProperties.scala +++ b/library/src/scala/sys/SystemProperties.scala @@ -29,12 +29,12 @@ 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 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 @@ -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] = 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/util/Sorting.scala b/library/src/scala/util/Sorting.scala index 88c27a5c2c6b..19c8ae111f09 100644 --- a/library/src/scala/util/Sorting.scala +++ b/library/src/scala/util/Sorting.scala @@ -237,7 +237,7 @@ object Sorting { @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/matching/Regex.scala b/library/src/scala/util/matching/Regex.scala index 4a8507b1da95..7b90fb28d749 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() @@ -662,7 +662,7 @@ object Regex { 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. @@ -768,7 +768,7 @@ object Regex { * */ object Match { - def unapply(m: Match): Some[String] = Option.fromNullable(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 From d654acc6622fb6f785ac418671b481acd49a7906 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Sat, 30 Aug 2025 03:17:39 +0200 Subject: [PATCH 04/46] More changes --- library/src/scala/collection/Iterator.scala | 8 +- library/src/scala/collection/View.scala | 2 +- .../scala/collection/concurrent/TrieMap.scala | 28 +- .../convert/impl/BinaryTreeStepper.scala | 19 +- .../convert/impl/TableStepper.scala | 10 +- .../scala/collection/immutable/HashMap.scala | 2 +- .../collection/immutable/RedBlackTree.scala | 64 ++--- .../scala/collection/immutable/TreeSet.scala | 66 ++--- .../scala/collection/immutable/Vector.scala | 22 +- .../mutable/CollisionProofHashMap.scala | 257 +++++++++--------- .../scala/collection/mutable/HashMap.scala | 1 - .../scala/collection/mutable/HashSet.scala | 5 +- library/src/scala/sys/BooleanProp.scala | 2 +- library/src/scala/sys/Prop.scala | 2 +- 14 files changed, 243 insertions(+), 245 deletions(-) diff --git a/library/src/scala/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 9ab7cb787027..79aa35a956e1 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -756,7 +756,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 | Null = leading + private[this] var myLeading = leading /* Status flag meanings: * -1 not yet accessed * 0 single element waiting in leading @@ -771,14 +771,14 @@ 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.nn.finish()) { status = 0 ; true } else { status = 1 ; myLeading = null ; hasNext } + if (myLeading.finish()) { status = 0 ; true } else { status = 1 ; myLeading = null.asInstanceOf[Leading]; hasNext } } def next() = { if (hasNext) { if (status == 0) { status = 1 - val res = myLeading.nn.trailer - myLeading = null + val res = myLeading.trailer + myLeading = null.asInstanceOf[Leading] res } else { status = 1 diff --git a/library/src/scala/collection/View.scala b/library/src/scala/collection/View.scala index 9697a31dbbc4..3c74825f7391 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -465,7 +465,7 @@ object View extends IterableFactory[View] { if(pos == maxlen) pos = 0 len += 1 } - underlying = null.asInstanceOf[Iterator[A]^] // allow GC of underlying iterator + underlying = null.asInstanceOf // allow GC of underlying iterator if(len > maxlen) len = maxlen pos = pos - len if(pos < 0) pos += maxlen diff --git a/library/src/scala/collection/concurrent/TrieMap.scala b/library/src/scala/collection/concurrent/TrieMap.scala index a40504fd7268..77cf96e62225 100644 --- a/library/src/scala/collection/concurrent/TrieMap.scala +++ b/library/src/scala/collection/concurrent/TrieMap.scala @@ -28,7 +28,7 @@ import scala.collection.mutable.GrowableBuilder import scala.util.Try import scala.util.hashing.Hashing -private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen, equiv: Equiv[K]) extends INodeBase[K, V](g) { +private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, equiv: Equiv[K]) extends INodeBase[K, V](g) { import INodeBase._ WRITE(bn) @@ -43,14 +43,14 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen, equiv: E def GCAS_READ(ct: TrieMap[K, V]): MainNode[K, V] = { val m = /*READ*/mainnode - val prevval = /*READ*/m.prev + val prevval: MainNode[K, V] | Null = /*READ*/m.prev if (prevval eq null) m else GCAS_Complete(m, ct) } @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: TrieMap[K, V]): MainNode[K, V] = if (m eq null) null else { // complete the GCAS - val prev = /*READ*/m.prev + val prev: MainNode[K, V] | Null = /*READ*/m.prev val ctr = ct.readRoot(abort = true) prev match { @@ -700,7 +700,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater private[this] var hashingobj = if (hashf.isInstanceOf[Hashing.Default[_]]) new TrieMap.MangledHashing[K] else hashf private[this] var equalityobj = ef @transient - private[this] var rootupdater = rtupd + private[this] var rootupdater: AtomicReferenceFieldUpdater[TrieMap[K, V], AnyRef] | Null = rtupd def hashing = hashingobj def equality = equalityobj @volatile private var root = r @@ -750,7 +750,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater } } - private def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv) + private def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.nn.compareAndSet(this, ov, nv) private[collection] def readRoot(abort: Boolean = false): INode[K, V] = RDCSS_READ_ROOT(abort) @@ -859,7 +859,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater @tailrec def snapshot(): TrieMap[K, V] = { val r = RDCSS_READ_ROOT() val expmain = r.gcasRead(this) - if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new TrieMap(r.copyToGen(new Gen, this), rootupdater, hashing, equality) + if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new TrieMap(r.copyToGen(new Gen, this), rootupdater.nn, hashing, equality) else snapshot() } @@ -1075,23 +1075,23 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: private val stack = new Array[Array[BasicNode]](7) private val stackpos = new Array[Int](7) private var depth = -1 - private var subiter: Iterator[(K, V)] = null - private var current: KVNode[K, V] = null + @annotation.stableNull private var subiter: Iterator[(K, V)] | Null = null + @annotation.stableNull private var current: KVNode[K, V] | Null = null if (mustInit) initialize() def hasNext = (current ne null) || (subiter ne null) def next() = if (hasNext) { - var r: (K, V) = null + var r: (K, V) | Null = null if (subiter ne null) { - r = subiter.next() + r = subiter.nn.next() checkSubiter() } else { - r = current.kvPair + r = current.nn.kvPair advance() } - r + r.nn } else Iterator.empty.next() private def readin(in: INode[K, V]) = in.gcasRead(ct) match { @@ -1110,7 +1110,7 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: case mainNode => throw new MatchError(mainNode) } - private def checkSubiter() = if (!subiter.hasNext) { + private def checkSubiter() = if (!subiter.nn.hasNext) { subiter = null advance() } @@ -1153,7 +1153,7 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: // this one needs to be evaluated if (this.subiter == null) it.subiter = null else { - val lst = this.subiter.to(immutable.List) + val lst = this.subiter.nn.to(immutable.List) this.subiter = lst.iterator it.subiter = lst.iterator } diff --git a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala index 4e8a844c1ac8..01a3c60865eb 100644 --- a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala +++ b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala @@ -14,7 +14,6 @@ package scala.collection.convert package impl import scala.language.`2.13` -import scala.language.unsafeNulls import java.util.Spliterator @@ -90,7 +89,7 @@ extends EfficientSplit { * * Right now overwrites everything so could allow reuse, but isn't used for it. */ - private[impl] final def initialize(root: T, size: Int): Unit = + private[impl] final def initialize(root: T | Null, size: Int): Unit = if (root eq null) { maxLength = 0 myCurrent = null @@ -158,11 +157,11 @@ with AnyStepper[A] { } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): AnyBinaryTreeStepper[A, T] = + def semiclone(maxL: Int, myC: T | Null, 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 <: 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 | Null, 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 @@ -184,11 +183,11 @@ with DoubleStepper { } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): DoubleBinaryTreeStepper[T] = + def semiclone(maxL: Int, myC: T | Null, 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 <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Double): DoubleBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T | Null, 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 @@ -210,11 +209,11 @@ with IntStepper { } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): IntBinaryTreeStepper[T] = + def semiclone(maxL: Int, myC: T | Null, 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 <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Int): IntBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T | Null, 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 @@ -237,11 +236,11 @@ with LongStepper { } else Stepper.throwNSEE() - def semiclone(maxL: Int, myC: T, stk: Array[AnyRef | Null], ix: Int): LongBinaryTreeStepper[T] = + def semiclone(maxL: Int, myC: T | Null, 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 <: AnyRef](maxLength: Int, root: T, left: T => T, right: T => T, extract: T => Long): LongBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T | Null, 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/TableStepper.scala b/library/src/scala/collection/convert/impl/TableStepper.scala index 089fe6bf12af..acdd1c57ec64 100644 --- a/library/src/scala/collection/convert/impl/TableStepper.scala +++ b/library/src/scala/collection/convert/impl/TableStepper.scala @@ -18,7 +18,7 @@ import scala.collection.Stepper.EfficientSplit import scala.collection._ 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 + protected var maxLength: Int, protected val table: Array[I | Null], 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 @@ -71,7 +71,7 @@ extends EfficientSplit { private[collection] final class AnyTableStepper[A, I <: AnyRef]( - _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => A, _i0: Int, _iN: Int + _maxLength: Int, _table: Array[I | Null], 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] { @@ -88,7 +88,7 @@ with AnyStepper[A] { private[collection] final class DoubleTableStepper[I <: AnyRef]( - _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Double, _i0: Int, _iN: Int + _maxLength: Int, _table: Array[I | Null], iterate: I => I, extract: I => Double, _i0: Int, _iN: Int ) extends TableStepperBase[Double, I, DoubleStepper, DoubleTableStepper[I]](_maxLength, _table, _i0, _iN) with DoubleStepper { @@ -105,7 +105,7 @@ with DoubleStepper { private[collection] final class IntTableStepper[I <: AnyRef]( - _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Int, _i0: Int, _iN: Int + _maxLength: Int, _table: Array[I | Null], iterate: I => I, extract: I => Int, _i0: Int, _iN: Int ) extends TableStepperBase[Int, I, IntStepper, IntTableStepper[I]](_maxLength, _table, _i0, _iN) with IntStepper { @@ -122,7 +122,7 @@ with IntStepper { private[collection] final class LongTableStepper[I <: AnyRef]( - _maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Long, _i0: Int, _iN: Int + _maxLength: Int, _table: Array[I | Null], iterate: I => I, extract: I => Long, _i0: Int, _iN: Int ) extends TableStepperBase[Long, I, LongStepper, LongTableStepper[I]](_maxLength, _table, _i0, _iN) with LongStepper { diff --git a/library/src/scala/collection/immutable/HashMap.scala b/library/src/scala/collection/immutable/HashMap.scala index aa1aa7ad714d..2b91a153b733 100644 --- a/library/src/scala/collection/immutable/HashMap.scala +++ b/library/src/scala/collection/immutable/HashMap.scala @@ -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] | Null = { + def removed[V1 >: V](key: K, originalHash: Int, keyHash: Int, shift: Int): BitmapIndexedMapNode[K, V1] = { val mask = maskFrom(keyHash, shift) val bitpos = bitposFrom(mask) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index edbb2186da4f..363ea921d957 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -46,23 +46,23 @@ private[collection] object RedBlackTree { tree } - def isEmpty(tree: Tree[_, _]): Boolean = tree eq null + def isEmpty(tree: Tree[_, _] | Null): Boolean = tree eq null - def contains[A: Ordering](tree: Tree[A, _], x: A): Boolean = lookup(tree, x) ne null - def get[A: Ordering, B](tree: Tree[A, B], x: A): Option[B] = lookup(tree, x) match { + def contains[A: Ordering](tree: Tree[A, _] | Null, x: A): Boolean = lookup(tree, x) ne null + def get[A: Ordering, B](tree: Tree[A, B] | Null, x: A): Option[B] = lookup(tree, x) match { case null => None case found => Some(found.value) } @tailrec - def lookup[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def lookup[A, B](tree: Tree[A, B] | Null, x: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if (tree eq null) null else { val cmp = ordering.compare(x, tree.key) if (cmp < 0) lookup(tree.left, x) else if (cmp > 0) lookup(tree.right, x) else tree } private[immutable] abstract class Helper[A](implicit val ordering: Ordering[A]) { - def beforePublish[B](tree: Tree[A, B]): Tree[A, B] = { + def beforePublish[B](tree: Tree[A, B] | Null): Tree[A, B] | Null = { if (tree eq null) tree else if (tree.isMutable) { val res = tree.mutableBlack.makeImmutable @@ -191,22 +191,22 @@ private[collection] object RedBlackTree { } 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 { + def update[A: Ordering, B, B1 >: B](tree: Tree[A, B] | Null, k: A, v: B1, overwrite: Boolean): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) + def delete[A: Ordering, B](tree: Tree[A, B] | Null, k: A): Tree[A, B] = blacken(del(tree, k)) + def rangeImpl[A: Ordering, B](tree: Tree[A, B] | Null, from: Option[A], until: Option[A]): Tree[A, B]= (from, until) match { case (Some(from), Some(until)) => this.range(tree, from, until) case (Some(from), None) => this.from(tree, from) case (None, Some(until)) => this.until(tree, until) case (None, None) => tree } - def range[A: Ordering, B](tree: Tree[A, B], from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) - def from[A: Ordering, B](tree: Tree[A, B], from: A): Tree[A, B] = blacken(doFrom(tree, from)) - def to[A: Ordering, B](tree: Tree[A, B], to: A): Tree[A, B] = blacken(doTo(tree, to)) - def until[A: Ordering, B](tree: Tree[A, B], key: A): Tree[A, B] = blacken(doUntil(tree, key)) + def range[A: Ordering, B](tree: Tree[A, B] | Null, from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) + def from[A: Ordering, B](tree: Tree[A, B] | Null, from: A): Tree[A, B] = blacken(doFrom(tree, from)) + def to[A: Ordering, B](tree: Tree[A, B] | Null, to: A): Tree[A, B] = blacken(doTo(tree, to)) + def until[A: Ordering, B](tree: Tree[A, B] | Null, key: A): Tree[A, B] = blacken(doUntil(tree, key)) - def drop[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = blacken(doDrop(tree, n)) - 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 drop[A: Ordering, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] = blacken(doDrop(tree, n)) + def take[A: Ordering, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] = blacken(doTake(tree, n)) + def slice[A: Ordering, B](tree: Tree[A, B] | Null, from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) def smallest[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { if (tree eq null) throw new NoSuchElementException("empty tree") @@ -248,7 +248,7 @@ private[collection] object RedBlackTree { /** * Returns the smallest node with a key larger than or equal to `x`. Returns `null` if there is no such node. */ - def minAfter[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def minAfter[A, B](tree: Tree[A, B] | Null, x: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if (tree eq null) null else { val cmp = ordering.compare(x, tree.key) if (cmp == 0) tree else if (cmp < 0) { @@ -260,7 +260,7 @@ private[collection] object RedBlackTree { /** * Returns the largest node with a key smaller than `x`. Returns `null` if there is no such node. */ - def maxBefore[A, B](tree: Tree[A, B], x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def maxBefore[A, B](tree: Tree[A, B] | Null, x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { val cmp = ordering.compare(x, tree.key) if (cmp <= 0) maxBefore(tree.left, x) else { @@ -269,21 +269,21 @@ private[collection] object RedBlackTree { } } - def foreach[A,B,U](tree:Tree[A,B], f:((A,B)) => U):Unit = if (tree ne null) _foreach(tree,f) + def foreach[A,B,U](tree:Tree[A,B] | Null, f:((A,B)) => U):Unit = if (tree ne null) _foreach(tree,f) - def keysEqual[A: Ordering, X, Y](a: Tree[A, X], b: Tree[A, Y]): Boolean = { + def keysEqual[A: Ordering, X, Y](a: Tree[A, X] | Null, b: Tree[A, Y] | Null): Boolean = { if (a eq b) true else if (a eq null) false else if (b eq null) false else a.count == b.count && (new EqualsIterator(a)).sameKeys(new EqualsIterator(b)) } - def valuesEqual[A: Ordering, X, Y](a: Tree[A, X], b: Tree[A, Y]): Boolean = { + def valuesEqual[A: Ordering, X, Y](a: Tree[A, X] | Null, b: Tree[A, Y] | Null): Boolean = { if (a eq b) true else if (a eq null) false else if (b eq null) false else a.count == b.count && (new EqualsIterator(a)).sameValues(new EqualsIterator(b)) } - def entriesEqual[A: Ordering, X, Y](a: Tree[A, X], b: Tree[A, Y]): Boolean = { + def entriesEqual[A: Ordering, X, Y](a: Tree[A, X] | Null, b: Tree[A, Y] | Null): Boolean = { if (a eq b) true else if (a eq null) false else if (b eq null) false @@ -296,7 +296,7 @@ private[collection] object RedBlackTree { if (tree.right ne null) _foreach(tree.right, f) } - def foreachKey[A, U](tree:Tree[A,_], f: A => U):Unit = if (tree ne null) _foreachKey(tree,f) + def foreachKey[A, U](tree:Tree[A,_] | Null, f: A => U):Unit = if (tree ne null) _foreachKey(tree,f) private[this] def _foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = { if (tree.left ne null) _foreachKey(tree.left, f) @@ -304,7 +304,7 @@ private[collection] object RedBlackTree { if (tree.right ne null) _foreachKey(tree.right, f) } - def foreachEntry[A, B, U](tree:Tree[A,B], f: (A, B) => U):Unit = if (tree ne null) _foreachEntry(tree,f) + def foreachEntry[A, B, U](tree:Tree[A,B] | Null, f: (A, B) => U):Unit = if (tree ne null) _foreachEntry(tree,f) private[this] def _foreachEntry[A, B, U](tree: Tree[A, B], f: (A, B) => U): Unit = { if (tree.left ne null) _foreachEntry(tree.left, f) @@ -312,9 +312,9 @@ private[collection] object RedBlackTree { if (tree.right ne null) _foreachEntry(tree.right, f) } - def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) - def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) - def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) + def iterator[A: Ordering, B](tree: Tree[A, B] | Null, start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) + def keysIterator[A: Ordering](tree: Tree[A, _] | Null, start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) + def valuesIterator[A: Ordering, B](tree: Tree[A, B] | Null, start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) @tailrec def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { @@ -324,10 +324,10 @@ private[collection] object RedBlackTree { else tree } - def isBlack(tree: Tree[_, _]) = (tree eq null) || tree.isBlack + def isBlack(tree: Tree[_, _] | Null) = (tree eq null) || tree.isBlack - @`inline` private[this] def isRedTree(tree: Tree[_, _]) = (tree ne null) && tree.isRed - @`inline` private[this] def isBlackTree(tree: Tree[_, _]) = (tree ne null) && tree.isBlack + @`inline` private[this] def isRedTree(tree: Tree[_, _] | Null) = (tree ne null) && tree.isRed + @`inline` private[this] def isBlackTree(tree: Tree[_, _] | Null) = (tree ne null) && tree.isBlack private[this] def blacken[A, B](t: Tree[A, B] | Null): Tree[A, B] = if (t eq null) null else t.black @@ -974,7 +974,7 @@ private[collection] object RedBlackTree { f(1, size) } - def transform[A, B, C](t: Tree[A, B], f: (A, B) => C): Tree[A, C] = + def transform[A, B, C](t: Tree[A, B] | Null, f: (A, B) => C): Tree[A, C] | Null = if(t eq null) null else { val k = t.key @@ -990,7 +990,7 @@ private[collection] object RedBlackTree { else mkTree(t.isBlack, k, v2, l2, r2) } - def filterEntries[A, B](t: Tree[A, B], f: (A, B) => Boolean): Tree[A, B] = if(t eq null) null else { + def filterEntries[A, B](t: Tree[A, B] | Null, f: (A, B) => Boolean): Tree[A, B] | Null = if(t eq null) null else { def fk(t: Tree[A, B]): Tree[A, B] = { val k = t.key val v = t.value @@ -1008,7 +1008,7 @@ private[collection] object RedBlackTree { private[this] val null2 = (null, null) - def partitionEntries[A, B](t: Tree[A, B], p: (A, B) => Boolean): (Tree[A, B], Tree[A, B]) = if(t eq null) (null, null) else { + def partitionEntries[A, B](t: Tree[A, B] | Null, p: (A, B) => Boolean): (Tree[A, B] | Null, Tree[A, B] | Null) = if(t eq null) (null, null) else { if (t eq null) null2 else { object partitioner { diff --git a/library/src/scala/collection/immutable/TreeSet.scala b/library/src/scala/collection/immutable/TreeSet.scala index 8a34204e44a1..faf55def414d 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -59,13 +59,13 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ override def isEmpty = size == 0 - override def head: A = RB.smallest(tree.nn).key + override def head: A = RB.smallest(tree).key - override def last: A = RB.greatest(tree.nn).key + override def last: A = RB.greatest(tree).key - override def tail: TreeSet[A] = new TreeSet(RB.tail(tree.nn)) + override def tail: TreeSet[A] = new TreeSet(RB.tail(tree)) - override def init: TreeSet[A] = new TreeSet(RB.init(tree.nn)) + override def init: TreeSet[A] = new TreeSet(RB.init(tree)) 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.nn, n)) + else new TreeSet(RB.drop(tree, n)) } override def take(n: Int): TreeSet[A] = { if (n <= 0) empty else if (n >= size) this - else new TreeSet(RB.take(tree.nn, n)) + else new TreeSet(RB.take(tree, 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.nn, from, until)) + else new TreeSet(RB.slice(tree, 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.nn, f) + override def foreach[U](f: A => U): Unit = RB.foreachKey(tree, f) override def minAfter(key: A): Option[A] = { - val v = RB.minAfter(tree.nn, key) + val v = RB.minAfter(tree, key) if (v eq null) Option.empty else Some(v.key) } override def maxBefore(key: A): Option[A] = { - val v = RB.maxBefore(tree.nn, key) + val v = RB.maxBefore(tree, key) if (v eq null) Option.empty else Some(v.key) } - def iterator: Iterator[A] = RB.keysIterator(tree.nn) + def iterator: Iterator[A] = RB.keysIterator(tree) - def iteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree.nn, Some(start)) + def iteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree, 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.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)) + 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)) } 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.nn, elem) + def contains(elem: A): Boolean = RB.contains(tree, elem) - override def range(from: A, until: A): TreeSet[A] = newSetOrSelf(RB.range(tree.nn, from, until)) + override def range(from: A, until: A): TreeSet[A] = newSetOrSelf(RB.range(tree, from, until)) - def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = newSetOrSelf(RB.rangeImpl(tree.nn, from, until)) + def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = newSetOrSelf(RB.rangeImpl(tree, 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.nn, elem, null, overwrite = false)) + newSetOrSelf(RB.update(tree, 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.nn, elem)) + newSetOrSelf(RB.delete(tree, 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.nn, ts.tree.nn) + RB.union(tree, ts.tree) case _ => val it = that.iterator - var t = tree.nn + var t = tree 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.nn, ts.tree.nn)) + newSetOrSelf(RB.difference(tree, ts.tree)) 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.nn + var currentTree = tree 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.nn, ts.tree.nn)) + newSetOrSelf(RB.intersect(tree, ts.tree)) 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.nn, ts.tree.nn)) + newSetOrSelf(RB.difference(tree, ts.tree)) case _ => super.diff(that) } - override def filter(f: A => Boolean): TreeSet[A] = newSetOrSelf(RB.filterEntries[A, Any](tree.nn, {(k, _) => f(k)})) + override def filter(f: A => Boolean): TreeSet[A] = newSetOrSelf(RB.filterEntries[A, Any](tree, {(k, _) => f(k)})) override def partition(p: A => Boolean): (TreeSet[A], TreeSet[A]) = { - val (l, r) = RB.partitionEntries(tree.nn, {(a:A, _: Any) => p(a)}) + val (l, r) = RB.partitionEntries(tree, {(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.nn, that.tree.nn) + case that: TreeSet[A @unchecked] if ordering == that.ordering => RB.keysEqual(tree, that.tree) case _ => super.equals(obj) } @@ -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.nn), ts.tree)(ordering) + else tree = RB.union(beforePublish(tree), 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.nn), ts.tree0)(ordering) + else tree = RB.union(beforePublish(tree), 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.nn))(ordering) + override def result(): TreeSet[A] = new TreeSet[A](beforePublish(tree))(ordering) } } diff --git a/library/src/scala/collection/immutable/Vector.scala b/library/src/scala/collection/immutable/Vector.scala index 8017b7b7aa06..afb357b25189 100644 --- a/library/src/scala/collection/immutable/Vector.scala +++ b/library/src/scala/collection/immutable/Vector.scala @@ -265,7 +265,7 @@ sealed abstract class Vector[+A] private[immutable] (private[immutable] final va /** Number of slices */ protected[immutable] def vectorSliceCount: Int /** Slice at index */ - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] /** Length of all slices up to and including index */ protected[immutable] def vectorSlicePrefixLength(idx: Int): Int @@ -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] | Null = null + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = null.asInstanceOf[Array[_ <: AnyRef | Null]] protected[immutable] def vectorSlicePrefixLength(idx: Int): Int = 0 override def equals(o: Any): Boolean = { @@ -426,7 +426,7 @@ private final class Vector1[+A](_data1: Arr1) extends VectorImpl[A](_data1) { else new Vector1(copyInit(prefix1)) protected[immutable] def vectorSliceCount: Int = 1 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = prefix1 + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = prefix1 protected[immutable] def vectorSlicePrefixLength(idx: Int): Int = prefix1.length override protected[this] def prependedAll0[B >: A](prefix: collection.IterableOnce[B]^, k: Int): Vector[B] = @@ -513,7 +513,7 @@ private final class Vector2[+A](_prefix1: Arr1, private[immutable] val len1: Int else slice0(0, length0-1) protected[immutable] def vectorSliceCount: Int = 3 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = (idx: @switch) match { + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = (idx: @switch) match { case 0 => prefix1 case 1 => data2 case 2 => suffix1 @@ -631,7 +631,7 @@ private final class Vector3[+A](_prefix1: Arr1, private[immutable] val len1: Int else slice0(0, length0-1) protected[immutable] def vectorSliceCount: Int = 5 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = (idx: @switch) match { + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = (idx: @switch) match { case 0 => prefix1 case 1 => prefix2 case 2 => data3 @@ -770,7 +770,7 @@ private final class Vector4[+A](_prefix1: Arr1, private[immutable] val len1: Int else slice0(0, length0-1) protected[immutable] def vectorSliceCount: Int = 7 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = (idx: @switch) match { + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = (idx: @switch) match { case 0 => prefix1 case 1 => prefix2 case 2 => prefix3 @@ -930,7 +930,7 @@ private final class Vector5[+A](_prefix1: Arr1, private[immutable] val len1: Int else slice0(0, length0-1) protected[immutable] def vectorSliceCount: Int = 9 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = (idx: @switch) match { + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = (idx: @switch) match { case 0 => prefix1 case 1 => prefix2 case 2 => prefix3 @@ -1111,7 +1111,7 @@ private final class Vector6[+A](_prefix1: Arr1, private[immutable] val len1: Int else slice0(0, length0-1) protected[immutable] def vectorSliceCount: Int = 11 - protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef] = (idx: @switch) match { + protected[immutable] def vectorSlice(idx: Int): Array[_ <: AnyRef | Null] = (idx: @switch) match { case 0 => prefix1 case 1 => prefix2 case 2 => prefix3 @@ -2120,7 +2120,7 @@ private object VectorStatics { final val empty5: Arr5 = new Array(0) final val empty6: Arr6 = new Array(0) - final def foreachRec[T <: AnyRef, A, U](level: Int, a: Array[T], f: A => U): Unit = { + final def foreachRec[T <: AnyRef | Null, A, U](level: Int, a: Array[T], f: A => U): Unit = { var i = 0 val len = a.length if(level == 0) { @@ -2131,7 +2131,7 @@ private object VectorStatics { } else { val l = level-1 while(i < len) { - foreachRec(l, a(i).asInstanceOf[Array[AnyRef]], f) + foreachRec(l, a(i).asInstanceOf[Array[AnyRef | Null]], f) i += 1 } } @@ -2274,7 +2274,7 @@ private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLe private[this] def advanceSlice(): Unit = { if(!hasNext) Iterator.empty.next() sliceIdx += 1 - var slice: Array[_ <: AnyRef] = v.vectorSlice(sliceIdx) + var slice: Array[_ <: AnyRef | Null] = v.vectorSlice(sliceIdx) while(slice.length == 0) { sliceIdx += 1 slice = v.vectorSlice(sliceIdx) diff --git a/library/src/scala/collection/mutable/CollisionProofHashMap.scala b/library/src/scala/collection/mutable/CollisionProofHashMap.scala index 6519df0ce3a2..e186bb4415c1 100644 --- a/library/src/scala/collection/mutable/CollisionProofHashMap.scala +++ b/library/src/scala/collection/mutable/CollisionProofHashMap.scala @@ -15,7 +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 @@ -50,7 +50,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double private[this] type LLNode = CollisionProofHashMap.LLNode[K, V] /** The actual hash table. */ - private[this] var table: Array[Node] = new Array[Node](tableSizeFor(initialCapacity)) + private[this] var table: Array[Node | Null] = new Array[Node | Null](tableSizeFor(initialCapacity)) /** The next size value at which to resize (capacity * load factor). */ private[this] var threshold: Int = newThreshold(table.length) @@ -98,7 +98,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double } } - @`inline` private[this] def findNode(elem: K): Node = { + @`inline` private[this] def findNode(elem: K): Node | Null = { val hash = computeHash(elem) table(index(hash)) match { case null => null @@ -124,25 +124,25 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double def addOne(elem: (K, V)): this.type = { put0(elem._1, elem._2, getOld = false); this } - @`inline` private[this] def put0(key: K, value: V, getOld: Boolean): Some[V] = { + @`inline` 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 = { val res = table(idx) match { case n: RBNode @uc => insert(n, idx, key, hash, value) case _old => - val old: LLNode = _old.asInstanceOf[LLNode] + val old: LLNode | Null = _old.asInstanceOf[LLNode | Null] if(old eq null) { table(idx) = new LLNode(key, hash, value, null) } else { var remaining = CollisionProofHashMap.treeifyThreshold - var prev: LLNode = null - var n = old + var prev: LLNode | Null = null + var n: LLNode | Null = old while((n ne null) && n.hash <= hash && remaining > 0) { if(n.hash == hash && key == n.key) { val old = n.value @@ -168,7 +168,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double private[this] def treeify(old: LLNode, idx: Int): Unit = { table(idx) = CollisionProofHashMap.leaf(old.key, old.hash, old.value, red = false, null) - var n: LLNode = old.next + var n: LLNode | Null = old.next while(n ne null) { val root = table(idx).asInstanceOf[RBNode] insertIntoExisting(root, idx, n.key, n.hash, n.value, root) @@ -218,7 +218,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double protected[this] def extract(node: RBNode): R private[this] var i = 0 - private[this] var node: Node = null + private[this] var node: Node | Null = null private[this] val len = table.length def hasNext: Boolean = { @@ -287,13 +287,14 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double } @`inline` private[this] def reallocTable(newlen: Int) = { - table = new Array(newlen) + table = new Array[Node | Null](newlen) threshold = newThreshold(table.length) } - @`inline` private[this] def splitBucket(tree: Node, lowBucket: Int, highBucket: Int, mask: Int): Unit = tree match { + @`inline` private[this] def splitBucket(tree: Node | Null, lowBucket: Int, highBucket: Int, mask: Int): Unit = tree match { case t: LLNode @uc => splitBucket(t, lowBucket, highBucket, mask) case t: RBNode @uc => splitBucket(t, lowBucket, highBucket, mask) + case null => } private[this] def splitBucket(list: LLNode, lowBucket: Int, highBucket: Int, mask: Int): Unit = { @@ -303,7 +304,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double //preHigh.next = null var lastLow: LLNode = preLow var lastHigh: LLNode = preHigh - var n = list + var n: LLNode | Null = list while(n ne null) { val next = n.next if((n.hash & mask) == 0) { // keep low @@ -462,8 +463,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double ///////////////////// RedBlackTree code derived from mutable.RedBlackTree: - @`inline` private[this] def isRed(node: RBNode) = (node ne null) && node.red - @`inline` private[this] def isBlack(node: RBNode) = (node eq null) || !node.red + @`inline` private[this] def isRed(node: RBNode | Null) = (node ne null) && node.nn.red + @`inline` private[this] def isBlack(node: RBNode | Null) = (node eq null) || !node.nn.red @unused @`inline` private[this] def compare(key: K, hash: Int, node: LLNode): Int = { val i = hash - node.hash @@ -490,52 +491,52 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double table(bucket) = fixAfterInsert(_root, z) return true } - else insertIntoExisting(_root, bucket, key, hash, value, next) + else insertIntoExisting(_root, bucket, key, hash, value, next.nn) } } - private[this] final def insert(tree: RBNode, bucket: Int, key: K, hash: Int, value: V): Boolean = { + private[this] final def insert(tree: RBNode | Null, bucket: Int, key: K, hash: Int, value: V): Boolean = { if(tree eq null) { table(bucket) = CollisionProofHashMap.leaf(key, hash, value, red = false, null) true - } else insertIntoExisting(tree, bucket, key, hash, value, tree) + } else insertIntoExisting(tree.nn, bucket, key, hash, value, tree.nn) } private[this] def fixAfterInsert(_root: RBNode, node: RBNode): RBNode = { var root = _root var z = node while (isRed(z.parent)) { - if (z.parent eq z.parent.parent.left) { - val y = z.parent.parent.right + if (z.parent.nn eq z.parent.nn.parent.nn.left) { + val y = z.parent.nn.parent.nn.right if (isRed(y)) { - z.parent.red = false - y.red = false - z.parent.parent.red = true - z = z.parent.parent + z.parent.nn.red = false + y.nn.red = false + z.parent.nn.parent.nn.red = true + z = z.parent.nn.parent.nn } else { - if (z eq z.parent.right) { - z = z.parent + if (z eq z.parent.nn.right) { + z = z.parent.nn root = rotateLeft(root, z) } - z.parent.red = false - z.parent.parent.red = true - root = rotateRight(root, z.parent.parent) + z.parent.nn.red = false + z.parent.nn.parent.nn.red = true + root = rotateRight(root, z.parent.nn.parent.nn) } } else { // symmetric cases - val y = z.parent.parent.left + val y = z.parent.nn.parent.nn.left if (isRed(y)) { - z.parent.red = false - y.red = false - z.parent.parent.red = true - z = z.parent.parent + z.parent.nn.red = false + y.nn.red = false + z.parent.nn.parent.nn.red = true + z = z.parent.nn.parent.nn } else { - if (z eq z.parent.left) { - z = z.parent + if (z eq z.parent.nn.left) { + z = z.parent.nn root = rotateRight(root, z) } - z.parent.red = false - z.parent.parent.red = true - root = rotateLeft(root, z.parent.parent) + z.parent.nn.red = false + z.parent.nn.parent.nn.red = true + root = rotateLeft(root, z.parent.nn.parent.nn) } } } @@ -553,34 +554,34 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double val oldValue = z.value var y = z var yIsRed = y.red - var x: RBNode = null - var xParent: RBNode = null + var x: RBNode | Null = null + var xParent: RBNode | Null = null if (z.left eq null) { x = z.right - root = transplant(root, z, z.right) + root = transplant(root, z, z.right.nn) xParent = z.parent } else if (z.right eq null) { x = z.left - root = transplant(root, z, z.left) + root = transplant(root, z, z.left.nn) xParent = z.parent } else { - y = CollisionProofHashMap.minNodeNonNull(z.right) + y = CollisionProofHashMap.minNodeNonNull(z.right.nn) yIsRed = y.red x = y.right - if (y.parent eq z) xParent = y + if (y.parent.nn eq z) xParent = y else { xParent = y.parent - root = transplant(root, y, y.right) + root = transplant(root, y, y.right.nn) y.right = z.right - y.right.parent = y + y.right.nn.parent = y } root = transplant(root, z, y) y.left = z.left - y.left.parent = y + y.left.nn.parent = y y.red = z.red } @@ -590,67 +591,67 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double } else Statics.pfMarker } - private[this] def fixAfterDelete(_root: RBNode, node: RBNode, parent: RBNode): RBNode = { + private[this] def fixAfterDelete(_root: RBNode, node: RBNode | Null, parent: RBNode | Null): RBNode = { var root = _root var x = node var xParent = parent while ((x ne root) && isBlack(x)) { - if (x eq xParent.left) { - var w = xParent.right + if (x eq xParent.nn.left) { + var w = xParent.nn.right // assert(w ne null) - if (w.red) { - w.red = false - xParent.red = true - root = rotateLeft(root, xParent) - w = xParent.right + if (w.nn.red) { + w.nn.red = false + xParent.nn.red = true + root = rotateLeft(root, xParent.nn) + w = xParent.nn.right } - if (isBlack(w.left) && isBlack(w.right)) { - w.red = true + if (isBlack(w.nn.left) && isBlack(w.nn.right)) { + w.nn.red = true x = xParent } else { - if (isBlack(w.right)) { - w.left.red = false - w.red = true - root = rotateRight(root, w) - w = xParent.right + if (isBlack(w.nn.right)) { + w.nn.left.nn.red = false + w.nn.red = true + root = rotateRight(root, w.nn) + w = xParent.nn.right } - w.red = xParent.red - xParent.red = false - w.right.red = false - root = rotateLeft(root, xParent) + w.nn.red = xParent.nn.red + xParent.nn.red = false + w.nn.right.nn.red = false + root = rotateLeft(root, xParent.nn) x = root } } else { // symmetric cases - var w = xParent.left + var w = xParent.nn.left // assert(w ne null) - if (w.red) { - w.red = false - xParent.red = true - root = rotateRight(root, xParent) - w = xParent.left + if (w.nn.red) { + w.nn.red = false + xParent.nn.red = true + root = rotateRight(root, xParent.nn) + w = xParent.nn.left } - if (isBlack(w.right) && isBlack(w.left)) { - w.red = true + if (isBlack(w.nn.right) && isBlack(w.nn.left)) { + w.nn.red = true x = xParent } else { - if (isBlack(w.left)) { - w.right.red = false - w.red = true - root = rotateLeft(root, w) - w = xParent.left + if (isBlack(w.nn.left)) { + w.nn.right.nn.red = false + w.nn.red = true + root = rotateLeft(root, w.nn) + w = xParent.nn.left } - w.red = xParent.red - xParent.red = false - w.left.red = false - root = rotateRight(root, xParent) + w.nn.red = xParent.nn.red + xParent.nn.red = false + w.nn.left.nn.red = false + root = rotateRight(root, xParent.nn) x = root } } - xParent = x.parent + xParent = x.nn.parent } - if (x ne null) x.red = false + if (x ne null) x.nn.red = false root } @@ -658,16 +659,16 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double @`inline` private[this] def rotateLeft(_root: RBNode, x: RBNode): RBNode = { var root = _root - val y = x.right + val y = x.right.nn x.right = y.left val xp = x.parent - if (y.left ne null) y.left.parent = x + if (y.left ne null) y.left.nn.parent = x y.parent = xp if (xp eq null) root = y - else if (x eq xp.left) xp.left = y - else xp.right = y + else if (x eq xp.nn.left) xp.nn.left = y + else xp.nn.right = y y.left = x x.parent = y @@ -676,16 +677,16 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double @`inline` private[this] def rotateRight(_root: RBNode, x: RBNode): RBNode = { var root = _root - val y = x.left + val y = x.left.nn x.left = y.right val xp = x.parent - if (y.right ne null) y.right.parent = x + if (y.right ne null) y.right.nn.parent = x y.parent = xp if (xp eq null) root = y - else if (x eq xp.right) xp.right = y - else xp.left = y + else if (x eq xp.nn.right) xp.nn.right = y + else xp.nn.left = y y.right = x x.parent = y @@ -699,17 +700,17 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double private[this] def transplant(_root: RBNode, to: RBNode, from: RBNode): RBNode = { var root = _root if (to.parent eq null) root = from - else if (to eq to.parent.left) to.parent.left = from - else to.parent.right = from + else if (to eq to.parent.nn.left) to.parent.nn.left = from + else to.parent.nn.right = from if (from ne null) from.parent = to.parent root } // building - def fromNodes(xs: Iterator[Node], size: Int): RBNode = { + def fromNodes(xs: Iterator[Node], size: Int): RBNode | Null = { val maxUsedDepth = 32 - Integer.numberOfLeadingZeros(size) // maximum depth of non-leaf nodes - def f(level: Int, size: Int): RBNode = size match { + def f(level: Int, size: Int): RBNode | Null = size match { case 0 => null case 1 => val nn = xs.next() @@ -728,8 +729,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double case nn: RBNode @uc => (nn.key, nn.hash, nn.value) } val n = new RBNode(key, hash, value, red = false, left, right, null) - if(left ne null) left.parent = n - right.parent = n + if(left ne null) left.nn.parent = n + if(right ne null) right.nn.parent = n n } f(1, size) @@ -768,7 +769,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { @SerialVersionUID(3L) private final class DeserializationFactory[K, V](val tableLength: Int, val loadFactor: Double, val ordering: Ordering[K]) extends Factory[(K, V), CollisionProofHashMap[K, V]] with Serializable { - def fromSpecific(it: IterableOnce[(K, V)]^): CollisionProofHashMap[K, V] = new CollisionProofHashMap[K, V](tableLength, loadFactor)(ordering) ++= it + def fromSpecific(it: IterableOnce[(K, V)]^): CollisionProofHashMap[K, V] = new CollisionProofHashMap[K, V](tableLength, loadFactor)(using ordering) ++= it def newBuilder: Builder[(K, V), CollisionProofHashMap[K, V]] = CollisionProofHashMap.newBuilder(tableLength, loadFactor)(using ordering) } @@ -790,62 +791,62 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { /////////////////////////// Red-Black Tree Node - final class RBNode[K, V](var key: K, var hash: Int, var value: V, var red: Boolean, var left: RBNode[K, V], var right: RBNode[K, V], var parent: RBNode[K, V]) extends Node { + final class RBNode[K, V](var key: K, var hash: Int, var value: V, var red: Boolean, var left: RBNode[K, V] | Null, var right: RBNode[K, V] | Null, var parent: RBNode[K, V] | Null) extends Node { override def toString: String = "RBNode(" + key + ", " + hash + ", " + value + ", " + red + ", " + left + ", " + right + ")" - @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): RBNode[K, V] = { + @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): RBNode[K, V] | Null = { val cmp = compare(k, h, this) if (cmp < 0) { - if(left ne null) left.getNode(k, h) else null + if(left ne null) left.nn.getNode(k, h) else null } else if (cmp > 0) { - if(right ne null) right.getNode(k, h) else null + if(right ne null) right.nn.getNode(k, h) else null } else this } def foreach[U](f: ((K, V)) => U): Unit = { - if(left ne null) left.foreach(f) + if(left ne null) left.nn.foreach(f) f((key, value)) - if(right ne null) right.foreach(f) + if(right ne null) right.nn.foreach(f) } def foreachEntry[U](f: (K, V) => U): Unit = { - if(left ne null) left.foreachEntry(f) + if(left ne null) left.nn.foreachEntry(f) f(key, value) - if(right ne null) right.foreachEntry(f) + if(right ne null) right.nn.foreachEntry(f) } def foreachNode[U](f: RBNode[K, V] => U): Unit = { - if(left ne null) left.foreachNode(f) + if(left ne null) left.nn.foreachNode(f) f(this) - if(right ne null) right.foreachNode(f) + if(right ne null) right.nn.foreachNode(f) } } - @`inline` private def leaf[A, B](key: A, hash: Int, value: B, red: Boolean, parent: RBNode[A, B]): RBNode[A, B] = + @`inline` private def leaf[A, B](key: A, hash: Int, value: B, red: Boolean, parent: RBNode[A, B] | Null): RBNode[A, B] = new RBNode(key, hash, value, red, null, null, parent) @tailrec private def minNodeNonNull[A, B](node: RBNode[A, B]): RBNode[A, B] = - if (node.left eq null) node else minNodeNonNull(node.left) + if (node.left eq null) node else minNodeNonNull(node.left.nn) /** * Returns the node that follows `node` in an in-order tree traversal. If `node` has the maximum key (and is, * therefore, the last node), this method returns `null`. */ - private def successor[A, B](node: RBNode[A, B]): RBNode[A, B] = { - if (node.right ne null) minNodeNonNull(node.right) + private def successor[A, B](node: RBNode[A, B]): RBNode[A, B] | Null = { + if (node.right ne null) minNodeNonNull(node.right.nn) else { var x = node var y = x.parent - while ((y ne null) && (x eq y.right)) { - x = y - y = y.parent + while ((y ne null) && (x eq y.nn.right)) { + x = y.nn + y = y.nn.parent } y } } - private final class RBNodesIterator[A, B](tree: RBNode[A, B])(implicit @unused ord: Ordering[A]) extends AbstractIterator[RBNode[A, B]] { - private[this] var nextNode: RBNode[A, B] = if(tree eq null) null else minNodeNonNull(tree) + private final class RBNodesIterator[A, B](tree: RBNode[A, B] | Null)(implicit @unused ord: Ordering[A]) extends AbstractIterator[RBNode[A, B]] { + private[this] var nextNode: RBNode[A, B] | Null = if(tree eq null) null else minNodeNonNull(tree.nn) def hasNext: Boolean = nextNode ne null @@ -853,38 +854,38 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { def next(): RBNode[A, B] = nextNode match { case null => Iterator.empty.next() case node => - nextNode = successor(node) - node + nextNode = successor(node.nn) + node.nn } } /////////////////////////// Linked List Node - private final class LLNode[K, V](var key: K, var hash: Int, var value: V, var next: LLNode[K, V]) extends Node { + private final class LLNode[K, V](var key: K, var hash: Int, var value: V, @annotation.stableNull var next: LLNode[K, V] | Null) extends Node { override def toString = s"LLNode($key, $value, $hash) -> $next" private[this] def eq(a: Any, b: Any): Boolean = if(a.asInstanceOf[AnyRef] eq null) b.asInstanceOf[AnyRef] eq null else a.asInstanceOf[AnyRef].equals(b) - @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): LLNode[K, V] = { + @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): LLNode[K, V] | Null = { if(h == hash && eq(k, key) /*ord.compare(k, key) == 0*/) this else if((next eq null) || (hash > h)) null - else next.getNode(k, h) + else next.nn.getNode(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) } @tailrec def foreachNode[U](f: LLNode[K, V] => U): Unit = { f(this) - if(next ne null) next.foreachNode(f) + if(next ne null) next.nn.foreachNode(f) } } } diff --git a/library/src/scala/collection/mutable/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index 01a6e4bbcbee..963d58e608e2 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -15,7 +15,6 @@ 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 diff --git a/library/src/scala/collection/mutable/HashSet.scala b/library/src/scala/collection/mutable/HashSet.scala index f8a56dba4fbf..505108a59ef6 100644 --- a/library/src/scala/collection/mutable/HashSet.scala +++ b/library/src/scala/collection/mutable/HashSet.scala @@ -15,7 +15,6 @@ package mutable import scala.language.`2.13` import language.experimental.captureChecking -import scala.language.unsafeNulls import scala.annotation.tailrec import scala.collection.Stepper.EfficientSplit @@ -161,7 +160,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) table(idx) = new Node(elem, hash, null) case old => var prev: Node[A] | Null = null - var n = old + var n: Node[A] | Null = old while((n ne null) && n.hash <= hash) { if(n.hash == hash && elem == n.key) return false prev = n @@ -271,7 +270,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) preHigh.next = null var lastLow: Node[A] = preLow var lastHigh: Node[A] = preHigh - var n = old + var n: Node[A] | Null = old while(n ne null) { val next = n.next if((n.hash & oldlen) == 0) { // keep low diff --git a/library/src/scala/sys/BooleanProp.scala b/library/src/scala/sys/BooleanProp.scala index 723623d72769..6afe8658c9ce 100644 --- a/library/src/scala/sys/BooleanProp.scala +++ b/library/src/scala/sys/BooleanProp.scala @@ -50,7 +50,7 @@ object BooleanProp { private[sys] class ConstantImpl(val key: String, val value: Boolean) extends BooleanProp { val isSet = value - def set(newValue: String) = "" + value + def set(newValue: String | Null) = "" + value def setValue[T1 >: Boolean](newValue: T1): Boolean = value def get: String = "" + value def option = if (isSet) Some(value) else None diff --git a/library/src/scala/sys/Prop.scala b/library/src/scala/sys/Prop.scala index 0a7c8b678299..1a6d8c584cdc 100644 --- a/library/src/scala/sys/Prop.scala +++ b/library/src/scala/sys/Prop.scala @@ -44,7 +44,7 @@ trait Prop[+T] { * @param newValue the new string value * @return the old value, or null if it was unset. */ - def set(newValue: String): String + def set(newValue: String | Null): String | Null /** Sets the property with a value of the represented type. */ From e2069a5123a9a87d0e85444de0c11e0e3b7e3eb5 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Sun, 31 Aug 2025 02:20:10 +0200 Subject: [PATCH 05/46] Migrate RBT --- .../collection/immutable/RedBlackTree.scala | 318 +++++++++--------- .../scala/collection/immutable/TreeMap.scala | 49 ++- .../scala/collection/immutable/TreeSet.scala | 12 +- 3 files changed, 189 insertions(+), 190 deletions(-) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 363ea921d957..812a1c120905 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -16,7 +16,7 @@ package immutable import scala.language.`2.13` import language.experimental.captureChecking -import scala.language.unsafeNulls +// import scala.language.unsafeNulls import scala.annotation.meta.{getter, setter} import scala.annotation.tailrec @@ -30,15 +30,15 @@ import scala.runtime.Statics.releaseFence * optimizations behind a reasonably clean API. */ private[collection] object RedBlackTree { - def validate[A](tree: Tree[A, _])(implicit ordering: Ordering[A]): tree.type = { + def validate[A](tree: Tree[A, _] | Null)(implicit ordering: Ordering[A]): tree.type = { def impl(tree: Tree[A, _], keyProp: A => Boolean): Int = { assert(keyProp(tree.key), s"key check failed: $tree") if (tree.isRed) { - assert(tree.left == null || tree.left.isBlack, s"red-red left $tree") - assert(tree.right == null || tree.right.isBlack, s"red-red right $tree") + assert(tree.left == null || tree.left.nn.isBlack, s"red-red left $tree") + assert(tree.right == null || tree.right.nn.isBlack, s"red-red right $tree") } - val leftBlacks = if (tree.left == null) 0 else impl(tree.left, k => keyProp(k) && ordering.compare(k, tree.key) < 0) - val rightBlacks = if (tree.right == null) 0 else impl(tree.right, k => keyProp(k) && ordering.compare(k, tree.key) > 0) + val leftBlacks = if (tree.left == null) 0 else impl(tree.left.nn, k => keyProp(k) && ordering.compare(k, tree.key) < 0) + val rightBlacks = if (tree.right == null) 0 else impl(tree.right.nn, k => keyProp(k) && ordering.compare(k, tree.key) > 0) assert(leftBlacks == rightBlacks, s"not balanced: $tree") leftBlacks + (if (tree.isBlack) 1 else 0) } @@ -87,8 +87,8 @@ private[collection] object RedBlackTree { // RED // black(nl.L) nl.KV black // nl.R KV R - val resultLeft = newLeft_left.mutableBlack - val resultRight = tree.mutableBlackWithLeft(newLeft_right) + val resultLeft = newLeft_left.nn.mutableBlack + val resultRight = tree.mutableBlackWithLeft(newLeft_right.nn) newLeft.mutableWithLeftRight(resultLeft, resultRight) } else if (isRedTree(newLeft_right)) { @@ -96,12 +96,12 @@ private[collection] object RedBlackTree { // black nl.R.KV black // nl.L nl.KV nl.R.L nl.R.R KV R - val newLeft_right_right = newLeft_right.right + val newLeft_right_right = newLeft_right.nn.right - val resultLeft = newLeft.mutableBlackWithRight(newLeft_right.left) - val resultRight = tree.mutableBlackWithLeft(newLeft_right_right) + val resultLeft = newLeft.mutableBlackWithRight(newLeft_right.nn.left.nn) + val resultRight = tree.mutableBlackWithLeft(newLeft_right_right.nn) - newLeft_right.mutableWithLeftRight(resultLeft, resultRight) + newLeft_right.nn.mutableWithLeftRight(resultLeft, resultRight) } else { // tree // newLeft KV R @@ -130,10 +130,10 @@ private[collection] object RedBlackTree { // black nr.L.KV black // L KV nr.L.L nr.L.R nr.KV nr.R - val resultLeft = tree.mutableBlackWithRight(newRight_left.left) - val resultRight = newRight.mutableBlackWithLeft(newRight_left.right) + val resultLeft = tree.mutableBlackWithRight(newRight_left.nn.left.nn) + val resultRight = newRight.mutableBlackWithLeft(newRight_left.nn.right.nn) - newRight_left.mutableWithLeftRight(resultLeft, resultRight) + newRight_left.nn.mutableWithLeftRight(resultLeft, resultRight) } else { val newRight_right = newRight.right @@ -142,8 +142,8 @@ private[collection] object RedBlackTree { // black nr.KV black(nr.R) // L KV nr.L - val resultLeft = tree.mutableBlackWithRight(newRight_left) - val resultRight = newRight_right.mutableBlack + val resultLeft = tree.mutableBlackWithRight(newRight_left.nn) + val resultRight = newRight_right.nn.mutableBlack newRight.mutableWithLeftRight(resultLeft, resultRight) } else { @@ -191,50 +191,50 @@ private[collection] object RedBlackTree { } def count(tree: Tree[_, _] | Null) = if (tree eq null) 0 else tree.count - def update[A: Ordering, B, B1 >: B](tree: Tree[A, B] | Null, k: A, v: B1, overwrite: Boolean): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) - def delete[A: Ordering, B](tree: Tree[A, B] | Null, k: A): Tree[A, B] = blacken(del(tree, k)) - def rangeImpl[A: Ordering, B](tree: Tree[A, B] | Null, from: Option[A], until: Option[A]): Tree[A, B]= (from, until) match { + def update[A: Ordering, B, B1 >: B](tree: Tree[A, B] | Null, k: A, v: B1, overwrite: Boolean): Tree[A, B1] | Null = blacken(upd(tree, k, v, overwrite)) + def delete[A: Ordering, B](tree: Tree[A, B] | Null, k: A): Tree[A, B] | Null = blacken(del(tree, k)) + def rangeImpl[A: Ordering, B](tree: Tree[A, B] | Null, from: Option[A], until: Option[A]): Tree[A, B] | Null = (from, until) match { case (Some(from), Some(until)) => this.range(tree, from, until) case (Some(from), None) => this.from(tree, from) case (None, Some(until)) => this.until(tree, until) case (None, None) => tree } - def range[A: Ordering, B](tree: Tree[A, B] | Null, from: A, until: A): Tree[A, B] = blacken(doRange(tree, from, until)) - def from[A: Ordering, B](tree: Tree[A, B] | Null, from: A): Tree[A, B] = blacken(doFrom(tree, from)) - def to[A: Ordering, B](tree: Tree[A, B] | Null, to: A): Tree[A, B] = blacken(doTo(tree, to)) - def until[A: Ordering, B](tree: Tree[A, B] | Null, key: A): Tree[A, B] = blacken(doUntil(tree, key)) + def range[A: Ordering, B](tree: Tree[A, B] | Null, from: A, until: A): Tree[A, B] | Null = blacken(doRange(tree, from, until)) + def from[A: Ordering, B](tree: Tree[A, B] | Null, from: A): Tree[A, B] | Null = blacken(doFrom(tree, from)) + def to[A: Ordering, B](tree: Tree[A, B] | Null, to: A): Tree[A, B] | Null = blacken(doTo(tree, to)) + def until[A: Ordering, B](tree: Tree[A, B] | Null, key: A): Tree[A, B] | Null = blacken(doUntil(tree, key)) - def drop[A: Ordering, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] = blacken(doDrop(tree, n)) - def take[A: Ordering, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] = blacken(doTake(tree, n)) - def slice[A: Ordering, B](tree: Tree[A, B] | Null, from: Int, until: Int): Tree[A, B] = blacken(doSlice(tree, from, until)) + def drop[A: Ordering, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] | Null = blacken(doDrop(tree, n)) + def take[A: Ordering, B](tree: Tree[A, B] | Null, n: Int): Tree[A, B] | Null = blacken(doTake(tree, n)) + def slice[A: Ordering, B](tree: Tree[A, B] | Null, from: Int, until: Int): Tree[A, B] | Null = blacken(doSlice(tree, from, until)) 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 + var result = tree.nn + while (result.left ne null) result = result.left.nn result } 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 + var result = tree.nn + while (result.right ne null) result = result.right.nn result } - def tail[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { - def _tail(tree: Tree[A, B] | Null): Tree[A, B] = + def tail[A, B](tree: Tree[A, B] | Null): Tree[A, B] | Null = { + def _tail(tree: Tree[A, B] | Null): Tree[A, B] | Null= if (tree eq null) throw new NoSuchElementException("empty tree") else { val tl = tree.left if (tl eq null) tree.right - else if (tl.isBlack) balLeft(tree, _tail(tl), tree.right) + else if (tl.nn.isBlack) balLeft(tree, _tail(tl), tree.right) else tree.redWithLeft(_tail(tree.left)) } blacken(_tail(tree)) } - def init[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { - def _init(tree: Tree[A, B]): Tree[A, B] = + def init[A, B](tree: Tree[A, B] | Null): Tree[A, B] | Null = { + def _init(tree: Tree[A, B] | Null): Tree[A, B] | Null = if (tree eq null) throw new NoSuchElementException("empty tree") else { val tr = tree.right @@ -260,7 +260,7 @@ private[collection] object RedBlackTree { /** * Returns the largest node with a key smaller than `x`. Returns `null` if there is no such node. */ - def maxBefore[A, B](tree: Tree[A, B] | Null, x: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { + def maxBefore[A, B](tree: Tree[A, B] | Null, x: A)(implicit ordering: Ordering[A]): Tree[A, B] | Null = if (tree eq null) null else { val cmp = ordering.compare(x, tree.key) if (cmp <= 0) maxBefore(tree.left, x) else { @@ -291,36 +291,36 @@ private[collection] object RedBlackTree { } private[this] def _foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = { - if (tree.left ne null) _foreach(tree.left, f) + if (tree.left ne null) _foreach(tree.left.nn, f) f((tree.key, tree.value)) - if (tree.right ne null) _foreach(tree.right, f) + if (tree.right ne null) _foreach(tree.right.nn, f) } - def foreachKey[A, U](tree:Tree[A,_] | Null, f: A => U):Unit = if (tree ne null) _foreachKey(tree,f) + def foreachKey[A, U](tree: Tree[A,_] | Null, f: A => U):Unit = if (tree ne null) _foreachKey(tree,f) private[this] def _foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = { - if (tree.left ne null) _foreachKey(tree.left, f) + if (tree.left ne null) _foreachKey(tree.left.nn, f) f((tree.key)) - if (tree.right ne null) _foreachKey(tree.right, f) + if (tree.right ne null) _foreachKey(tree.right.nn, f) } - def foreachEntry[A, B, U](tree:Tree[A,B] | Null, f: (A, B) => U):Unit = if (tree ne null) _foreachEntry(tree,f) + def foreachEntry[A, B, U](tree: Tree[A,B] | Null, f: (A, B) => U):Unit = if (tree ne null) _foreachEntry(tree,f) private[this] def _foreachEntry[A, B, U](tree: Tree[A, B], f: (A, B) => U): Unit = { - if (tree.left ne null) _foreachEntry(tree.left, f) + if (tree.left ne null) _foreachEntry(tree.left.nn, f) f(tree.key, tree.value) - if (tree.right ne null) _foreachEntry(tree.right, f) + if (tree.right ne null) _foreachEntry(tree.right.nn, f) } - def iterator[A: Ordering, B](tree: Tree[A, B] | Null, start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) - def keysIterator[A: Ordering](tree: Tree[A, _] | Null, start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) - def valuesIterator[A: Ordering, B](tree: Tree[A, B] | Null, start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) + def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) + def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) + def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) @tailrec def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { val count = this.count(tree.left) - if (n < count) nth(tree.left, n) - else if (n > count) nth(tree.right, n - count - 1) + if (n < count) nth(tree.left.nn, n) + else if (n > count) nth(tree.right.nn, n - count - 1) else tree } @@ -329,14 +329,14 @@ private[collection] object RedBlackTree { @`inline` private[this] def isRedTree(tree: Tree[_, _] | Null) = (tree ne null) && tree.isRed @`inline` private[this] def isBlackTree(tree: Tree[_, _] | Null) = (tree ne null) && tree.isBlack - private[this] def blacken[A, B](t: Tree[A, B] | Null): 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] | Null = 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. private[this] def maybeBlacken[A, B](t: Tree[A, B]): Tree[A, B] = if(isBlack(t)) t else if(isRedTree(t.left) || isRedTree(t.right)) t.black else t - private[this] def mkTree[A, B](isBlack: Boolean, key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = { + private[this] def mkTree[A, B](isBlack: Boolean, key: A, value: B, left: Tree[A, B] | Null, right: Tree[A, B] | Null) = { val sizeAndColour = sizeOf(left) + sizeOf(right) + 1 | (if(isBlack) initialBlackCount else initialRedCount) new Tree(key, value.asInstanceOf[AnyRef], left, right, sizeAndColour) } @@ -356,20 +356,20 @@ private[collection] object RedBlackTree { // RED // black(nl.L) nl.KV black // nl.R KV R - val resultLeft = newLeft_left.black - val resultRight = tree.blackWithLeft(newLeft_right) + val resultLeft = newLeft_left.nn.black + val resultRight = tree.blackWithLeft(newLeft_right.nn) newLeft.withLeftRight(resultLeft, resultRight) } else if (isRedTree(newLeft_right)) { // RED // black nl.R.KV black // nl.L nl.KV nl.R.L nl.R.R KV R - val newLeft_right_right = newLeft_right.right + val newLeft_right_right = newLeft_right.nn.right - val resultLeft = newLeft.blackWithRight(newLeft_right.left) - val resultRight = tree.blackWithLeft(newLeft_right_right) + val resultLeft = newLeft.blackWithRight(newLeft_right.nn.left.nn) + val resultRight = tree.blackWithLeft(newLeft_right_right.nn) - newLeft_right.withLeftRight(resultLeft, resultRight) + newLeft_right.nn.withLeftRight(resultLeft, resultRight) } else { // tree // newLeft KV R @@ -396,18 +396,18 @@ private[collection] object RedBlackTree { // RED // black nr.L.KV black // L KV nr.L.L nr.L.R nr.KV nr.R - val resultLeft = tree.blackWithRight(newRight_left.left) - val resultRight = newRight.blackWithLeft(newRight_left.right) + val resultLeft = tree.blackWithRight(newRight_left.nn.left.nn) + val resultRight = newRight.blackWithLeft(newRight_left.nn.right.nn) - newRight_left.withLeftRight(resultLeft, resultRight) + newRight_left.nn.withLeftRight(resultLeft, resultRight) } else { val newRight_right = newRight.right if (isRedTree(newRight_right)) { // RED // black nr.KV black(nr.R) // L KV nr.L - val resultLeft = tree.blackWithRight(newRight_left) - val resultRight = newRight_right.black + val resultLeft = tree.blackWithRight(newRight_left.nn) + val resultRight = newRight_right.nn.black newRight.withLeftRight(resultLeft, resultRight) } else { @@ -425,7 +425,7 @@ private[collection] object RedBlackTree { } 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) + RedTree(k, v, null: Tree[A, B1] | Null, null: Tree[A, B1] | Null) } else if (k.asInstanceOf[AnyRef] eq tree.key.asInstanceOf[AnyRef]) { if (overwrite) tree.withV(v) @@ -441,7 +441,7 @@ private[collection] object RedBlackTree { else tree } 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) + RedTree(k, v, null: Tree[A, B1] | Null, null: Tree[A, B1] | Null) } else { val rank = count(tree.left) + 1 if (idx < rank) @@ -558,9 +558,9 @@ private[collection] object RedBlackTree { */ private[immutable] final class Tree[A, +B]( @(`inline` @getter @setter) private var _key: A, - @(`inline` @getter @setter) private var _value: AnyRef, - @(`inline` @getter @setter) private var _left: Tree[A, _], - @(`inline` @getter @setter) private var _right: Tree[A, _], + @(`inline` @getter @setter) private var _value: AnyRef | Null, + @(`inline` @getter @setter) private var _left: Tree[A, _] | Null, + @(`inline` @getter @setter) private var _right: Tree[A, _] | Null, @(`inline` @getter @setter) private var _count: Int) { @`inline` private[RedBlackTree] def isMutable: Boolean = (_count & colourMask) == 0 @@ -573,11 +573,11 @@ private[collection] object RedBlackTree { @`inline` private def mutableRetainingColour = _count & colourBit //inlined here to avoid outer object null checks - @`inline` private[RedBlackTree] final def sizeOf(tree:Tree[_,_]) = if (tree eq null) 0 else tree.count + @`inline` private[RedBlackTree] final def sizeOf(tree: Tree[_,_] | Null) = if (tree eq null) 0 else tree.count @`inline` private[immutable] final def key = _key @`inline` private[immutable] final def value = _value.asInstanceOf[B] - @`inline` private[immutable] final def left = _left.asInstanceOf[Tree[A, B]] - @`inline` private[immutable] final def right = _right.asInstanceOf[Tree[A, B]] + @`inline` private[immutable] final def left = _left.asInstanceOf[Tree[A, B] | Null] + @`inline` private[immutable] final def right = _right.asInstanceOf[Tree[A, B] | Null] //Note - only used in tests outside RedBlackTree @`inline` private[immutable] final def isBlack = _count < 0 //Note - only used in tests outside RedBlackTree @@ -591,12 +591,12 @@ private[collection] object RedBlackTree { if (isMutable) { var size = 1 if (_left ne null) { - _left.makeImmutable - size += _left.count + _left.nn.makeImmutable + size += _left.nn.count } if (_right ne null) { - _right.makeImmutable - size += _right.count + _right.nn.makeImmutable + size += _right.nn.count } _count |= size //retains colour } @@ -691,7 +691,7 @@ private[collection] object RedBlackTree { else new Tree(_key, newValue.asInstanceOf[AnyRef], _left, _right, _count) } - private[RedBlackTree] def withLeft[B1 >: B](newLeft: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def withLeft[B1 >: B](newLeft: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) if (newLeft eq _left) this @@ -700,7 +700,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], newLeft, _right, (_count & colourBit) | size) } } - private[RedBlackTree] def withRight[B1 >: B](newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def withRight[B1 >: B](newRight: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newRight) if (newRight eq _right) this @@ -709,7 +709,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], _left, newRight, (_count & colourBit) | size) } } - private[RedBlackTree] def blackWithLeft[B1 >: B](newLeft: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def blackWithLeft[B1 >: B](newLeft: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) if ((newLeft eq _left) && isBlack) this @@ -718,7 +718,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], newLeft, _right, initialBlackCount | size) } } - private[RedBlackTree] def redWithLeft[B1 >: B](newLeft: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def redWithLeft[B1 >: B](newLeft: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) if ((newLeft eq _left) && isRed) this @@ -727,7 +727,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], newLeft, _right, initialRedCount | size) } } - private[RedBlackTree] def blackWithRight[B1 >: B](newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def blackWithRight[B1 >: B](newRight: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newRight) if ((newRight eq _right) && isBlack) this @@ -736,7 +736,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], _left, newRight, initialBlackCount | size) } } - private[RedBlackTree] def redWithRight[B1 >: B](newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def redWithRight[B1 >: B](newRight: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) if ((newRight eq _right) && isRed) this @@ -745,7 +745,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], _left, newRight, initialRedCount | size) } } - private[RedBlackTree] def withLeftRight[B1 >: B](newLeft: Tree[A, B1], newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def withLeftRight[B1 >: B](newLeft: Tree[A, B1] | Null, newRight: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) //assertNotMutable(newRight) @@ -755,7 +755,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], newLeft, newRight, (_count & colourBit) | size) } } - private[RedBlackTree] def redWithLeftRight[B1 >: B](newLeft: Tree[A, B1], newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def redWithLeftRight[B1 >: B](newLeft: Tree[A, B1] | Null, newRight: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) //assertNotMutable(newRight) @@ -765,7 +765,7 @@ private[collection] object RedBlackTree { new Tree(key, value.asInstanceOf[AnyRef], newLeft, newRight, initialRedCount | size) } } - private[RedBlackTree] def blackWithLeftRight[B1 >: B](newLeft: Tree[A, B1], newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def blackWithLeftRight[B1 >: B](newLeft: Tree[A, B1] | Null, newRight: Tree[A, B1] | Null): Tree[A, B1] = { //assertNotMutable(this) //assertNotMutable(newLeft) //assertNotMutable(newRight) @@ -789,19 +789,19 @@ private[collection] object RedBlackTree { /** create a new immutable red tree. * left and right may be null */ - private[immutable] def RedTree[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]): Tree[A, B] = { + private[immutable] def RedTree[A, B](key: A, value: B, left: Tree[A, B] | Null, right: Tree[A, B] | Null): Tree[A, B] = { //assertNotMutable(left) //assertNotMutable(right) val size = sizeOf(left) + sizeOf(right) + 1 new Tree(key, value.asInstanceOf[AnyRef], left, right, initialRedCount | size) } - private[immutable] def BlackTree[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]): Tree[A, B] = { + private[immutable] def BlackTree[A, B](key: A, value: B, left: Tree[A, B] | Null, right: Tree[A, B] | Null): Tree[A, B] = { //assertNotMutable(left) //assertNotMutable(right) val size = sizeOf(left) + sizeOf(right) + 1 new Tree(key, value.asInstanceOf[AnyRef], left, right, initialBlackCount | size) } - @`inline` private def sizeOf(tree:Tree[_,_]) = if (tree eq null) 0 else tree.count + @`inline` private def sizeOf(tree:Tree[_,_] | Null) = if (tree eq null) 0 else tree.count //immutable APIs //assertions - uncomment decls and callers when changing functionality // private def devTimeAssert(assertion: Boolean) = { @@ -811,7 +811,7 @@ private[collection] object RedBlackTree { // private def assertNotMutable(t:Tree[_,_]) = { // devTimeAssert ((t eq null) || t.count > 0) // } - private[this] abstract class TreeIterator[A, B, R](root: Tree[A, B], start: Option[A])(protected implicit val ordering: Ordering[A]) extends AbstractIterator[R] { + private[this] abstract class TreeIterator[A, B, R](root: Tree[A, B] | Null, start: Option[A])(protected implicit val ordering: Ordering[A]) extends AbstractIterator[R] { protected[this] def nextResult(tree: Tree[A, B]): R override def hasNext: Boolean = lookahead ne null @@ -826,21 +826,21 @@ private[collection] object RedBlackTree { } @tailrec - protected final def findLeftMostOrPopOnEmpty(tree: Tree[A, B]): Tree[A, B] = + protected final def findLeftMostOrPopOnEmpty(tree: Tree[A, B] | Null): Tree[A, B] | Null = if (tree eq null) popNext() else if (tree.left eq null) tree else findLeftMostOrPopOnEmpty(goLeft(tree)) @`inline` private[this] def pushNext(tree: Tree[A, B]): Unit = { - stackOfNexts(index) = tree + stackOfNexts.nn(index) = tree index += 1 } - @`inline` protected final def popNext(): Tree[A, B] = if (index == 0) null else { + @`inline` protected final def popNext(): Tree[A, B] | Null = if (index == 0) null else { index -= 1 - stackOfNexts(index) + stackOfNexts.nn(index) } - protected[this] val stackOfNexts = if (root eq null) null else { + protected[this] val stackOfNexts: Array[Tree[A, B]] | Null = if (root eq null) null else { /* * According to "Ralf Hinze. Constructing red-black trees" [https://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. @@ -854,7 +854,7 @@ private[collection] object RedBlackTree { new Array[Tree[A, B]](maximumHeight) } private[this] var index = 0 - protected var lookahead: Tree[A, B] = if (start.isDefined) startFrom(start.get) else findLeftMostOrPopOnEmpty(root) + protected var lookahead: Tree[A, B] | Null = if (start.isDefined) startFrom(start.get) else findLeftMostOrPopOnEmpty(root) /** * Find the leftmost subtree whose key is equal to the given key, or if no such thing, @@ -862,12 +862,12 @@ private[collection] object RedBlackTree { * to the ordering. Along the way build up the iterator's path stack so that "next" * functionality works. */ - private[this] def startFrom(key: A) : Tree[A,B] = if (root eq null) null else { - @tailrec def find(tree: Tree[A, B]): Tree[A, B] = + private[this] def startFrom(key: A) : Tree[A,B] | Null = if (root eq null) null else { + @tailrec def find(tree: Tree[A, B] | Null): Tree[A, B] | Null = if (tree eq null) popNext() else find( - if (ordering.lteq(key, tree.key)) goLeft(tree) - else goRight(tree) + if (ordering.lteq(key, tree.nn.key)) goLeft(tree.nn) + else goRight(tree.nn) ) find(root) } @@ -890,10 +890,10 @@ private[collection] object RedBlackTree { this.lookahead = this.popNext() that.lookahead = that.popNext() } else { - equal = (this.lookahead.key.asInstanceOf[AnyRef] eq that.lookahead.key.asInstanceOf[AnyRef]) || - ordering.equiv(this.lookahead.key, that.lookahead.key) - this.lookahead = this.findLeftMostOrPopOnEmpty(this.goRight(this.lookahead)) - that.lookahead = that.findLeftMostOrPopOnEmpty(that.goRight(that.lookahead)) + equal = (this.lookahead.nn.key.asInstanceOf[AnyRef] eq that.lookahead.nn.key.asInstanceOf[AnyRef]) || + ordering.equiv(this.lookahead.nn.key, that.lookahead.nn.key) + this.lookahead = this.findLeftMostOrPopOnEmpty(this.goRight(this.lookahead.nn)) + that.lookahead = that.findLeftMostOrPopOnEmpty(that.goRight(that.lookahead.nn)) } } equal && (this.lookahead eq null) && (that.lookahead eq null) @@ -905,9 +905,9 @@ private[collection] object RedBlackTree { this.lookahead = this.popNext() that.lookahead = that.popNext() } else { - equal = this.lookahead.value == that.lookahead.value - this.lookahead = this.findLeftMostOrPopOnEmpty(this.goRight(this.lookahead)) - that.lookahead = that.findLeftMostOrPopOnEmpty(that.goRight(that.lookahead)) + equal = this.lookahead.nn.value == that.lookahead.nn.value + this.lookahead = this.findLeftMostOrPopOnEmpty(this.goRight(this.lookahead.nn)) + that.lookahead = that.findLeftMostOrPopOnEmpty(that.goRight(that.lookahead.nn)) } } equal && (this.lookahead eq null) && (that.lookahead eq null) @@ -919,10 +919,10 @@ private[collection] object RedBlackTree { this.lookahead = this.popNext() that.lookahead = that.popNext() } else { - equal = ((this.lookahead.key.asInstanceOf[AnyRef] eq that.lookahead.key.asInstanceOf[AnyRef]) || - ordering.equiv(this.lookahead.key, that.lookahead.key)) && this.lookahead.value == that.lookahead.value - this.lookahead = this.findLeftMostOrPopOnEmpty(this.goRight(this.lookahead)) - that.lookahead = that.findLeftMostOrPopOnEmpty(that.goRight(that.lookahead)) + equal = ((this.lookahead.nn.key.asInstanceOf[AnyRef] eq that.lookahead.nn.key.asInstanceOf[AnyRef]) || + ordering.equiv(this.lookahead.nn.key, that.lookahead.nn.key)) && this.lookahead.nn.value == that.lookahead.nn.value + this.lookahead = this.findLeftMostOrPopOnEmpty(this.goRight(this.lookahead.nn)) + that.lookahead = that.findLeftMostOrPopOnEmpty(that.goRight(that.lookahead.nn)) } } equal && (this.lookahead eq null) && (that.lookahead eq null) @@ -941,9 +941,9 @@ private[collection] object RedBlackTree { } /** Build a Tree suitable for a TreeSet from an ordered sequence of keys */ - def fromOrderedKeys[A](xs: Iterator[A]^, size: Int): Tree[A, Null] = { + def fromOrderedKeys[A](xs: Iterator[A]^, size: Int): Tree[A, Null] | Null = { val maxUsedDepth = 32 - Integer.numberOfLeadingZeros(size) // maximum depth of non-leaf nodes - def f(level: Int, size: Int): Tree[A, Null] = size match { + def f(level: Int, size: Int): Tree[A, Null] | Null = size match { case 0 => null case 1 => mkTree(level != maxUsedDepth || level == 1, xs.next(), null, null, null) case n => @@ -957,9 +957,9 @@ private[collection] object RedBlackTree { } /** Build a Tree suitable for a TreeMap from an ordered sequence of key/value pairs */ - def fromOrderedEntries[A, B](xs: Iterator[(A, B)]^, size: Int): Tree[A, B] = { + def fromOrderedEntries[A, B](xs: Iterator[(A, B)]^, size: Int): Tree[A, B] | Null = { val maxUsedDepth = 32 - Integer.numberOfLeadingZeros(size) // maximum depth of non-leaf nodes - def f(level: Int, size: Int): Tree[A, B] = size match { + def f(level: Int, size: Int): Tree[A, B] | Null = size match { case 0 => null case 1 => val (k, v) = xs.next() @@ -977,10 +977,10 @@ private[collection] object RedBlackTree { def transform[A, B, C](t: Tree[A, B] | Null, f: (A, B) => C): Tree[A, C] | Null = if(t eq null) null else { - val k = t.key - val v = t.value - val l = t.left - val r = t.right + val k = t.nn.key + val v = t.nn.value + val l = t.nn.left + val r = t.nn.right val l2 = transform(l, f) val v2 = f(k, v) val r2 = transform(r, f) @@ -991,7 +991,7 @@ private[collection] object RedBlackTree { } def filterEntries[A, B](t: Tree[A, B] | Null, f: (A, B) => Boolean): Tree[A, B] | Null = if(t eq null) null else { - def fk(t: Tree[A, B]): Tree[A, B] = { + def fk(t: Tree[A, B]): Tree[A, B] | Null = { val k = t.key val v = t.value val l = t.left @@ -1012,13 +1012,13 @@ private[collection] object RedBlackTree { if (t eq null) null2 else { object partitioner { - var tmpk, tmpd = null: Tree[A, B] // shared vars to avoid returning tuples from fk + var tmpk, tmpd = null: Tree[A, B] | Null // shared vars to avoid returning tuples from fk def fk(t: Tree[A, B]): Unit = { val k = t.key val v = t.value - val l = t.left - val r = t.right - var l2k, l2d, r2k, r2d = null: Tree[A, B] + var l = t.left + var r = t.right + var l2k, l2d, r2k, r2d = null: Tree[A, B] | Null if (l ne null) { fk(l) l2k = tmpk @@ -1058,64 +1058,64 @@ private[collection] object RedBlackTree { val newLeft = del(tree.left, k) if (newLeft eq tree.left) tree else if (isBlackTree(tree.left)) balLeft(tree, newLeft, tree.right) - else tree.redWithLeft(newLeft) + else tree.redWithLeft(newLeft.nn) } else if (cmp > 0) { val newRight = del(tree.right, k) if (newRight eq tree.right) tree else if (isBlackTree(tree.right)) balRight(tree, tree.left, newRight) - else tree.redWithRight(newRight) + else tree.redWithRight(newRight.nn) } else append(tree.left, tree.right) } - private[this] def balance[A, B](tree: Tree[A,B], tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = + private[this] def balance[A, B](tree: Tree[A,B], tl: Tree[A, B] | Null, tr: Tree[A, B] | Null): Tree[A, B] = if (isRedTree(tl)) { - if (isRedTree(tr)) tree.redWithLeftRight(tl.black, tr.black) - else if (isRedTree(tl.left)) tl.withLeftRight(tl.left.black, tree.blackWithLeftRight(tl.right, tr)) - else if (isRedTree(tl.right)) tl.right.withLeftRight(tl.blackWithRight(tl.right.left), tree.blackWithLeftRight(tl.right.right, tr)) + if (isRedTree(tr)) tree.redWithLeftRight(tl.nn.black, tr.nn.black) + else if (isRedTree(tl.nn.left)) tl.nn.withLeftRight(tl.nn.left.nn.black, tree.blackWithLeftRight(tl.nn.right, tr)) + else if (isRedTree(tl.nn.right)) tl.nn.right.nn.withLeftRight(tl.nn.blackWithRight(tl.nn.right.nn.left), tree.blackWithLeftRight(tl.nn.right.nn.right, tr)) else tree.blackWithLeftRight(tl, tr) } else if (isRedTree(tr)) { - if (isRedTree(tr.right)) tr.withLeftRight(tree.blackWithLeftRight(tl, tr.left), tr.right.black) - else if (isRedTree(tr.left)) tr.left.withLeftRight(tree.blackWithLeftRight(tl, tr.left.left), tr.blackWithLeftRight(tr.left.right, tr.right)) + if (isRedTree(tr.nn.right)) tr.nn.withLeftRight(tree.blackWithLeftRight(tl, tr.nn.left), tr.nn.right.nn.black) + else if (isRedTree(tr.nn.left)) tr.nn.left.nn.withLeftRight(tree.blackWithLeftRight(tl, tr.nn.left.nn.left), tr.nn.blackWithLeftRight(tr.nn.left.nn.right, tr.nn.right)) else tree.blackWithLeftRight(tl, tr) } else tree.blackWithLeftRight(tl, tr) - private[this] def balLeft[A, B](tree: Tree[A,B], tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = - if (isRedTree(tl)) tree.redWithLeftRight(tl.black, tr) - else if (isBlackTree(tr)) balance(tree, tl, tr.red) - else if (isRedTree(tr) && isBlackTree(tr.left)) - tr.left.redWithLeftRight(tree.blackWithLeftRight(tl, tr.left.left), balance(tr, tr.left.right, tr.right.red)) + private[this] def balLeft[A, B](tree: Tree[A,B], tl: Tree[A, B] | Null, tr: Tree[A, B] | Null): Tree[A, B] = + if (isRedTree(tl)) tree.redWithLeftRight(tl.nn.black, tr) + else if (isBlackTree(tr)) balance(tree, tl, tr.nn.red) + else if (isRedTree(tr) && isBlackTree(tr.nn.left)) + tr.nn.left.nn.redWithLeftRight(tree.blackWithLeftRight(tl, tr.nn.left.nn.left), balance(tr.nn, tr.nn.left.nn.right.nn, tr.nn.right.nn.red)) else sys.error("Defect: invariance violation") - private[this] def balRight[A, B](tree: Tree[A,B], tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = - if (isRedTree(tr)) tree.redWithLeftRight(tl, tr.black) - else if (isBlackTree(tl)) balance(tree, tl.red, tr) - else if (isRedTree(tl) && isBlackTree(tl.right)) - tl.right.redWithLeftRight(balance(tl, tl.left.red, tl.right.left), tree.blackWithLeftRight(tl.right.right, tr)) + private[this] def balRight[A, B](tree: Tree[A,B], tl: Tree[A, B] | Null, tr: Tree[A, B] | Null): Tree[A, B] = + if (isRedTree(tr)) tree.redWithLeftRight(tl, tr.nn.black) + else if (isBlackTree(tl)) balance(tree, tl.nn.red, tr) + else if (isRedTree(tl) && isBlackTree(tl.nn.right)) + tl.nn.right.nn.redWithLeftRight(balance(tl.nn, tl.nn.left.nn.red, tl.nn.right.nn.left.nn), tree.blackWithLeftRight(tl.nn.right.nn.right, tr)) else sys.error("Defect: invariance violation") /** `append` is similar to `join2` but requires that both subtrees have the same black height */ - private[this] def append[A, B](tl: Tree[A, B], tr: Tree[A, B]): Tree[A, B] = { + private[this] def append[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 if (tl.isRed) { if (tr.isRed) { //tl is red, tr is red val bc = append(tl.right, tr.left) - if (isRedTree(bc)) bc.withLeftRight(tl.withRight(bc.left), tr.withLeft(bc.right)) + if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left.nn), tr.withLeft(bc.nn.right.nn)) else tl.withRight(tr.withLeft(bc)) } else { //tl is red, tr is black - tl.withRight(append(tl.right, tr)) + tl.withRight(append(tl.right, tr).nn) } } else { if (tr.isBlack) { //tl is black tr is black val bc = append(tl.right, tr.left) - if (isRedTree(bc)) bc.withLeftRight(tl.withRight(bc.left), tr.withLeft(bc.right)) + if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left.nn), tr.withLeft(bc.nn.right.nn)) else balLeft(tl, tl.left, tr.withLeft(bc)) } else { //tl is black tr is red - tr.withLeft(append(tl, tr.left)) + tr.withLeft(append(tl, tr.left).nn) } } } @@ -1126,11 +1126,11 @@ 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] | Null, t2: Tree[A, B] | Null)(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] | Null = blacken(_union(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 intersect[A, B](t1: Tree[A, B] | Null, t2: Tree[A, B] | Null)(implicit ordering: Ordering[A]): Tree[A, B] | Null = blacken(_intersect(t1, t2)) - def difference[A, B](t1: Tree[A, B] | Null, t2: Tree[A, _] | Null)(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] | Null = blacken(_difference(t1, t2.asInstanceOf[Tree[A, B]])) /** Compute the rank from a tree and its black height */ @@ -1146,11 +1146,11 @@ private[collection] object RedBlackTree { else { val tlBlack = isBlackTree(tl) val bhtlr = if(tlBlack) bhtl-1 else bhtl - val ttr = joinRight(tl.right, k, v, tr, bhtlr, rtr) + val ttr = joinRight(tl.right.nn, k, v, tr, bhtlr, rtr) if(tlBlack && isRedTree(ttr) && isRedTree(ttr.right)) RedTree(ttr.key, ttr.value, BlackTree(tl.key, tl.value, tl.left, ttr.left), - ttr.right.black) + ttr.right.nn.black) else mkTree(tlBlack, tl.key, tl.value, tl.left, ttr) } } @@ -1161,26 +1161,26 @@ private[collection] object RedBlackTree { else { val trBlack = isBlackTree(tr) val bhtrl = if(trBlack) bhtr-1 else bhtr - val ttl = joinLeft(tl, k, v, tr.left, rtl, bhtrl) + val ttl = joinLeft(tl, k, v, tr.left.nn, rtl, bhtrl) if(trBlack && isRedTree(ttl) && isRedTree(ttl.left)) RedTree(ttl.key, ttl.value, - ttl.left.black, + ttl.left.nn.black, BlackTree(tr.key, tr.value, ttl.right, tr.right)) else mkTree(trBlack, tr.key, tr.value, ttl, tr.right) } } 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 = + @tailrec def h(t: Tree[_, _] | Null, 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) val bhtr = h(tr, 0) if(bhtl > bhtr) { - val tt = joinRight(tl, k, v, tr, bhtl, rank(tr, bhtr)) + val tt = joinRight(tl.nn, k, v, tr.nn, bhtl, rank(tr, bhtr)) if(isRedTree(tt) && isRedTree(tt.right)) tt.black else tt } else if(bhtr > bhtl) { - val tt = joinLeft(tl, k, v, tr, rank(tl, bhtl), bhtr) + val tt = joinLeft(tl.nn, k, v, tr.nn, rank(tl, bhtl), bhtr) if(isRedTree(tt) && isRedTree(tt.left)) tt.black else tt } else mkTree(isRedTree(tl) || isRedTree(tr), k, v, tl, tr) @@ -1201,17 +1201,17 @@ private[collection] object RedBlackTree { } private[this] def splitLast[A, B](t: Tree[A, B]): (Tree[A, B], A, B) = - if(t.right eq null) (t.left, t.key, t.value) + if(t.right eq null) (t.left.nn, t.key, t.value) else { - val (tt, kk, vv) = splitLast(t.right) - (join(t.left, t.key, t.value, tt), kk, vv) + val (tt, kk, vv) = splitLast(t.right.nn) + (join(t.left, t.key, t.value, tt).nn, kk, vv) } 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 { - val (ttl, k, v) = splitLast(tl) + val (ttl, k, v) = splitLast(tl.nn) join(ttl, k, v, tr) } diff --git a/library/src/scala/collection/immutable/TreeMap.scala b/library/src/scala/collection/immutable/TreeMap.scala index ee68bc2a7a12..ec8330f78fee 100644 --- a/library/src/scala/collection/immutable/TreeMap.scala +++ b/library/src/scala/collection/immutable/TreeMap.scala @@ -16,7 +16,6 @@ package immutable import scala.language.`2.13` import language.experimental.captureChecking -import scala.language.unsafeNulls import scala.annotation.tailrec import scala.collection.Stepper.EfficientSplit @@ -74,7 +73,7 @@ import scala.runtime.AbstractFunction2 * @define mayNotTerminateInf * @define willNotTerminateInf */ -final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit val ordering: Ordering[K]) +final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(implicit val ordering: Ordering[K]) extends AbstractMap[K, V] with SortedMap[K, V] with StrictOptimizedSortedMapOps[K, V, TreeMap, TreeMap[K, V]] @@ -82,26 +81,26 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit va with DefaultSerializable { def this()(implicit ordering: Ordering[K]) = this(null)(ordering) - private[immutable] def tree0: RB.Tree[K, V] = tree + private[immutable] def tree0: RB.Tree[K, V] | Null = tree - private[this] def newMapOrSelf[V1 >: V](t: RB.Tree[K, V1]): TreeMap[K, V1] = if(t eq tree) this else new TreeMap[K, V1](t) + private[this] def newMapOrSelf[V1 >: V](t: RB.Tree[K, V1] | Null): TreeMap[K, V1] = if(t eq tree) this else new TreeMap[K, V1](t) override def sortedMapFactory: SortedMapFactory[TreeMap] = TreeMap - def iterator: Iterator[(K, V)] = RB.iterator(tree) + def iterator: Iterator[(K, V)] = RB.iterator(tree.nn) - def keysIteratorFrom(start: K): Iterator[K] = RB.keysIterator(tree, Some(start)) + def keysIteratorFrom(start: K): Iterator[K] = RB.keysIterator(tree.nn, Some(start)) override def keySet: TreeSet[K] = new TreeSet(tree)(ordering) - def iteratorFrom(start: K): Iterator[(K, V)] = RB.iterator(tree, Some(start)) + def iteratorFrom(start: K): Iterator[(K, V)] = RB.iterator(tree.nn, Some(start)) - override def valuesIteratorFrom(start: K): Iterator[V] = RB.valuesIterator(tree, Some(start)) + override def valuesIteratorFrom(start: K): Iterator[V] = RB.valuesIterator(tree.nn, Some(start)) override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( scala.collection.convert.impl.AnyBinaryTreeStepper.from[(K, V), RB.Tree[K, V]]( - size, tree, _.left, _.right, x => (x.key, x.value) + size, tree, _.left.nn, _.right.nn, x => (x.key, x.value) ) ) @@ -109,10 +108,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit va import scala.collection.convert.impl._ type T = RB.Tree[K, V] 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[K, T](size, tree, _.left, _.right, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -121,10 +120,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit va import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.value.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.value.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.value.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree, _.left, _.right, _.value.asInstanceOf[V])) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[V])) } s.asInstanceOf[S with EfficientSplit] } @@ -213,17 +212,17 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit va override def isEmpty = size == 0 - override def firstKey: K = RB.smallest(tree).key + override def firstKey: K = RB.smallest(tree.nn).key - override def lastKey: K = RB.greatest(tree).key + override def lastKey: K = RB.greatest(tree.nn).key override def head: (K, V) = { - val smallest = RB.smallest(tree) + val smallest = RB.smallest(tree.nn) (smallest.key, smallest.value) } override def last: (K, V) = { - val greatest = RB.greatest(tree) + val greatest = RB.greatest(tree.nn) (greatest.key, greatest.value) } @@ -283,7 +282,7 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit va private final class Adder[B1 >: V] extends RB.MapHelper[K, B1] with Function1[(K, B1), Unit] { - private var currentMutableTree: RB.Tree[K,B1] = tree0 + private var currentMutableTree: RB.Tree[K,B1] | Null = tree0 def finalTree = beforePublish(currentMutableTree) override def apply(kv: (K, B1)): Unit = { currentMutableTree = mutableUpd(currentMutableTree, kv._1, kv._2) @@ -319,7 +318,7 @@ object TreeMap extends SortedMapFactory[TreeMap] { case sm: scala.collection.SortedMap[K, V] if ordering == sm.ordering => new TreeMap[K, V](RB.fromOrderedEntries(sm.iterator, sm.size)) case _ => - var t: RB.Tree[K, V] = null + var t: RB.Tree[K, V] | Null = null val i = it.iterator while (i.hasNext) { val (k, v) = i.next() @@ -334,7 +333,7 @@ object TreeMap extends SortedMapFactory[TreeMap] { extends RB.MapHelper[K, V] with ReusableBuilder[(K, V), TreeMap[K, V]] { type Tree = RB.Tree[K, V] - private var tree:Tree = null + private var tree: Tree | Null = null def addOne(elem: (K, V)): this.type = { tree = mutableUpd(tree, elem._1, elem._2) @@ -343,7 +342,7 @@ object TreeMap extends SortedMapFactory[TreeMap] { private object adder extends AbstractFunction2[K, V, Unit] { // we cache tree to avoid the outer access to tree // in the hot path (apply) - private[this] var accumulator :Tree = null + private[this] var accumulator: Tree | Null = null def addForEach(hasForEach: collection.Map[K, V]): Unit = { accumulator = tree hasForEach.foreachEntry(this) diff --git a/library/src/scala/collection/immutable/TreeSet.scala b/library/src/scala/collection/immutable/TreeSet.scala index faf55def414d..85a04cb3c143 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -130,18 +130,18 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ 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.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.nn, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } From 30695d9006cdceaa37e34ea2fb20e5fafac96534 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 13:33:28 +0200 Subject: [PATCH 06/46] Another RBT --- .../collection/immutable/RedBlackTree.scala | 1 - .../collection/mutable/RedBlackTree.scala | 366 +++++++++--------- .../scala/collection/mutable/TreeMap.scala | 18 +- .../scala/collection/mutable/TreeSet.scala | 8 +- 4 files changed, 200 insertions(+), 193 deletions(-) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 812a1c120905..b1e58bd44acf 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -16,7 +16,6 @@ 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 diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index 23c8e01bfec1..de4d5d83c3bc 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -14,7 +14,6 @@ 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} @@ -34,11 +33,19 @@ private[collection] object RedBlackTree { // Therefore, while obtaining the size of the whole tree is O(1), knowing the number of entries inside a range is O(n) // on the size of the range. - final class Tree[A, B](var root: Node[A, B], var size: Int) { + final class Tree[A, B](var root: Node[A, B] | Null, var size: Int) { def treeCopy(): Tree[A, B] = new Tree(copyTree(root), size) } - final class Node[A, B](var key: A, var value: B, var red: Boolean, var left: Node[A, B], var right: Node[A, B], var parent: Node[A, B]) { + final class Node[A, B]( + var key: A, var value: B, var red: Boolean, + @annotation.stableNull + var left: Node[A, B] | Null, + @annotation.stableNull + var right: Node[A, B] | Null, + @annotation.stableNull + var parent: Node[A, B] | Null + ) { override def toString: String = "Node(" + key + ", " + value + ", " + red + ", " + left + ", " + right + ")" } @@ -60,12 +67,12 @@ private[collection] object RedBlackTree { // ---- getters ---- - def isRed(node: Node[_, _]) = (node ne null) && node.red - def isBlack(node: Node[_, _]) = (node eq null) || !node.red + def isRed(node: Node[_, _] | Null) = (node ne null) && node.red + def isBlack(node: Node[_, _] | Null) = (node eq null) || !node.red // ---- size ---- - def size(node: Node[_, _]): Int = if (node eq null) 0 else 1 + size(node.left) + size(node.right) + def size(node: Node[_, _] | Null): Int = if (node eq null) 0 else 1 + size(node.left) + size(node.right) def size(tree: Tree[_, _]): Int = tree.size def isEmpty(tree: Tree[_, _]) = tree.root eq null def clear(tree: Tree[_, _]): Unit = { tree.root = null; tree.size = 0 } @@ -77,7 +84,7 @@ private[collection] object RedBlackTree { case node => Some(node.value) } - @tailrec private[this] def getNode[A, B](node: Node[A, B], key: A)(implicit ord: Ordering[A]): Node[A, B] = + @tailrec private[this] def getNode[A, B](node: Node[A, B] | Null, key: A)(implicit ord: Ordering[A]): Node[A, B] | Null = if (node eq null) null else { val cmp = ord.compare(key, node.key) @@ -98,11 +105,11 @@ private[collection] object RedBlackTree { case node => Some(node.key) } - private def minNode[A, B](node: Node[A, B]): Node[A, B] = - if (node eq null) null else minNodeNonNull(node) + private def minNode[A, B](node: Node[A, B] | Null): Node[A, B] | Null = + if (node eq null) null else minNodeNonNull(node.nn) @tailrec def minNodeNonNull[A, B](node: Node[A, B]): Node[A, B] = - if (node.left eq null) node else minNodeNonNull(node.left) + if (node.left eq null) node else minNodeNonNull(node.left.nn) def max[A, B](tree: Tree[A, B]): Option[(A, B)] = maxNode(tree.root) match { case null => None @@ -114,11 +121,11 @@ private[collection] object RedBlackTree { case node => Some(node.key) } - private def maxNode[A, B](node: Node[A, B]): Node[A, B] = - if (node eq null) null else maxNodeNonNull(node) + private def maxNode[A, B](node: Node[A, B] | Null): Node[A, B] | Null = + if (node eq null) null else maxNodeNonNull(node.nn) @tailrec def maxNodeNonNull[A, B](node: Node[A, B]): Node[A, B] = - if (node.right eq null) node else maxNodeNonNull(node.right) + if (node.right eq null) node else maxNodeNonNull(node.right.nn) /** * Returns the first (lowest) map entry with a key equal or greater than `key`. Returns `None` if there is no such @@ -136,16 +143,16 @@ private[collection] object RedBlackTree { case node => Some(node.key) } - private[this] def minNodeAfter[A, B](node: Node[A, B], key: A)(implicit ord: Ordering[A]): Node[A, B] = { + private[this] def minNodeAfter[A, B](node: Node[A, B] | Null, key: A)(implicit ord: Ordering[A]): Node[A, B] | Null = { if (node eq null) null else { - var y: Node[A, B] = null - var x = node + var y: Node[A, B] | Null = null + var x: Node[A, B] | Null = node var cmp = 1 while ((x ne null) && cmp != 0) { y = x - cmp = ord.compare(key, x.key) - x = if (cmp < 0) x.left else x.right + cmp = ord.compare(key, x.nn.key) + x = if (cmp < 0) x.nn.left else x.nn.right } if (cmp <= 0) y else successor(y) } @@ -166,16 +173,16 @@ private[collection] object RedBlackTree { case node => Some(node.key) } - private[this] def maxNodeBefore[A, B](node: Node[A, B], key: A)(implicit ord: Ordering[A]): Node[A, B] = { + private[this] def maxNodeBefore[A, B](node: Node[A, B] | Null, key: A)(implicit ord: Ordering[A]): Node[A, B] | Null = { if (node eq null) null else { - var y: Node[A, B] = null - var x = node + var y: Node[A, B] | Null = null + var x: Node[A, B] | Null = node var cmp = 1 while ((x ne null) && cmp != 0) { y = x - cmp = ord.compare(key, x.key) - x = if (cmp < 0) x.left else x.right + cmp = ord.compare(key, x.nn.key) + x = if (cmp < 0) x.nn.left else x.nn.right } if (cmp > 0) y else predecessor(y) } @@ -184,22 +191,22 @@ private[collection] object RedBlackTree { // ---- insertion ---- def insert[A, B](tree: Tree[A, B], key: A, value: B)(implicit ord: Ordering[A]): Unit = { - var y: Node[A, B] = null + var y: Node[A, B] | Null = null var x = tree.root var cmp = 1 while ((x ne null) && cmp != 0) { y = x - cmp = ord.compare(key, x.key) - x = if (cmp < 0) x.left else x.right + cmp = ord.compare(key, x.nn.key) + x = if (cmp < 0) x.nn.left else x.nn.right } - if (cmp == 0) y.value = value + if (cmp == 0) y.nn.value = value else { - val z = Node.leaf(key, value, red = true, y) + val z = Node.leaf(key, value, red = true, y.nn) if (y eq null) tree.root = z - else if (cmp < 0) y.left = z - else y.right = z + else if (cmp < 0) y.nn.left = z + else y.nn.right = z fixAfterInsert(tree, z) tree.size += 1 @@ -209,41 +216,41 @@ private[collection] object RedBlackTree { private[this] def fixAfterInsert[A, B](tree: Tree[A, B], node: Node[A, B]): Unit = { var z = node while (isRed(z.parent)) { - if (z.parent eq z.parent.parent.left) { - val y = z.parent.parent.right + if (z.parent.nn eq z.parent.nn.parent.nn.left) { + val y = z.parent.nn.parent.nn.right if (isRed(y)) { - z.parent.red = false - y.red = false - z.parent.parent.red = true - z = z.parent.parent + z.parent.nn.red = false + y.nn.red = false + z.parent.nn.parent.nn.red = true + z = z.parent.nn.parent.nn } else { - if (z eq z.parent.right) { - z = z.parent + if (z eq z.parent.nn.right) { + z = z.parent.nn rotateLeft(tree, z) } - z.parent.red = false - z.parent.parent.red = true - rotateRight(tree, z.parent.parent) + z.parent.nn.red = false + z.parent.nn.parent.nn.red = true + rotateRight(tree, z.parent.nn.parent.nn) } } else { // symmetric cases - val y = z.parent.parent.left + val y = z.parent.nn.parent.nn.left if (isRed(y)) { - z.parent.red = false - y.red = false - z.parent.parent.red = true - z = z.parent.parent + z.parent.nn.red = false + y.nn.red = false + z.parent.nn.parent.nn.red = true + z = z.parent.nn.parent.nn } else { - if (z eq z.parent.left) { - z = z.parent + if (z eq z.parent.nn.left) { + z = z.parent.nn rotateRight(tree, z) } - z.parent.red = false - z.parent.parent.red = true - rotateLeft(tree, z.parent.parent) + z.parent.nn.red = false + z.parent.nn.parent.nn.red = true + rotateLeft(tree, z.parent.nn.parent.nn) } } } - tree.root.red = false + tree.root.nn.red = false } // ---- deletion ---- @@ -252,36 +259,36 @@ private[collection] object RedBlackTree { val z = getNode(tree.root, key) if (z ne null) { var y = z - var yIsRed = y.red - var x: Node[A, B] = null - var xParent: Node[A, B] = null - - if (z.left eq null) { - x = z.right - transplant(tree, z, z.right) - xParent = z.parent + var yIsRed = y.nn.red + var x: Node[A, B] | Null = null + var xParent: Node[A, B] | Null = null + + if (z.nn.left eq null) { + x = z.nn.right + transplant(tree, z.nn, z.nn.right) + xParent = z.nn.parent } - else if (z.right eq null) { - x = z.left - transplant(tree, z, z.left) - xParent = z.parent + else if (z.nn.right eq null) { + x = z.nn.left + transplant(tree, z.nn, z.nn.left) + xParent = z.nn.parent } else { - y = minNodeNonNull(z.right) + y = minNodeNonNull(z.nn.right.nn) yIsRed = y.red x = y.right - if (y.parent eq z) xParent = y + if (y.parent eq z.nn) xParent = y else { xParent = y.parent transplant(tree, y, y.right) - y.right = z.right - y.right.parent = y + y.right = z.nn.right + y.right.nn.parent = y } - transplant(tree, z, y) - y.left = z.left - y.left.parent = y - y.red = z.red + transplant(tree, z.nn, y) + y.left = z.nn.left + y.left.nn.parent = y + y.red = z.nn.red } if (!yIsRed) fixAfterDelete(tree, x, xParent) @@ -289,66 +296,66 @@ private[collection] object RedBlackTree { } } - private[this] def fixAfterDelete[A, B](tree: Tree[A, B], node: Node[A, B], parent: Node[A, B]): Unit = { + private[this] def fixAfterDelete[A, B](tree: Tree[A, B], node: Node[A, B] | Null, parent: Node[A, B] | Null): Unit = { var x = node var xParent = parent while ((x ne tree.root) && isBlack(x)) { - if (x eq xParent.left) { - var w = xParent.right + if (x eq xParent.nn.left) { + var w = xParent.nn.right // assert(w ne null) - if (w.red) { - w.red = false - xParent.red = true - rotateLeft(tree, xParent) - w = xParent.right + if (w.nn.red) { + w.nn.red = false + xParent.nn.red = true + rotateLeft(tree, xParent.nn) + w = xParent.nn.right } - if (isBlack(w.left) && isBlack(w.right)) { - w.red = true + if (isBlack(w.nn.left) && isBlack(w.nn.right)) { + w.nn.red = true x = xParent } else { - if (isBlack(w.right)) { - w.left.red = false - w.red = true - rotateRight(tree, w) - w = xParent.right + if (isBlack(w.nn.right)) { + w.nn.left.nn.red = false + w.nn.red = true + rotateRight(tree, w.nn) + w = xParent.nn.right } - w.red = xParent.red - xParent.red = false - w.right.red = false - rotateLeft(tree, xParent) + w.nn.red = xParent.nn.red + xParent.nn.red = false + w.nn.right.nn.red = false + rotateLeft(tree, xParent.nn) x = tree.root } } else { // symmetric cases - var w = xParent.left + var w = xParent.nn.left // assert(w ne null) - if (w.red) { - w.red = false - xParent.red = true - rotateRight(tree, xParent) - w = xParent.left + if (w.nn.red) { + w.nn.red = false + xParent.nn.red = true + rotateRight(tree, xParent.nn) + w = xParent.nn.left } - if (isBlack(w.right) && isBlack(w.left)) { - w.red = true + if (isBlack(w.nn.right) && isBlack(w.nn.left)) { + w.nn.red = true x = xParent } else { - if (isBlack(w.left)) { - w.right.red = false - w.red = true - rotateLeft(tree, w) - w = xParent.left + if (isBlack(w.nn.left)) { + w.nn.right.nn.red = false + w.nn.red = true + rotateLeft(tree, w.nn) + w = xParent.nn.left } - w.red = xParent.red - xParent.red = false - w.left.red = false - rotateRight(tree, xParent) + w.nn.red = xParent.nn.red + xParent.nn.red = false + w.nn.left.nn.red = false + rotateRight(tree, xParent.nn) x = tree.root } } - xParent = x.parent + xParent = x.nn.parent } - if (x ne null) x.red = false + if (x ne null) x.nn.red = false } // ---- helpers ---- @@ -357,14 +364,15 @@ private[collection] object RedBlackTree { * Returns the node that follows `node` in an in-order tree traversal. If `node` has the maximum key (and is, * therefore, the last node), this method returns `null`. */ - private[this] def successor[A, B](node: Node[A, B]): Node[A, B] = { - if (node.right ne null) minNodeNonNull(node.right) + private[this] def successor[A, B](node: Node[A, B] | Null): Node[A, B] | Null = { + if (node eq null) null + else if (node.nn.right ne null) minNodeNonNull(node.nn.right.nn) else { var x = node - var y = x.parent - while ((y ne null) && (x eq y.right)) { + var y = x.nn.parent + while ((y ne null) && (x eq y.nn.right)) { x = y - y = y.parent + y = y.nn.parent } y } @@ -374,14 +382,15 @@ private[collection] object RedBlackTree { * Returns the node that precedes `node` in an in-order tree traversal. If `node` has the minimum key (and is, * therefore, the first node), this method returns `null`. */ - private[this] def predecessor[A, B](node: Node[A, B]): Node[A, B] = { - if (node.left ne null) maxNodeNonNull(node.left) + private[this] def predecessor[A, B](node: Node[A, B] | Null): Node[A, B] | Null = { + if (node eq null) null + else if (node.nn.left ne null) maxNodeNonNull(node.nn.left.nn) else { var x = node - var y = x.parent - while ((y ne null) && (x eq y.left)) { + var y = x.nn.parent + while ((y ne null) && (x eq y.nn.left)) { x = y - y = y.parent + y = y.nn.parent } y } @@ -390,32 +399,32 @@ private[collection] object RedBlackTree { private[this] def rotateLeft[A, B](tree: Tree[A, B], x: Node[A, B]): Unit = if (x ne null) { // assert(x.right ne null) val y = x.right - x.right = y.left + x.right = y.nn.left - if (y.left ne null) y.left.parent = x - y.parent = x.parent + if (y.nn.left ne null) y.nn.left.nn.parent = x + y.nn.parent = x.parent if (x.parent eq null) tree.root = y - else if (x eq x.parent.left) x.parent.left = y - else x.parent.right = y + else if (x eq x.parent.nn.left) x.parent.nn.left = y + else x.parent.nn.right = y - y.left = x + y.nn.left = x x.parent = y } private[this] def rotateRight[A, B](tree: Tree[A, B], x: Node[A, B]): Unit = if (x ne null) { // assert(x.left ne null) val y = x.left - x.left = y.right + x.left = y.nn.right - if (y.right ne null) y.right.parent = x - y.parent = x.parent + if (y.nn.right ne null) y.nn.right.nn.parent = x + y.nn.parent = x.parent if (x.parent eq null) tree.root = y - else if (x eq x.parent.right) x.parent.right = y - else x.parent.left = y + else if (x eq x.parent.nn.right) x.parent.nn.right = y + else x.parent.nn.left = y - y.right = x + y.nn.right = x x.parent = y } @@ -423,60 +432,60 @@ private[collection] object RedBlackTree { * Transplant the node `from` to the place of node `to`. This is done by setting `from` as a child of `to`'s previous * parent and setting `from`'s parent to the `to`'s previous parent. The children of `from` are left unchanged. */ - private[this] def transplant[A, B](tree: Tree[A, B], to: Node[A, B], from: Node[A, B]): Unit = { + private[this] def transplant[A, B](tree: Tree[A, B], to: Node[A, B], from: Node[A, B] | Null): Unit = { if (to.parent eq null) tree.root = from - else if (to eq to.parent.left) to.parent.left = from - else to.parent.right = from + else if (to eq to.parent.nn.left) to.parent.nn.left = from + else to.parent.nn.right = from - if (from ne null) from.parent = to.parent + if (from ne null) from.nn.parent = to.parent } // ---- tree traversal ---- def foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = foreachNode(tree.root, f) - private[this] def foreachNode[A, B, U](node: Node[A, B], f: ((A, B)) => U): Unit = - if (node ne null) foreachNodeNonNull(node, f) + private[this] def foreachNode[A, B, U](node: Node[A, B] | Null, f: ((A, B)) => U): Unit = + if (node ne null) foreachNodeNonNull(node.nn, f) private[this] def foreachNodeNonNull[A, B, U](node: Node[A, B], f: ((A, B)) => U): Unit = { - if (node.left ne null) foreachNodeNonNull(node.left, f) + if (node.left ne null) foreachNodeNonNull(node.left.nn, f) f((node.key, node.value)) - if (node.right ne null) foreachNodeNonNull(node.right, f) + if (node.right ne null) foreachNodeNonNull(node.right.nn, f) } def foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = { def g(node: Node[A, _]): Unit = { val l = node.left - if(l ne null) g(l) + if(l ne null) g(l.nn) f(node.key) val r = node.right - if(r ne null) g(r) + if(r ne null) g(r.nn) } val r = tree.root - if(r ne null) g(r) + if(r ne null) g(r.nn) } def foreachEntry[A, B, U](tree: Tree[A, B], f: (A, B) => U): Unit = { def g(node: Node[A, B]): Unit = { val l = node.left - if(l ne null) g(l) + if(l ne null) g(l.nn) f(node.key, node.value) val r = node.right - if(r ne null) g(r) + if(r ne null) g(r.nn) } val r = tree.root - if(r ne null) g(r) + if(r ne null) g(r.nn) } def transform[A, B](tree: Tree[A, B], f: (A, B) => B): Unit = transformNode(tree.root, f) - private[this] def transformNode[A, B, U](node: Node[A, B], f: (A, B) => B): Unit = - if (node ne null) transformNodeNonNull(node, f) + private[this] def transformNode[A, B, U](node: Node[A, B] | Null, f: (A, B) => B): Unit = + if (node ne null) transformNodeNonNull(node.nn, f) private[this] def transformNodeNonNull[A, B, U](node: Node[A, B], f: (A, B) => B): Unit = { - if (node.left ne null) transformNodeNonNull(node.left, f) + if (node.left ne null) transformNodeNonNull(node.left.nn, f) node.value = f(node.key, node.value) - if (node.right ne null) transformNodeNonNull(node.right, f) + if (node.right ne null) transformNodeNonNull(node.right.nn, f) } def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[(A, B)] = @@ -504,18 +513,17 @@ private[collection] object RedBlackTree { nextResult(node) } - private[this] var nextNode: Node[A, B] = start match { + private[this] var nextNode: Node[A, B] | Null = start match { case None => minNode(tree.root) case Some(from) => minNodeAfter(tree.root, from) } private[this] def setNullIfAfterEnd(): Unit = - if (end.isDefined && (nextNode ne null) && ord.compare(nextNode.key, end.get) >= 0) + if (end.isDefined && (nextNode ne null) && ord.compare(nextNode.nn.key, end.get) >= 0) nextNode = null setNullIfAfterEnd() } - private[this] final class EntriesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) extends TreeIterator[A, B, (A, B)](tree, start, end) { @@ -551,28 +559,28 @@ private[collection] object RedBlackTree { */ private[this] def hasProperParentRefs[A, B](tree: Tree[A, B]): Boolean = { - def hasProperParentRefs(node: Node[A, B]): Boolean = { + def hasProperParentRefs(node: Node[A, B] | Null): Boolean = { if (node eq null) true else { - if ((node.left ne null) && (node.left.parent ne node) || - (node.right ne null) && (node.right.parent ne node)) false - else hasProperParentRefs(node.left) && hasProperParentRefs(node.right) + if ((node.nn.left ne null) && (node.nn.left.nn.parent ne node) || + (node.nn.right ne null) && (node.nn.right.nn.parent ne node)) false + else hasProperParentRefs(node.nn.left) && hasProperParentRefs(node.nn.right) } } if(tree.root eq null) true - else (tree.root.parent eq null) && hasProperParentRefs(tree.root) + else (tree.root.nn.parent eq null) && hasProperParentRefs(tree.root) } /** * Returns true if this node follows the properties of a binary search tree. */ - private[this] def isValidBST[A, B](node: Node[A, B])(implicit ord: Ordering[A]): Boolean = { + private[this] def isValidBST[A, B](node: Node[A, B] | Null)(implicit ord: Ordering[A]): Boolean = { if (node eq null) true else { - if ((node.left ne null) && (ord.compare(node.key, node.left.key) <= 0) || - (node.right ne null) && (ord.compare(node.key, node.right.key) >= 0)) false - else isValidBST(node.left) && isValidBST(node.right) + if ((node.nn.left ne null) && (ord.compare(node.nn.key, node.nn.left.nn.key) <= 0) || + (node.nn.right ne null) && (ord.compare(node.nn.key, node.nn.right.nn.key) >= 0)) false + else isValidBST(node.nn.left) && isValidBST(node.nn.right) } } @@ -582,20 +590,20 @@ private[collection] object RedBlackTree { */ private[this] def isValidRedBlackTree[A, B](tree: Tree[A, B]): Boolean = { - def noRedAfterRed(node: Node[A, B]): Boolean = { + def noRedAfterRed(node: Node[A, B] | Null): Boolean = { if (node eq null) true - else if (node.red && (isRed(node.left) || isRed(node.right))) false - else noRedAfterRed(node.left) && noRedAfterRed(node.right) + else if (node.nn.red && (isRed(node.nn.left) || isRed(node.nn.right))) false + else noRedAfterRed(node.nn.left) && noRedAfterRed(node.nn.right) } - def blackHeight(node: Node[A, B]): Int = { + def blackHeight(node: Node[A, B] | Null): Int = { if (node eq null) 1 else { - val lh = blackHeight(node.left) - val rh = blackHeight(node.right) + val lh = blackHeight(node.nn.left) + val rh = blackHeight(node.nn.right) if (lh == -1 || lh != rh) -1 - else if (isRed(node)) lh + else if (isRed(node.nn)) lh else lh + 1 } } @@ -608,7 +616,7 @@ private[collection] object RedBlackTree { /** Build a Tree suitable for a TreeSet from an ordered sequence of keys */ def fromOrderedKeys[A](xs: Iterator[A]^, size: Int): Tree[A, Null] = { val maxUsedDepth = 32 - Integer.numberOfLeadingZeros(size) // maximum depth of non-leaf nodes - def f(level: Int, size: Int): Node[A, Null] = size match { + def f(level: Int, size: Int): Node[A, Null] | Null = size match { case 0 => null case 1 => new Node(xs.next(), null, level == maxUsedDepth && level != 1, null, null, null) case n => @@ -617,8 +625,8 @@ private[collection] object RedBlackTree { val x = xs.next() val right = f(level+1, size-1-leftSize) val n = new Node(x, null, red = false, left, right, null) - if(left ne null) left.parent = n - right.parent = n + if(left ne null) left.nn.parent = n + right.nn.parent = n n } new Tree(f(1, size), size) @@ -627,7 +635,7 @@ private[collection] object RedBlackTree { /** Build a Tree suitable for a TreeMap from an ordered sequence of key/value pairs */ def fromOrderedEntries[A, B](xs: Iterator[(A, B)]^, size: Int): Tree[A, B] = { val maxUsedDepth = 32 - Integer.numberOfLeadingZeros(size) // maximum depth of non-leaf nodes - def f(level: Int, size: Int): Node[A, B] = size match { + def f(level: Int, size: Int): Node[A, B] | Null = size match { case 0 => null case 1 => val (k, v) = xs.next() @@ -638,18 +646,18 @@ private[collection] object RedBlackTree { val (k, v) = xs.next() val right = f(level+1, size-1-leftSize) val n = new Node(k, v, red = false, left, right, null) - if(left ne null) left.parent = n - right.parent = n + if(left ne null) left.nn.parent = n + right.nn.parent = n n } new Tree(f(1, size), size) } - def copyTree[A, B](n: Node[A, B]): Node[A, B] = + def copyTree[A, B](n: Node[A, B] | Null): Node[A, B] | Null = if(n eq null) null else { - val c = new Node(n.key, n.value, n.red, copyTree(n.left), copyTree(n.right), null) - if(c.left != null) c.left.parent = c - if(c.right != null) c.right.parent = c + val c = new Node(n.nn.key, n.nn.value, n.nn.red, copyTree(n.nn.left), copyTree(n.nn.right), null) + if(c.left != null) c.left.nn.parent = c + if(c.right != null) c.right.nn.parent = c c } } diff --git a/library/src/scala/collection/mutable/TreeMap.scala b/library/src/scala/collection/mutable/TreeMap.scala index 04bd71a424d6..7ec62e57037a 100644 --- a/library/src/scala/collection/mutable/TreeMap.scala +++ b/library/src/scala/collection/mutable/TreeMap.scala @@ -82,7 +82,7 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( scala.collection.convert.impl.AnyBinaryTreeStepper.from[(K, V), RB.Node[K, V]]( - size, tree.root, _.left, _.right, x => (x.key, x.value) + size, tree.root, _.left.nn, _.right.nn, x => (x.key, x.value) ) ) @@ -90,10 +90,10 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: import scala.collection.convert.impl._ type T = RB.Node[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left, _.right, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree.root, _.left, _.right, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree.root, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -102,10 +102,10 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: import scala.collection.convert.impl._ type T = RB.Node[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.value.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.value.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.value.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree.root, _.left, _.right, _.value)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree.root, _.left.nn, _.right.nn, _.value)) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/collection/mutable/TreeSet.scala b/library/src/scala/collection/mutable/TreeSet.scala index f54423cbe12d..66141c9982e8 100644 --- a/library/src/scala/collection/mutable/TreeSet.scala +++ b/library/src/scala/collection/mutable/TreeSet.scala @@ -59,10 +59,10 @@ sealed class TreeSet[A] private (private val tree: RB.Tree[A, Null])(implicit va import scala.collection.convert.impl._ type T = RB.Node[A, Null] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left, _.right, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.root, _.left, _.right, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.root, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } From e5cdd00285bb68a379741e6d7f216c0d1719409b Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 13:52:44 +0200 Subject: [PATCH 07/46] Update TrieMap --- .../scala/collection/concurrent/TrieMap.scala | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/library/src/scala/collection/concurrent/TrieMap.scala b/library/src/scala/collection/concurrent/TrieMap.scala index 77cf96e62225..5691e89f0d0b 100644 --- a/library/src/scala/collection/concurrent/TrieMap.scala +++ b/library/src/scala/collection/concurrent/TrieMap.scala @@ -16,7 +16,6 @@ package concurrent import scala.language.`2.13` import language.experimental.captureChecking -import scala.language.unsafeNulls import java.util.concurrent.atomic._ import scala.{unchecked => uc} @@ -35,20 +34,20 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e def this(g: Gen, equiv: Equiv[K]) = this(null, g, equiv) - def WRITE(nval: MainNode[K, V]) = INodeBase.updater.set(this, nval) + def WRITE(nval: MainNode[K, V] | Null) = INodeBase.updater.set(this, nval) def CAS(old: MainNode[K, V], n: MainNode[K, V]) = INodeBase.updater.compareAndSet(this, old, n) - def gcasRead(ct: TrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct) + def gcasRead(ct: TrieMap[K, V]): MainNode[K, V] | Null = GCAS_READ(ct) - def GCAS_READ(ct: TrieMap[K, V]): MainNode[K, V] = { + def GCAS_READ(ct: TrieMap[K, V]): MainNode[K, V] | Null = { val m = /*READ*/mainnode val prevval: MainNode[K, V] | Null = /*READ*/m.prev if (prevval eq null) m else GCAS_Complete(m, ct) } - @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: TrieMap[K, V]): MainNode[K, V] = if (m eq null) null else { + @tailrec private def GCAS_Complete(m: MainNode[K, V] | Null, ct: TrieMap[K, V]): MainNode[K, V] | Null = if (m eq null) null else { // complete the GCAS val prev: MainNode[K, V] | Null = /*READ*/m.prev val ctr = ct.readRoot(abort = true) @@ -74,7 +73,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e else GCAS_Complete(m, ct) } else { // try to abort - m.CAS_PREV(prev, new FailedNode(prev)) + m.CAS_PREV(prev, new FailedNode(prev.nn)) GCAS_Complete(/*READ*/mainnode, ct) } } @@ -107,7 +106,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e * * @return true if successful, false otherwise */ - @tailrec def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): Boolean = { + @tailrec def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V] | Null, startgen: Gen, ct: TrieMap[K, V]): Boolean = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -141,7 +140,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e GCAS(cn, ncnode, ct) } case tn: TNode[K, V] => - clean(parent, ct, lev - 5) + clean(parent.nn, ct, lev - 5) false case ln: LNode[K, V] => // 3) an l-node val nn = ln.inserted(k, v) @@ -163,7 +162,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e * * @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key) */ - @tailrec def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, fullEquals: Boolean, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): Option[V] = { + @tailrec def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, fullEquals: Boolean, lev: Int, parent: INode[K, V] | Null, startgen: Gen, ct: TrieMap[K, V]): Option[V] | Null = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -220,7 +219,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e case otherv => None } case sn: TNode[K, V] => - clean(parent, ct, lev - 5) + clean(parent.nn, ct, lev - 5) null case ln: LNode[K, V] => // 3) an l-node def insertln() = { @@ -259,7 +258,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e * @return NO_SUCH_ELEMENT_SENTINEL if no value has been found, RESTART if the operation wasn't successful, * or any other value otherwise */ - @tailrec def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): AnyRef = { + @tailrec def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V] | Null, startgen: Gen, ct: TrieMap[K, V]): AnyRef = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -286,7 +285,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e } case tn: TNode[_, _] => // 3) non-live node def cleanReadOnly(tn: TNode[K, V]) = if (ct.nonReadOnly) { - clean(parent, ct, lev - 5) + clean(parent.nn, ct, lev - 5) RESTART } else { if (tn.hc == hc && tn.k == k) tn.v.asInstanceOf[AnyRef] @@ -314,9 +313,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e removalPolicy: Int, hc: Int, lev: Int, - parent: INode[K, V], + parent: INode[K, V] | Null, startgen: Gen, - ct: TrieMap[K, V]): Option[V] = { + ct: TrieMap[K, V]): Option[V] | Null = { GCAS_READ(ct) match { case cn: CNode[K, V] => @@ -344,8 +343,8 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e if (res == None || (res eq null)) res else { - @tailrec def cleanParent(nonlive: AnyRef): Unit = { - val cn = parent.GCAS_READ(ct) + @tailrec def cleanParent(nonlive: AnyRef | Null): Unit = { + val cn = parent.nn.GCAS_READ(ct) cn match { case cn: CNode[K, V] => val idx = (hc >>> (lev - 5)) & 0x1f @@ -358,7 +357,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e if (sub eq this) (nonlive: @uc) match { case tn: TNode[K, V] @uc => val ncn = cn.updatedAt(pos, tn.copyUntombed, gen).toContracted(lev - 5) - if (!parent.GCAS(cn, ncn, ct)) + if (!parent.nn.GCAS(cn, ncn, ct)) if (ct.readRoot().gen == startgen) cleanParent(nonlive) } } @@ -376,7 +375,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e } } case tn: TNode[K, V] => - clean(parent, ct, lev - 5) + clean(parent.nn, ct, lev - 5) null case ln: LNode[K, V] => if (removalPolicy == RemovalPolicy.Always) { @@ -404,10 +403,10 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e def isNullInode(ct: TrieMap[K, V]) = GCAS_READ(ct) eq null def cachedSize(ct: TrieMap[K, V]): Int = - GCAS_READ(ct).cachedSize(ct) + GCAS_READ(ct).nn.cachedSize(ct) def knownSize(ct: TrieMap[K, V]): Int = - GCAS_READ(ct).knownSize() + GCAS_READ(ct).nn.knownSize() /* this is a quiescent method! */ def string(lev: Int) = "%sINode -> %s".format(" " * lev, mainnode match { @@ -690,7 +689,7 @@ private[concurrent] case class RDCSS_Descriptor[K, V](old: INode[K, V], expected * For details, see: [[http://lampwww.epfl.ch/~prokopec/ctries-snapshot.pdf]] */ @SerialVersionUID(-5212455458703321708L) -final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[TrieMap[K, V], AnyRef], hashf: Hashing[K], ef: Equiv[K]) +final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[TrieMap[K, V], AnyRef] | Null, hashf: Hashing[K], ef: Equiv[K]) extends scala.collection.mutable.AbstractMap[K, V] with scala.collection.concurrent.Map[K, V] with scala.collection.mutable.MapOps[K, V, TrieMap, TrieMap[K, V]] @@ -788,8 +787,8 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater } } - private def RDCSS_ROOT(ov: INode[K, V], expectedmain: MainNode[K, V], nv: INode[K, V]): Boolean = { - val desc = RDCSS_Descriptor(ov, expectedmain, nv) + private def RDCSS_ROOT(ov: INode[K, V], expectedmain: MainNode[K, V] | Null, nv: INode[K, V]): Boolean = { + val desc = RDCSS_Descriptor(ov, expectedmain.nn, nv) if (CAS_ROOT(ov, desc)) { RDCSS_Complete(abort = false) /*READ*/desc.committed From 6b1847beefa6413f6b255a676ce641825b97a4fe Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 14:01:09 +0200 Subject: [PATCH 08/46] Fix some cc errors --- library/src/scala/collection/Iterator.scala | 2 +- library/src/scala/collection/SeqView.scala | 2 +- library/src/scala/collection/mutable/ListBuffer.scala | 6 +++--- library/src/scala/collection/mutable/UnrolledBuffer.scala | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src/scala/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 79aa35a956e1..0a8e9fb3c20e 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -188,7 +188,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 diff --git a/library/src/scala/collection/SeqView.scala b/library/src/scala/collection/SeqView.scala index 9879efb91d91..c97a1962ef1c 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: SomeSeqOps[A] | Null = underlying_ + private var underlying: SomeSeqOps[A]^{underlying_} | Null = underlying_ // force evaluation immediately by calling `length` so infinite collections // hang on `sorted`/`sortWith`/`sortBy` rather than on arbitrary method calls diff --git a/library/src/scala/collection/mutable/ListBuffer.scala b/library/src/scala/collection/mutable/ListBuffer.scala index 15a6fb7cb29e..88150b490b38 100644 --- a/library/src/scala/collection/mutable/ListBuffer.scala +++ b/library/src/scala/collection/mutable/ListBuffer.scala @@ -125,7 +125,7 @@ class ListBuffer[A] } // 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 @@ -144,7 +144,7 @@ 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) @@ -254,7 +254,7 @@ class ListBuffer[A] } } - 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) { diff --git a/library/src/scala/collection/mutable/UnrolledBuffer.scala b/library/src/scala/collection/mutable/UnrolledBuffer.scala index f27f87249d36..5c10264ded18 100644 --- a/library/src/scala/collection/mutable/UnrolledBuffer.scala +++ b/library/src/scala/collection/mutable/UnrolledBuffer.scala @@ -380,7 +380,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] 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 From e48e05065845b518bd5d0a0e469b7dd961e31bc3 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 14:15:12 +0200 Subject: [PATCH 09/46] Fix remaining cc errors --- .../src/scala/collection/convert/AsScalaConverters.scala | 8 ++++---- library/src/scala/collection/immutable/HashMap.scala | 2 +- library/src/scala/collection/mutable/HashSet.scala | 8 ++++---- library/src/scala/collection/mutable/LongMap.scala | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index d4c950d23e2c..5ac91f3c4a62 100644 --- a/library/src/scala/collection/convert/AsScalaConverters.scala +++ b/library/src/scala/collection/convert/AsScalaConverters.scala @@ -43,7 +43,7 @@ trait AsScalaConverters { */ def asScala[A](i: ju.Iterator[A] | Null): Iterator[A] | Null = i match { case null => null - case wrapper: IteratorWrapper[A @uc] => wrapper.underlying + case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JIteratorWrapper(i.nn) } @@ -61,7 +61,7 @@ trait AsScalaConverters { */ def asScala[A](e: ju.Enumeration[A] | Null): Iterator[A] | Null = e match { case null => null - case wrapper: IteratorWrapper[A @uc] => wrapper.underlying + case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JEnumerationWrapper(e.nn) } @@ -79,7 +79,7 @@ trait AsScalaConverters { */ def asScala[A](i: jl.Iterable[A] | Null): Iterable[A] | Null = i match { case null => null - case wrapper: IterableWrapper[A @uc] => wrapper.underlying + case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JIterableWrapper(i.nn) } @@ -94,7 +94,7 @@ trait AsScalaConverters { */ def asScala[A](c: ju.Collection[A] | Null): Iterable[A] | Null = c match { case null => null - case wrapper: IterableWrapper[A @uc] => wrapper.underlying + case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JCollectionWrapper(c.nn) } diff --git a/library/src/scala/collection/immutable/HashMap.scala b/library/src/scala/collection/immutable/HashMap.scala index 2b91a153b733..9b4c8cc75a90 100644 --- a/library/src/scala/collection/immutable/HashMap.scala +++ b/library/src/scala/collection/immutable/HashMap.scala @@ -2206,7 +2206,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() diff --git a/library/src/scala/collection/mutable/HashSet.scala b/library/src/scala/collection/mutable/HashSet.scala index 505108a59ef6..2ba4c9909689 100644 --- a/library/src/scala/collection/mutable/HashSet.scala +++ b/library/src/scala/collection/mutable/HashSet.scala @@ -243,10 +243,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, _.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)) + case StepperShape.IntShape => new IntTableStepper[Node[A]] (size, table, _.next.nn, _.key.asInstanceOf[Int], 0, table.length) + case StepperShape.LongShape => new LongTableStepper[Node[A]] (size, table, _.next.nn, _.key.asInstanceOf[Long], 0, table.length) + case StepperShape.DoubleShape => new DoubleTableStepper[Node[A]](size, table, _.next.nn, _.key.asInstanceOf[Double], 0, table.length) + case _ => shape.parUnbox(new AnyTableStepper[A, Node[A]](size, table, _.next.nn, _.key, 0, table.length)) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/collection/mutable/LongMap.scala b/library/src/scala/collection/mutable/LongMap.scala index 36980718874c..c19e240be1d7 100644 --- a/library/src/scala/collection/mutable/LongMap.scala +++ b/library/src/scala/collection/mutable/LongMap.scala @@ -469,18 +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] = { + 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] = From 825052184f48105cb2cbdd21ca715c67d8dff580 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 15:46:55 +0200 Subject: [PATCH 10/46] Clean some unnecessary .nn --- library/src/scala/collection/Iterator.scala | 6 +- library/src/scala/collection/View.scala | 6 +- .../scala/collection/concurrent/TrieMap.scala | 12 +- .../convert/AsScalaConverters.scala | 2 +- .../convert/impl/IteratorStepper.scala | 28 ++-- .../scala/collection/immutable/HashMap.scala | 24 ++-- .../scala/collection/immutable/HashSet.scala | 8 +- .../scala/collection/immutable/LazyList.scala | 3 +- .../immutable/LazyListIterable.scala | 2 +- .../src/scala/collection/immutable/List.scala | 14 +- .../scala/collection/immutable/ListMap.scala | 6 +- .../collection/immutable/RedBlackTree.scala | 67 ++++----- .../scala/collection/immutable/TreeMap.scala | 26 ++-- .../collection/immutable/TreeSeqMap.scala | 6 +- .../scala/collection/immutable/TreeSet.scala | 10 +- .../scala/collection/immutable/Vector.scala | 2 +- .../scala/collection/mutable/AnyRefMap.scala | 133 +++++++++--------- .../src/scala/collection/mutable/BitSet.scala | 4 +- .../mutable/CollisionProofHashMap.scala | 29 ++-- .../scala/collection/mutable/HashMap.scala | 4 +- .../scala/collection/mutable/HashTable.scala | 28 ++-- .../collection/mutable/LinkedHashMap.scala | 10 +- .../collection/mutable/LinkedHashSet.scala | 5 +- .../scala/collection/mutable/ListBuffer.scala | 12 +- .../scala/collection/mutable/LongMap.scala | 112 +++++++-------- .../collection/mutable/UnrolledBuffer.scala | 16 +-- .../scala/concurrent/BatchingExecutor.scala | 2 +- .../src/scala/concurrent/impl/Promise.scala | 8 +- library/src/scala/io/Codec.scala | 12 +- library/src/scala/io/Source.scala | 2 +- library/src/scala/math/BigInt.scala | 2 +- library/src/scala/ref/WeakReference.scala | 2 +- .../src/scala/reflect/NameTransformer.scala | 6 +- .../src/scala/sys/process/ProcessImpl.scala | 2 +- library/src/scala/util/Sorting.scala | 2 +- library/src/scala/util/Using.scala | 2 +- 36 files changed, 309 insertions(+), 306 deletions(-) diff --git a/library/src/scala/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 0a8e9fb3c20e..a1cd708d94a5 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -278,7 +278,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite 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.nn).asInstanceOf[immutable.ArraySeq[B]] + val res = immutable.ArraySeq.unsafeWrapArray(buffer).asInstanceOf[immutable.ArraySeq[B]] buffer = null first = false res @@ -1188,9 +1188,9 @@ object Iterator extends IterableFactory[Iterator] { false } else { - current = tail.nn.headIterator + current = tail.headIterator if (last eq tail) last = last.nn.tail - tail = tail.nn.tail + tail = tail.tail merge() if (currentHasNextChecked) true else if (current != null && current.hasNext) { diff --git a/library/src/scala/collection/View.scala b/library/src/scala/collection/View.scala index 3c74825f7391..79c88259b953 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -459,8 +459,8 @@ object View extends IterableFactory[View] { len = 0 while(underlying.hasNext) { val n = underlying.next().asInstanceOf[AnyRef] - if(pos >= buf.nn.length) buf.nn.addOne(n) - else buf.nn(pos) = n + if(pos >= buf.length) buf.addOne(n) + else buf(pos) = n pos += 1 if(pos == maxlen) pos = 0 len += 1 @@ -513,7 +513,7 @@ object View extends IterableFactory[View] { def init(): Unit = if(buf eq null) { buf = new ArrayBuffer[AnyRef](maxlen min 256) while(pos < maxlen && underlying.hasNext) { - buf.nn.addOne(underlying.next().asInstanceOf[AnyRef]) + buf.addOne(underlying.next().asInstanceOf[AnyRef]) pos += 1 } if(!underlying.hasNext) len = 0 diff --git a/library/src/scala/collection/concurrent/TrieMap.scala b/library/src/scala/collection/concurrent/TrieMap.scala index 5691e89f0d0b..dd07a4205441 100644 --- a/library/src/scala/collection/concurrent/TrieMap.scala +++ b/library/src/scala/collection/concurrent/TrieMap.scala @@ -673,7 +673,7 @@ private[concurrent] object CNode { } -private[concurrent] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmain: MainNode[K, V], nv: INode[K, V]) { +private[concurrent] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmain: MainNode[K, V] | Null, nv: INode[K, V]) { @volatile var committed = false } @@ -788,7 +788,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater } private def RDCSS_ROOT(ov: INode[K, V], expectedmain: MainNode[K, V] | Null, nv: INode[K, V]): Boolean = { - val desc = RDCSS_Descriptor(ov, expectedmain.nn, nv) + val desc = RDCSS_Descriptor(ov, expectedmain, nv) if (CAS_ROOT(ov, desc)) { RDCSS_Complete(abort = false) /*READ*/desc.committed @@ -858,7 +858,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater @tailrec def snapshot(): TrieMap[K, V] = { val r = RDCSS_READ_ROOT() val expmain = r.gcasRead(this) - if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new TrieMap(r.copyToGen(new Gen, this), rootupdater.nn, hashing, equality) + if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new TrieMap(r.copyToGen(new Gen, this), rootupdater, hashing, equality) else snapshot() } @@ -1084,13 +1084,13 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: def next() = if (hasNext) { var r: (K, V) | Null = null if (subiter ne null) { - r = subiter.nn.next() + r = subiter.next() checkSubiter() } else { r = current.nn.kvPair advance() } - r.nn + r } else Iterator.empty.next() private def readin(in: INode[K, V]) = in.gcasRead(ct) match { @@ -1152,7 +1152,7 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: // this one needs to be evaluated if (this.subiter == null) it.subiter = null else { - val lst = this.subiter.nn.to(immutable.List) + val lst = this.subiter.to(immutable.List) this.subiter = lst.iterator it.subiter = lst.iterator } diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index 5ac91f3c4a62..2c7fa3d788cd 100644 --- a/library/src/scala/collection/convert/AsScalaConverters.scala +++ b/library/src/scala/collection/convert/AsScalaConverters.scala @@ -206,6 +206,6 @@ trait AsScalaConverters { */ def asScala(p: ju.Properties | Null): mutable.Map[String, String] | Null = p match { case null => null - case _ => new JPropertiesWrapper(p.nn) + case _ => new JPropertiesWrapper(p) } } diff --git a/library/src/scala/collection/convert/impl/IteratorStepper.scala b/library/src/scala/collection/convert/impl/IteratorStepper.scala index 7e42f9bb75f3..2e8e35e29205 100644 --- a/library/src/scala/collection/convert/impl/IteratorStepper.scala +++ b/library/src/scala/collection/convert/impl/IteratorStepper.scala @@ -24,16 +24,16 @@ private[collection] class AnyIteratorStepper[A](_underlying: Iterator[A] | Null) with AnyStepper[A] { protected def semiclone(): AnyIteratorStepper[A] = new AnyIteratorStepper(null) - def nextStep(): A = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() + def nextStep(): A = if (proxied ne null) proxied.nextStep() else underlying.nn.next() - def trySplit(): AnyStepper[A] | Null = if (proxied ne null) proxied.nn.trySplit() else { + def trySplit(): AnyStepper[A] | Null = if (proxied ne null) proxied.trySplit() else { val acc = new AnyAccumulator[A] var i = 0 val n = nextChunkSize & 0xFFFFFFFC while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.nn.trySplit() + proxied.trySplit() } else { val ans = semiclone() @@ -49,16 +49,16 @@ private[collection] class DoubleIteratorStepper(_underlying: Iterator[Double] | with DoubleStepper { protected def semiclone(): DoubleIteratorStepper = new DoubleIteratorStepper(null) - def nextStep(): Double = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() + def nextStep(): Double = if (proxied ne null) proxied.nextStep() else underlying.nn.next() - def trySplit(): DoubleStepper | Null = if (proxied ne null) proxied.nn.trySplit() else { + def trySplit(): DoubleStepper | Null = if (proxied ne null) proxied.trySplit() else { val acc = new DoubleAccumulator var i = 0 val n = nextChunkSize & 0xFFFFFFFC while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.nn.trySplit() + proxied.trySplit() } else { val ans = semiclone() @@ -74,16 +74,16 @@ private[collection] class IntIteratorStepper(_underlying: Iterator[Int] | Null) with IntStepper { protected def semiclone(): IntIteratorStepper = new IntIteratorStepper(null) - def nextStep(): Int = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() + def nextStep(): Int = if (proxied ne null) proxied.nextStep() else underlying.nn.next() - def trySplit(): IntStepper | Null = if (proxied ne null) proxied.nn.trySplit() else { + def trySplit(): IntStepper | Null = if (proxied ne null) proxied.trySplit() else { val acc = new IntAccumulator var i = 0 val n = nextChunkSize & 0xFFFFFFFC while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.nn.trySplit() + proxied.trySplit() } else { val ans = semiclone() @@ -99,16 +99,16 @@ private[collection] class LongIteratorStepper(_underlying: Iterator[Long] | Null with LongStepper { protected def semiclone(): LongIteratorStepper = new LongIteratorStepper(null) - def nextStep(): Long = if (proxied ne null) proxied.nn.nextStep() else underlying.nn.next() + def nextStep(): Long = if (proxied ne null) proxied.nextStep() else underlying.nn.next() - def trySplit(): LongStepper | Null = if (proxied ne null) proxied.nn.trySplit() else { + def trySplit(): LongStepper | Null = if (proxied ne null) proxied.trySplit() else { val acc = new LongAccumulator var i = 0 val n = nextChunkSize & 0xFFFFFFFC while (i < n && underlying.nn.hasNext) { acc += underlying.nn.next(); i += 1 } if (i < n || !underlying.nn.hasNext) { proxied = acc.stepper - proxied.nn.trySplit() + proxied.trySplit() } else { val ans = semiclone() @@ -126,6 +126,6 @@ private[convert] abstract class IteratorStepperBase[A, SP <: Stepper[A], Semi <: 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.nn.estimateSize else Long.MaxValue - def hasStep: Boolean = if (proxied ne null) proxied.nn.hasStep else underlying.nn.hasNext + def estimateSize: Long = if (proxied ne null) proxied.estimateSize else Long.MaxValue + def hasStep: Boolean = if (proxied ne null) proxied.hasStep else underlying.nn.hasNext } diff --git a/library/src/scala/collection/immutable/HashMap.scala b/library/src/scala/collection/immutable/HashMap.scala index 9b4c8cc75a90..2a4774a75c3c 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).nn) + newHashMapOrThis(rootNode.removed(key, keyUnimprovedHash, improve(keyUnimprovedHash), 0)) } 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).nn.updated(mergedK, mergedV, mergedOriginalHash, mergedImprovedHash, 0, replaceValue = true)) + new HashMap(that.rootNode.removed(thatPayload._1, originalHash, improved, 0).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).nn + curr = curr.removed(next.key, originalHash, improved, 0) 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).nn + curr = curr.removed(next.key, originalHash, improved, 0) 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).nn + curr = curr.removed(next, originalHash, improved, 0) if (curr.size == 0) { return HashMap.empty } @@ -1773,7 +1773,7 @@ private final class BitmapIndexedMapNode[K, +V]( if (newNodes == null) { newNodes = mutable.Queue.empty } - newNodes.nn += newSubNode + newNodes += newSubNode } } else if (newSubNode.size == 1) { newDataMap |= bitpos @@ -1781,7 +1781,7 @@ private final class BitmapIndexedMapNode[K, +V]( if (nodesToMigrateToData == null) { nodesToMigrateToData = mutable.Queue() } - nodesToMigrateToData.nn += newSubNode + nodesToMigrateToData += newSubNode } nodeIndex += 1 @@ -2017,9 +2017,9 @@ private final class HashCollisionMapNode[K, +V ]( if (hc.indexOf(nextPayload._1) < 0) { if (newContent == null) { newContent = new VectorBuilder[(K, V1)]() - newContent.nn.addAll(hc.content) + newContent.addAll(hc.content) } - newContent.nn.addOne(nextPayload) + newContent.addOne(nextPayload) } } if (newContent eq null) hc else new HashCollisionMapNode(originalHash, hash, newContent.result()) @@ -2182,7 +2182,7 @@ private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) keyHash = improve(originalHash), originalHash = originalHash, shift = 0 - ).nn + ) currentValueCursor += 1 } curr @@ -2339,11 +2339,11 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K, if (rootNode.size == 0) { HashMap.empty } else if (aliased != null) { - aliased.nn + aliased } else { aliased = new HashMap(rootNode) releaseFence() - aliased.nn + aliased } 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 ea2bd788606c..c052dee5506d 100644 --- a/library/src/scala/collection/immutable/HashSet.scala +++ b/library/src/scala/collection/immutable/HashSet.scala @@ -1150,7 +1150,7 @@ private final class BitmapIndexedSetNode[A]( if (newNodes eq null) { newNodes = mutable.Queue.empty } - newNodes.nn += newSubNode + newNodes += 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.nn += newSubNode + nodesToMigrateToData += newSubNode } nodeIndex += 1 @@ -1265,7 +1265,7 @@ private final class BitmapIndexedSetNode[A]( if (newNodes eq null) { newNodes = mutable.Queue.empty } - newNodes.nn += newSubNode + newNodes += 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.nn += newSubNode + nodesToMigrateToData += newSubNode } nodeIndex += 1 diff --git a/library/src/scala/collection/immutable/LazyList.scala b/library/src/scala/collection/immutable/LazyList.scala index a0430c3a0339..b056fab200ec 100644 --- a/library/src/scala/collection/immutable/LazyList.scala +++ b/library/src/scala/collection/immutable/LazyList.scala @@ -1117,7 +1117,7 @@ object LazyList extends SeqFactory[LazyList] { var rest = restRef // var rest = restRef.elem while (!itHasNext && !rest.isEmpty) { it = f(rest.head).iterator - itHasNext = it.nn.hasNext + itHasNext = it.hasNext if (!itHasNext) { // wait to advance `rest` because `it.next()` can throw rest = rest.tail restRef = rest // restRef.elem = rest @@ -1449,3 +1449,4 @@ object LazyList extends SeqFactory[LazyList] { private[this] def readResolve(): Any = coll } } + diff --git a/library/src/scala/collection/immutable/LazyListIterable.scala b/library/src/scala/collection/immutable/LazyListIterable.scala index f0fddc2fb543..c74cbf4d5abc 100644 --- a/library/src/scala/collection/immutable/LazyListIterable.scala +++ b/library/src/scala/collection/immutable/LazyListIterable.scala @@ -1139,7 +1139,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { var rest: LazyListIterable[A]^{ll} = restRef // var rest = restRef.elem while (!itHasNext && !rest.isEmpty) { it = f(rest.head).iterator - itHasNext = it.nn.hasNext + itHasNext = it.hasNext if (!itHasNext) { // wait to advance `rest` because `it.next()` can throw rest = rest.tail restRef = rest // restRef.elem = rest diff --git a/library/src/scala/collection/immutable/List.scala b/library/src/scala/collection/immutable/List.scala index 8265c5c4caa2..a26e63078b24 100644 --- a/library/src/scala/collection/immutable/List.scala +++ b/library/src/scala/collection/immutable/List.scala @@ -261,9 +261,9 @@ sealed abstract class List[+A] 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.nn + if (rest eq Nil) return if (h eq null) Nil else h } - var t = h.nn + var t = h // Remaining elements while (rest ne Nil) { x = pf.applyOrElse(rest.head, List.partialNotApplied) @@ -275,7 +275,7 @@ sealed abstract class List[+A] rest = rest.tail } releaseFence() - h.nn + h } } @@ -290,7 +290,7 @@ sealed abstract class List[+A] if (t eq null) { h = nx } else { - t.nn.next = nx + t.next = nx } t = nx } @@ -458,7 +458,7 @@ sealed abstract class List[+A] if (mappedHead eq null) unchanged else { mappedLast.nn.next = (unchanged: List[B]) - mappedHead.nn + mappedHead } } else { @@ -474,13 +474,13 @@ sealed abstract class List[+A] while (xc ne pending) { val next = new ::[B](xc.head, Nil) if (mappedHead1 eq null) mappedHead1 = next - if (mappedLast1 ne null) mappedLast1.nn.next = next + if (mappedLast1 ne null) mappedLast1.next = next mappedLast1 = next xc = xc.tail } val next = new ::(head1, Nil) if (mappedHead1 eq null) mappedHead1 = next - if (mappedLast1 ne null) mappedLast1.nn.next = next + if (mappedLast1 ne null) mappedLast1.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 0780e9d99eb7..b6599369a1bd 100644 --- a/library/src/scala/collection/immutable/ListMap.scala +++ b/library/src/scala/collection/immutable/ListMap.scala @@ -202,7 +202,7 @@ object ListMap extends MapFactory[ListMap] { while (i < index) { val temp = new ListMap.Node(curr.key, curr.value, null) if (prev != null) { - prev.nn._init = temp + prev._init = temp } prev = temp curr = curr.init @@ -213,10 +213,10 @@ object ListMap extends MapFactory[ListMap] { } val newNode = new ListMap.Node(curr.key, v, curr.init) if (prev != null) { - prev.nn._init = newNode + prev._init = newNode } releaseFence() - if (newHead == null) newNode else newHead.nn + if (newHead == null) newNode else newHead } else { this } diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index b1e58bd44acf..a853ddd1b780 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -87,7 +87,7 @@ private[collection] object RedBlackTree { // black(nl.L) nl.KV black // nl.R KV R val resultLeft = newLeft_left.nn.mutableBlack - val resultRight = tree.mutableBlackWithLeft(newLeft_right.nn) + val resultRight = tree.mutableBlackWithLeft(newLeft_right) newLeft.mutableWithLeftRight(resultLeft, resultRight) } else if (isRedTree(newLeft_right)) { @@ -97,8 +97,8 @@ private[collection] object RedBlackTree { val newLeft_right_right = newLeft_right.nn.right - val resultLeft = newLeft.mutableBlackWithRight(newLeft_right.nn.left.nn) - val resultRight = tree.mutableBlackWithLeft(newLeft_right_right.nn) + val resultLeft = newLeft.mutableBlackWithRight(newLeft_right.nn.left) + val resultRight = tree.mutableBlackWithLeft(newLeft_right_right) newLeft_right.nn.mutableWithLeftRight(resultLeft, resultRight) } else { @@ -129,8 +129,8 @@ private[collection] object RedBlackTree { // black nr.L.KV black // L KV nr.L.L nr.L.R nr.KV nr.R - val resultLeft = tree.mutableBlackWithRight(newRight_left.nn.left.nn) - val resultRight = newRight.mutableBlackWithLeft(newRight_left.nn.right.nn) + val resultLeft = tree.mutableBlackWithRight(newRight_left.nn.left) + val resultRight = newRight.mutableBlackWithLeft(newRight_left.nn.right) newRight_left.nn.mutableWithLeftRight(resultLeft, resultRight) @@ -141,7 +141,7 @@ private[collection] object RedBlackTree { // black nr.KV black(nr.R) // L KV nr.L - val resultLeft = tree.mutableBlackWithRight(newRight_left.nn) + val resultLeft = tree.mutableBlackWithRight(newRight_left) val resultRight = newRight_right.nn.mutableBlack newRight.mutableWithLeftRight(resultLeft, resultRight) @@ -209,13 +209,13 @@ private[collection] object RedBlackTree { def smallest[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { if (tree eq null) throw new NoSuchElementException("empty tree") - var result = tree.nn + var result = tree while (result.left ne null) result = result.left.nn result } def greatest[A, B](tree: Tree[A, B] | Null): Tree[A, B] = { if (tree eq null) throw new NoSuchElementException("empty tree") - var result = tree.nn + var result = tree while (result.right ne null) result = result.right.nn result } @@ -238,7 +238,7 @@ private[collection] object RedBlackTree { else { val tr = tree.right if (tr eq null) tree.left - else if (tr.isBlack) balRight(tree, tree.left, _init(tr)) + else if (tr.nn.isBlack) balRight(tree, tree.left, _init(tr)) else tree.redWithRight(_init(tr)) } blacken(_init(tree)) @@ -356,7 +356,7 @@ private[collection] object RedBlackTree { // black(nl.L) nl.KV black // nl.R KV R val resultLeft = newLeft_left.nn.black - val resultRight = tree.blackWithLeft(newLeft_right.nn) + val resultRight = tree.blackWithLeft(newLeft_right) newLeft.withLeftRight(resultLeft, resultRight) } else if (isRedTree(newLeft_right)) { @@ -365,8 +365,8 @@ private[collection] object RedBlackTree { // nl.L nl.KV nl.R.L nl.R.R KV R val newLeft_right_right = newLeft_right.nn.right - val resultLeft = newLeft.blackWithRight(newLeft_right.nn.left.nn) - val resultRight = tree.blackWithLeft(newLeft_right_right.nn) + val resultLeft = newLeft.blackWithRight(newLeft_right.nn.left) + val resultRight = tree.blackWithLeft(newLeft_right_right) newLeft_right.nn.withLeftRight(resultLeft, resultRight) } else { @@ -395,8 +395,8 @@ private[collection] object RedBlackTree { // RED // black nr.L.KV black // L KV nr.L.L nr.L.R nr.KV nr.R - val resultLeft = tree.blackWithRight(newRight_left.nn.left.nn) - val resultRight = newRight.blackWithLeft(newRight_left.nn.right.nn) + val resultLeft = tree.blackWithRight(newRight_left.nn.left) + val resultRight = newRight.blackWithLeft(newRight_left.nn.right) newRight_left.nn.withLeftRight(resultLeft, resultRight) } else { @@ -405,10 +405,10 @@ private[collection] object RedBlackTree { // RED // black nr.KV black(nr.R) // L KV nr.L - val resultLeft = tree.blackWithRight(newRight_left.nn) + val resultLeft = tree.blackWithRight(newRight_left) val resultRight = newRight_right.nn.black - newRight.withLeftRight(resultLeft, resultRight) + newRight.nn.withLeftRight(resultLeft, resultRight) } else { // tree // L KV newRight @@ -629,21 +629,21 @@ private[collection] object RedBlackTree { } else new Tree(_key, newValue.asInstanceOf[AnyRef], _left, _right, mutableRetainingColour) } - private[RedBlackTree] def mutableWithLeft[B1 >: B](newLeft: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def mutableWithLeft[B1 >: B](newLeft: Tree[A, B1] | Null): Tree[A, B1] = { if (_left eq newLeft) this else if (isMutable) { _left = newLeft this } else new Tree(_key, _value, newLeft, _right, mutableRetainingColour) } - private[RedBlackTree] def mutableWithRight[B1 >: B](newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def mutableWithRight[B1 >: B](newRight: Tree[A, B1] | Null): Tree[A, B1] = { if (_right eq newRight) this else if (isMutable) { _right = newRight this } else new Tree(_key, _value, _left, newRight, mutableRetainingColour) } - private[RedBlackTree] def mutableWithLeftRight[B1 >: B](newLeft: Tree[A, B1], newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def mutableWithLeftRight[B1 >: B](newLeft: Tree[A, B1] | Null, newRight: Tree[A, B1] | Null): Tree[A, B1] = { if ((_left eq newLeft) && (_right eq newRight)) this else if (isMutable) { _left = newLeft @@ -651,7 +651,7 @@ private[collection] object RedBlackTree { this } else new Tree(_key, _value, newLeft, newRight, mutableRetainingColour) } - private[RedBlackTree] def mutableBlackWithLeft[B1 >: B](newLeft: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def mutableBlackWithLeft[B1 >: B](newLeft: Tree[A, B1] | Null): Tree[A, B1] = { if ((_left eq newLeft) && isBlack) this else if (isMutable) { _count = initialBlackCount @@ -659,7 +659,7 @@ private[collection] object RedBlackTree { this } else new Tree(_key, _value, newLeft, _right, initialBlackCount) } - private[RedBlackTree] def mutableBlackWithRight[B1 >: B](newRight: Tree[A, B1]): Tree[A, B1] = { + private[RedBlackTree] def mutableBlackWithRight[B1 >: B](newRight: Tree[A, B1] | Null): Tree[A, B1] = { if ((_right eq newRight) && isBlack) this else if (isMutable) { _count = initialBlackCount @@ -865,8 +865,8 @@ private[collection] object RedBlackTree { @tailrec def find(tree: Tree[A, B] | Null): Tree[A, B] | Null = if (tree eq null) popNext() else find( - if (ordering.lteq(key, tree.nn.key)) goLeft(tree.nn) - else goRight(tree.nn) + if (ordering.lteq(key, tree.key)) goLeft(tree) + else goRight(tree) ) find(root) } @@ -1057,12 +1057,12 @@ private[collection] object RedBlackTree { val newLeft = del(tree.left, k) if (newLeft eq tree.left) tree else if (isBlackTree(tree.left)) balLeft(tree, newLeft, tree.right) - else tree.redWithLeft(newLeft.nn) + else tree.redWithLeft(newLeft) } else if (cmp > 0) { val newRight = del(tree.right, k) if (newRight eq tree.right) tree else if (isBlackTree(tree.right)) balRight(tree, tree.left, newRight) - else tree.redWithRight(newRight.nn) + else tree.redWithRight(newRight) } else append(tree.left, tree.right) } @@ -1082,14 +1082,14 @@ private[collection] object RedBlackTree { if (isRedTree(tl)) tree.redWithLeftRight(tl.nn.black, tr) else if (isBlackTree(tr)) balance(tree, tl, tr.nn.red) else if (isRedTree(tr) && isBlackTree(tr.nn.left)) - tr.nn.left.nn.redWithLeftRight(tree.blackWithLeftRight(tl, tr.nn.left.nn.left), balance(tr.nn, tr.nn.left.nn.right.nn, tr.nn.right.nn.red)) + tr.nn.left.nn.redWithLeftRight(tree.blackWithLeftRight(tl, tr.nn.left.nn.left), balance(tr.nn, tr.nn.left.nn.right, tr.nn.right.nn.red)) else sys.error("Defect: invariance violation") private[this] def balRight[A, B](tree: Tree[A,B], tl: Tree[A, B] | Null, tr: Tree[A, B] | Null): Tree[A, B] = if (isRedTree(tr)) tree.redWithLeftRight(tl, tr.nn.black) else if (isBlackTree(tl)) balance(tree, tl.nn.red, tr) else if (isRedTree(tl) && isBlackTree(tl.nn.right)) - tl.nn.right.nn.redWithLeftRight(balance(tl.nn, tl.nn.left.nn.red, tl.nn.right.nn.left.nn), tree.blackWithLeftRight(tl.nn.right.nn.right, tr)) + tl.nn.right.nn.redWithLeftRight(balance(tl.nn, tl.nn.left.nn.red, tl.nn.right.nn.left), tree.blackWithLeftRight(tl.nn.right.nn.right, tr)) else sys.error("Defect: invariance violation") /** `append` is similar to `join2` but requires that both subtrees have the same black height */ @@ -1100,21 +1100,21 @@ private[collection] object RedBlackTree { if (tr.isRed) { //tl is red, tr is red val bc = append(tl.right, tr.left) - if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left.nn), tr.withLeft(bc.nn.right.nn)) + if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left), tr.withLeft(bc.nn.right)) else tl.withRight(tr.withLeft(bc)) } else { //tl is red, tr is black - tl.withRight(append(tl.right, tr).nn) + tl.withRight(append(tl.right, tr)) } } else { if (tr.isBlack) { //tl is black tr is black val bc = append(tl.right, tr.left) - if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left.nn), tr.withLeft(bc.nn.right.nn)) + if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left), tr.withLeft(bc.nn.right)) else balLeft(tl, tl.left, tr.withLeft(bc)) } else { //tl is black tr is red - tr.withLeft(append(tl, tr.left).nn) + tr.withLeft(append(tl, tr.left)) } } } @@ -1203,14 +1203,14 @@ private[collection] object RedBlackTree { if(t.right eq null) (t.left.nn, t.key, t.value) else { val (tt, kk, vv) = splitLast(t.right.nn) - (join(t.left, t.key, t.value, tt).nn, kk, vv) + (join(t.left, t.key, t.value, tt), kk, vv) } 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 { - val (ttl, k, v) = splitLast(tl.nn) + val (ttl, k, v) = splitLast(tl) join(ttl, k, v, tr) } @@ -1245,3 +1245,4 @@ private[collection] object RedBlackTree { join2(tl, tr) } } + diff --git a/library/src/scala/collection/immutable/TreeMap.scala b/library/src/scala/collection/immutable/TreeMap.scala index ec8330f78fee..ef9298437b21 100644 --- a/library/src/scala/collection/immutable/TreeMap.scala +++ b/library/src/scala/collection/immutable/TreeMap.scala @@ -100,7 +100,7 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( scala.collection.convert.impl.AnyBinaryTreeStepper.from[(K, V), RB.Tree[K, V]]( - size, tree, _.left.nn, _.right.nn, x => (x.key, x.value) + size, tree.nn, _.left.nn, _.right.nn, x => (x.key, x.value) ) ) @@ -108,10 +108,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree, _.left.nn, _.right.nn, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree.nn, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -120,10 +120,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[V])) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[V])) } s.asInstanceOf[S with EfficientSplit] } @@ -212,17 +212,17 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl override def isEmpty = size == 0 - override def firstKey: K = RB.smallest(tree.nn).key + override def firstKey: K = RB.smallest(tree).key - override def lastKey: K = RB.greatest(tree.nn).key + override def lastKey: K = RB.greatest(tree).key override def head: (K, V) = { - val smallest = RB.smallest(tree.nn) + val smallest = RB.smallest(tree) (smallest.key, smallest.value) } override def last: (K, V) = { - val greatest = RB.greatest(tree.nn) + val greatest = RB.greatest(tree) (greatest.key, greatest.value) } diff --git a/library/src/scala/collection/immutable/TreeSeqMap.scala b/library/src/scala/collection/immutable/TreeSeqMap.scala index ba94814da45f..76e39cbc8c2e 100644 --- a/library/src/scala/collection/immutable/TreeSeqMap.scala +++ b/library/src/scala/collection/immutable/TreeSeqMap.scala @@ -356,7 +356,7 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { if (aliased eq null) { aliased = new TreeSeqMap(ong, bdr.result(), ord, orderedBy) } - aliased.nn + aliased } } @@ -589,8 +589,8 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { if (!hasMatch(ordinal, p, m)) { val b2 = join(ordinal, Tip(ordinal, value), p, this) if (parent != null) { - parent.nn.right = b2 - parent.nn + parent.right = b2 + parent } 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 85a04cb3c143..299f29970b78 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -138,10 +138,10 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ import scala.collection.convert.impl._ type T = RB.Tree[A, Any] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.nn, _.left.nn, _.right.nn, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -256,7 +256,7 @@ object TreeSet extends SortedIterableFactory[TreeSet] { case _ => var t: RB.Tree[E, Null] | Null = null val i = it.iterator - while (i.hasNext) t = RB.update(t.nn, i.next(), null, overwrite = false) + while (i.hasNext) t = RB.update(t, i.next(), null, overwrite = false) new TreeSet[E](t) } diff --git a/library/src/scala/collection/immutable/Vector.scala b/library/src/scala/collection/immutable/Vector.scala index afb357b25189..a5089a24b3e7 100644 --- a/library/src/scala/collection/immutable/Vector.scala +++ b/library/src/scala/collection/immutable/Vector.scala @@ -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.nn.length + suf.nn.length <= WIDTH-2) { + if(pre.length + suf.length <= WIDTH-2) { slices(prefixIdx(maxDim)) = concatArrays(pre, suf) slices(suffixIdx(maxDim)) = null } else resultDim += 1 diff --git a/library/src/scala/collection/mutable/AnyRefMap.scala b/library/src/scala/collection/mutable/AnyRefMap.scala index 0c361f31b847..8228254ddfe2 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 - @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 + private[this] var _hashes: Array[Int] = _ + private[this] var _keys: Array[AnyRef | Null] = _ + private[this] var _values: Array[AnyRef | Null] = _ if (initBlank) defaultInitialize(initialBufferSize) @@ -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.nn - val keys = _keys.nn + val hashes = _hashes + val keys = _keys 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.nn(e); g != 0}) { - if (g == h && { val q = _keys.nn(e); (q eq k) || ((q ne null) && (q equals k)) }) return e + while ({ g = _hashes(e); g != 0}) { + if (g == h && { val q = _keys(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.nn(i).asInstanceOf[V]) + if (i < 0) None else Some(_values(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.nn(i).asInstanceOf[V] + if (i < 0) default else _values(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.nn + val ohs = _hashes 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.nn(j)) { + if (ohs.ne(_hashes) || oh != _hashes(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.nn(j) = h - _keys.nn(j) = key.asInstanceOf[AnyRef] - _values.nn(j) = value.asInstanceOf[AnyRef] + _hashes(j) = h + _keys(j) = key.asInstanceOf[AnyRef] + _values(j) = value.asInstanceOf[AnyRef] if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() value } - else _values.nn(i).asInstanceOf[V] + else _values(i).asInstanceOf[V] } /** Retrieves the value associated with a key, or the default for that type if none exists @@ -202,7 +202,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi */ def getOrNull(key: K): V | Null = { val i = seekEntry(hashOf(key), key) - if (i < 0) null else _values.nn(i).asInstanceOf[V] + if (i < 0) null else _values(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.nn(i).asInstanceOf[V] + if (i < 0) defaultEntry(key) else _values(i).asInstanceOf[V] } /** Defers to defaultEntry to find a default value for the key. Throws an @@ -221,9 +221,9 @@ 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.nn - val ok = _keys.nn - val ov = _values.nn + val oh = _hashes + val ok = _keys + val ov = _values mask = newMask _hashes = new Array[Int](mask+1) _keys = new Array[AnyRef | Null](mask+1) @@ -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.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) + 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) } 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.nn(j) = h - _keys.nn(j) = key - _values.nn(j) = value.asInstanceOf[AnyRef] + _hashes(j) = h + _keys(j) = key + _values(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() None } else { - val ans = Some(_values.nn(i).asInstanceOf[V]) - _hashes.nn(i) = h - _values.nn(i) = value.asInstanceOf[AnyRef] + val ans = Some(_values(i).asInstanceOf[V]) + _hashes(i) = h + _values(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.nn(j) = h - _keys.nn(j) = key - _values.nn(j) = value.asInstanceOf[AnyRef] + _hashes(j) = h + _keys(j) = key + _values(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() } else { - _hashes.nn(i) = h - _values.nn(i) = value.asInstanceOf[AnyRef] + _hashes(i) = h + _values(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.nn(i) = Int.MinValue - _keys.nn(i) = null - _values.nn(i) = null + _hashes(i) = Int.MinValue + _keys(i) = null + _values(i) = null } this } @@ -334,9 +334,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi } private abstract class AnyRefMapIterator[A] extends AbstractIterator[A] { - private[this] val hz = _hashes.nn - private[this] val kz = _keys.nn - private[this] val vz = _values.nn + private[this] val hz = _hashes + private[this] val kz = _keys + private[this] val vz = _values private[this] var index = 0 @@ -367,9 +367,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi var i = 0 var e = _size while (e > 0) { - 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])) + 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])) 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.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]) + 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]) i += 1 e -= 1 } @@ -392,9 +392,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi } override def clone(): AnyRefMap[K, V] = { - 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 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 arm = new AnyRefMap[K, V](defaultEntry, 1, initBlank = false) 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 | Null] | Null, f: A => B): Unit = { + private[this] def foreachElement[A,B](elems: Array[AnyRef | Null], f: A => B): Unit = { var i,j = 0 - while (i < _hashes.nn.length & j < _size) { - val h = _hashes.nn(i) + while (i < _hashes.length & j < _size) { + val h = _hashes(i) if (h+h != 0) { j += 1 - f(elems.nn(i).asInstanceOf[A]) + f(elems(i).asInstanceOf[A]) } i += 1 } @@ -446,15 +446,15 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi */ 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.nn, _hashes.nn.length) - val kz = java.util.Arrays.copyOf(_keys.nn, _keys.nn.length) - val vz = new Array[AnyRef | Null](_values.nn.length) + val hz = java.util.Arrays.copyOf(_hashes, _hashes.length) + val kz = java.util.Arrays.copyOf(_keys, _keys.length) + val vz = new Array[AnyRef | Null](_values.length) var i,j = 0 - while (i < _hashes.nn.length & j < _size) { - val h = _hashes.nn(i) + while (i < _hashes.length & j < _size) { + val h = _hashes(i) if (h+h != 0) { j += 1 - vz(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef] + vz(i) = f(_values(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.nn.length & j < _size) { - val h = _hashes.nn(i) + while (i < _hashes.length & j < _size) { + val h = _hashes(i) if (h+h != 0) { j += 1 - _values.nn(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef] + _values(i) = f(_values(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.nn, null) - fill(_values.nn, null) - fill(_hashes.nn, 0) + fill(_keys, null) + fill(_values, null) + fill(_hashes, 0) _size = 0 _vacant = 0 } @@ -628,3 +628,4 @@ object AnyRefMap { implicit def iterableFactory[K <: AnyRef, V]: Factory[(K, V), AnyRefMap[K, V]] = toFactory[K, V](this) implicit def buildFromAnyRefMap[K <: AnyRef, V]: BuildFrom[AnyRefMap[_, _], (K, V), AnyRefMap[K, V]] = toBuildFrom(this) } + diff --git a/library/src/scala/collection/mutable/BitSet.scala b/library/src/scala/collection/mutable/BitSet.scala index 172c483fc3e6..cc622acbe566 100644 --- a/library/src/scala/collection/mutable/BitSet.scala +++ b/library/src/scala/collection/mutable/BitSet.scala @@ -336,14 +336,14 @@ class BitSet(protected[collection] final var elems: Array[Long]) if (newArray eq null) { newArray = new Array(i + 1) } - newArray.nn(i) = w + newArray(i) = w } i -= 1 } if (newArray eq null) { empty } else { - fromBitMaskNoCopy(newArray.nn) + fromBitMaskNoCopy(newArray) } } diff --git a/library/src/scala/collection/mutable/CollisionProofHashMap.scala b/library/src/scala/collection/mutable/CollisionProofHashMap.scala index e186bb4415c1..38f9d8446214 100644 --- a/library/src/scala/collection/mutable/CollisionProofHashMap.scala +++ b/library/src/scala/collection/mutable/CollisionProofHashMap.scala @@ -463,8 +463,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double ///////////////////// RedBlackTree code derived from mutable.RedBlackTree: - @`inline` private[this] def isRed(node: RBNode | Null) = (node ne null) && node.nn.red - @`inline` private[this] def isBlack(node: RBNode | Null) = (node eq null) || !node.nn.red + @`inline` private[this] def isRed(node: RBNode | Null) = (node ne null) && node.red + @`inline` private[this] def isBlack(node: RBNode | Null) = (node eq null) || !node.red @unused @`inline` private[this] def compare(key: K, hash: Int, node: LLNode): Int = { val i = hash - node.hash @@ -491,7 +491,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double table(bucket) = fixAfterInsert(_root, z) return true } - else insertIntoExisting(_root, bucket, key, hash, value, next.nn) + else insertIntoExisting(_root, bucket, key, hash, value, next) } } @@ -499,14 +499,14 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double if(tree eq null) { table(bucket) = CollisionProofHashMap.leaf(key, hash, value, red = false, null) true - } else insertIntoExisting(tree.nn, bucket, key, hash, value, tree.nn) + } else insertIntoExisting(tree, bucket, key, hash, value, tree) } private[this] def fixAfterInsert(_root: RBNode, node: RBNode): RBNode = { var root = _root var z = node while (isRed(z.parent)) { - if (z.parent.nn eq z.parent.nn.parent.nn.left) { + if (z.parent eq z.parent.nn.parent.nn.left) { val y = z.parent.nn.parent.nn.right if (isRed(y)) { z.parent.nn.red = false @@ -651,7 +651,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double } xParent = x.nn.parent } - if (x ne null) x.nn.red = false + if (x ne null) x.red = false root } @@ -667,8 +667,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double y.parent = xp if (xp eq null) root = y - else if (x eq xp.nn.left) xp.nn.left = y - else xp.nn.right = y + else if (x eq xp.left) xp.left = y + else xp.right = y y.left = x x.parent = y @@ -685,8 +685,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double y.parent = xp if (xp eq null) root = y - else if (x eq xp.nn.right) xp.nn.right = y - else xp.nn.left = y + else if (x eq xp.right) xp.right = y + else xp.left = y y.right = x x.parent = y @@ -838,7 +838,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { var x = node var y = x.parent while ((y ne null) && (x eq y.nn.right)) { - x = y.nn + x = y y = y.nn.parent } y @@ -846,7 +846,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { } private final class RBNodesIterator[A, B](tree: RBNode[A, B] | Null)(implicit @unused ord: Ordering[A]) extends AbstractIterator[RBNode[A, B]] { - private[this] var nextNode: RBNode[A, B] | Null = if(tree eq null) null else minNodeNonNull(tree.nn) + private[this] var nextNode: RBNode[A, B] | Null = if(tree eq null) null else minNodeNonNull(tree) def hasNext: Boolean = nextNode ne null @@ -854,8 +854,8 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { def next(): RBNode[A, B] = nextNode match { case null => Iterator.empty.next() case node => - nextNode = successor(node.nn) - node.nn + nextNode = successor(node) + node } } @@ -889,3 +889,4 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { } } } + diff --git a/library/src/scala/collection/mutable/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index 963d58e608e2..789d3ec3616c 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -397,7 +397,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) preHigh.nn.next = null var lastLow: Node[K, V] | Null = preLow var lastHigh: Node[K, V] | Null = preHigh - var n = old + var n: Node[K, V] | Null = old while(n ne null) { val next = n.next if((n.hash & oldlen) == 0) { // keep low @@ -407,7 +407,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) lastHigh.nn.next = n lastHigh = n } - n = next.nn + n = next } lastLow.nn.next = null if(old ne preLow.nn.next) table(i) = preLow.nn.next.nn diff --git a/library/src/scala/collection/mutable/HashTable.scala b/library/src/scala/collection/mutable/HashTable.scala index 508402d7a684..0d6d01837abb 100644 --- a/library/src/scala/collection/mutable/HashTable.scala +++ b/library/src/scala/collection/mutable/HashTable.scala @@ -138,7 +138,7 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends 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 + while (e != null && !elemEquals(e.key, key)) e = e.next e } @@ -187,19 +187,19 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends var e = table(h).asInstanceOf[Entry | Null] if (e != null) { if (elemEquals(e.key, key)) { - table(h) = e.nn.next + table(h) = e.next tableSize = tableSize - 1 nnSizeMapRemove(h) e.next = null return e } else { - var e1 = e.nn.next + var e1 = e.next while (e1 != null && !elemEquals(e1.key, key)) { e = e1 - e1 = e1.nn.next + e1 = e1.next } if (e1 != null) { - e.nn.next = e1.nn.next + e.next = e1.next tableSize = tableSize - 1 nnSizeMapRemove(h) e1.next = null @@ -236,7 +236,7 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends var es = iterTable(idx) while (es != null) { - val next = es.nn.next // Cache next in case f removes es. + val next = es.next // Cache next in case f removes es. f(es.asInstanceOf[Entry]) es = next @@ -264,9 +264,9 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends while (i >= 0) { var e = oldTable(i) while (e != null) { - val h = index(elemHashCode(e.nn.key)) - val e1 = e.nn.next - e.nn.next = table(h).asInstanceOf[Entry | Null] + val h = index(elemHashCode(e.key)) + val e1 = e.next + e.next = table(h).asInstanceOf[Entry | Null] table(h) = e e = e1 nnSizeMapAdd(h) @@ -296,17 +296,17 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends * there. */ protected final def nnSizeMapAdd(h: Int) = if (sizemap ne null) { - sizemap.nn(h >> sizeMapBucketBitSize) += 1 + sizemap(h >> sizeMapBucketBitSize) += 1 } protected final def nnSizeMapRemove(h: Int) = if (sizemap ne null) { - sizemap.nn(h >> sizeMapBucketBitSize) -= 1 + sizemap(h >> sizeMapBucketBitSize) -= 1 } protected final def nnSizeMapReset(tableLength: Int) = if (sizemap ne null) { val nsize = calcSizeMapSize(tableLength) - if (sizemap.nn.length != nsize) sizemap = new Array[Int](nsize) - else java.util.Arrays.fill(sizemap.nn, 0) + if (sizemap.length != nsize) sizemap = new Array[Int](nsize) + else java.util.Arrays.fill(sizemap, 0) } private[collection] final def totalSizeMapBuckets = if (sizeMapBucketSize < table.length) 1 else table.length / sizeMapBucketSize @@ -335,7 +335,7 @@ private[collection] trait HashTable[A, B, Entry <: HashEntry[A, Entry]] extends var e = tbl(tableidx) while (e ne null) { currbucketsize += 1 - e = e.nn.next + e = e.next } tableidx += 1 } diff --git a/library/src/scala/collection/mutable/LinkedHashMap.scala b/library/src/scala/collection/mutable/LinkedHashMap.scala index eae94f5ca468..b3598b2f0609 100644 --- a/library/src/scala/collection/mutable/LinkedHashMap.scala +++ b/library/src/scala/collection/mutable/LinkedHashMap.scala @@ -321,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.nn.key, cur.nn.value)) - cur = cur.nn.later + f((cur.key, cur.value)) + cur = cur.later } } override def foreachEntry[U](f: (K, V) => U): Unit = { var cur = firstEntry while (cur ne null) { - f(cur.nn.key, cur.nn.value) - cur = cur.nn.later + f(cur.key, cur.value) + cur = cur.later } } @@ -400,7 +400,7 @@ class LinkedHashMap[K, V] nnode.next = old table(idx) = nnode } else { - nnode.next = prev.nn.next + nnode.next = prev.next prev.nn.next = nnode } } diff --git a/library/src/scala/collection/mutable/LinkedHashSet.scala b/library/src/scala/collection/mutable/LinkedHashSet.scala index ea4040b0d93e..51c8ff3c68ba 100644 --- a/library/src/scala/collection/mutable/LinkedHashSet.scala +++ b/library/src/scala/collection/mutable/LinkedHashSet.scala @@ -232,7 +232,7 @@ class LinkedHashSet[A] var next: Entry | Null = nd.next while ((next ne null) && next.hash <= hash) { if (next.hash == hash && next.key == elem) { - prev.next = next.next.nn + prev.next = next.next deleteEntry(next) contentSize -= 1 return true @@ -340,7 +340,7 @@ object LinkedHashSet extends IterableFactory[LinkedHashSet] { 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.nn.findEntry(k, h) + else next.findEntry(k, h) } /** The default load factor for the hash table */ @@ -349,4 +349,3 @@ object LinkedHashSet extends IterableFactory[LinkedHashSet] { /** The default initial capacity for the hash table */ private[collection] final def defaultinitialSize: Int = 16 } - diff --git a/library/src/scala/collection/mutable/ListBuffer.scala b/library/src/scala/collection/mutable/ListBuffer.scala index 88150b490b38..a6bd7ba9fef4 100644 --- a/library/src/scala/collection/mutable/ListBuffer.scala +++ b/library/src/scala/collection/mutable/ListBuffer.scala @@ -233,7 +233,7 @@ class ListBuffer[A] else { val p = predecessor(idx) val nx = elem :: getNext(p) - if(p eq null) first = nx else p.nn.next = nx + if(p eq null) first = nx else p.next = nx len += 1 } } @@ -247,7 +247,7 @@ class ListBuffer[A] private def insertAfter(prev: Predecessor, fresh: ListBuffer[A]): Unit = { if (!fresh.isEmpty) { val follow = getNext(prev) - if (prev eq null) first = fresh.first else prev.nn.next = fresh.first + if (prev eq null) first = fresh.first else prev.next = fresh.first fresh.last0.nn.next = follow if (follow.isEmpty) last0 = fresh.last0 len += fresh.length @@ -277,7 +277,7 @@ class ListBuffer[A] if(first.isEmpty) last0 = null } else { if(last0.nn eq nx) last0 = p - p.nn.next = nx.tail + p.next = nx.tail } len -= 1 nx.head @@ -296,7 +296,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.nn.next = nx + if(prev eq null) first = nx else prev.next = nx if(nx.isEmpty) last0 = prev len -= n } @@ -337,7 +337,7 @@ class ListBuffer[A] } src = src.tail } - first = if(dst eq null) Nil else dst.nn + first = if(dst eq null) Nil else dst aliased = false // we just rebuilt a fresh, unaliased instance this } @@ -355,7 +355,7 @@ class ListBuffer[A] val follow = cur.tail if (!p(cur.head)) { if(prev eq null) first = follow - else prev.nn.next = follow + else prev.next = follow len -= 1 } else { prev = cur.asInstanceOf[Predecessor] diff --git a/library/src/scala/collection/mutable/LongMap.scala b/library/src/scala/collection/mutable/LongMap.scala index c19e240be1d7..3b3f7983e9e5 100644 --- a/library/src/scala/collection/mutable/LongMap.scala +++ b/library/src/scala/collection/mutable/LongMap.scala @@ -76,8 +76,8 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff @annotation.stableNull private[this] var minValue: AnyRef | Null = null private[this] var _size = 0 private[this] var _vacant = 0 - @annotation.stableNull private[this] var _keys: Array[Long] | Null = null - @annotation.stableNull private[this] var _values: Array[AnyRef | Null] | Null = null + private[this] var _keys: Array[Long] = _ + private[this] var _values: Array[AnyRef | Null] = _ if (initBlank) defaultInitialize(initialBufferSize) @@ -90,7 +90,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } private[collection] def initializeTo( - m: Int, ek: Int, zv: AnyRef | Null, mv: AnyRef | Null, sz: Int, vc: Int, kz: Array[Long] | Null, vz: Array[AnyRef | Null] | Null + m: Int, ek: Int, zv: AnyRef | Null, mv: AnyRef | Null, sz: Int, vc: Int, kz: Array[Long], vz: Array[AnyRef | 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.nn(e) != 0) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } + while (_keys(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.nn(e); if (q==k) return e; q != 0}) { x += 1; e = (e + 2*(x+1)*x - 3) & mask } + while ({ q = _keys(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.nn(e); if (q==k) return e; q+q != 0}) { + while ({ q = _keys(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.nn(e); if (q==k) return e; q != 0}) { + while ({ q = _keys(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.nn(i).asInstanceOf[V]) + if (i < 0) None else Some(_values(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.nn(i).asInstanceOf[V1] + if (i < 0) default else _values(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.nn + val oks = _keys 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.nn) || ok != _keys.nn(j)) { + if (oks.ne(_keys) || ok != _keys(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.nn(j) = key - _values.nn(j) = value.asInstanceOf[AnyRef] + _keys(j) = key + _values(j) = value.asInstanceOf[AnyRef] if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() value } - else _values.nn(i).asInstanceOf[V] + else _values(i).asInstanceOf[V] } } @@ -230,7 +230,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } else { val i = seekEntry(key) - if (i < 0) null else _values.nn(i).asInstanceOf[V] + if (i < 0) null else _values(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.nn(i).asInstanceOf[V] + if (i < 0) defaultEntry(key) else _values(i).asInstanceOf[V] } } @@ -256,8 +256,8 @@ 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.nn - val ov = _values.nn + val ok = _keys + val ov = _values mask = newMask _keys = new Array[Long](mask+1) _values = new Array[AnyRef | Null](mask+1) @@ -267,8 +267,8 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff val k = ok(i) if (k != -k) { val j = seekEmpty(k) - _keys.nn(j) = k - _values.nn(j) = ov(i) + _keys(j) = k + _values(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.nn(j) = key - _values.nn(j) = value.asInstanceOf[AnyRef] + _keys(j) = key + _values(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() None } else { - val ans = Some(_values.nn(i).asInstanceOf[V]) - _keys.nn(i) = key - _values.nn(i) = value.asInstanceOf[AnyRef] + val ans = Some(_values(i).asInstanceOf[V]) + _keys(i) = key + _values(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.nn(j) = key - _values.nn(j) = value.asInstanceOf[AnyRef] + _keys(j) = key + _values(j) = value.asInstanceOf[AnyRef] _size += 1 if ((i & VacantBit) != 0) _vacant -= 1 else if (imbalanced) repack() } else { - _keys.nn(i) = key - _values.nn(i) = value.asInstanceOf[AnyRef] + _keys(i) = key + _values(i) = value.asInstanceOf[AnyRef] } } } @@ -376,16 +376,16 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff if (i >= 0) { _size -= 1 _vacant += 1 - _keys.nn(i) = Long.MinValue - _values.nn(i) = null + _keys(i) = Long.MinValue + _values(i) = null } } this } def iterator: Iterator[(Long, V)] = new AbstractIterator[(Long, V)] { - private[this] val kz = _keys.nn - private[this] val vz = _values.nn + private[this] val kz = _keys + private[this] val vz = _values private[this] var nextPair: (Long, V) | Null = if (extraKeys==0) null @@ -398,11 +398,11 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff private[this] var index = 0 - def hasNext: Boolean = nextPair != null || (index < kz.nn.length && { + def hasNext: Boolean = nextPair != null || (index < kz.length && { var q = kz(index) while (q == -q) { index += 1 - if (index >= kz.nn.length) return false + if (index >= kz.length) return false q = kz(index) } nextPair = (kz(index), vz(index).asInstanceOf[V]) @@ -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.nn.length & j < _size) { - val k = _keys.nn(i) + while (i < _keys.length & j < _size) { + val k = _keys(i) if (k != -k) { j += 1 - f((k, _values.nn(i).asInstanceOf[V])) + f((k, _values(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.nn.length & j < _size) { - val k = _keys.nn(i) + while (i < _keys.length & j < _size) { + val k = _keys(i) if (k != -k) { j += 1 - f(k, _values.nn(i).asInstanceOf[V]) + f(k, _values(i).asInstanceOf[V]) } i += 1 } } override def clone(): LongMap[V] = { - val kz = java.util.Arrays.copyOf(_keys.nn, _keys.nn.length) - val vz = java.util.Arrays.copyOf(_values.nn, _values.nn.length) + val kz = java.util.Arrays.copyOf(_keys, _keys.length) + val vz = java.util.Arrays.copyOf(_values, _values.length) val lm = new LongMap[V](defaultEntry, 1, initBlank = false) lm.initializeTo(mask, extraKeys, zeroValue, minValue, _size, _vacant, kz, vz) lm @@ -491,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.nn.length & j < _size) { - val k = _keys.nn(i) + while (i < _keys.length & j < _size) { + val k = _keys(i) if (k != -k) { j += 1 f(k) @@ -506,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.nn.length & j < _size) { - val k = _keys.nn(i) + while (i < _keys.length & j < _size) { + val k = _keys(i) if (k != -k) { j += 1 - f(_values.nn(i).asInstanceOf[V]) + f(_values(i).asInstanceOf[V]) } i += 1 } @@ -524,14 +524,14 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff 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.nn.length) - val vz = new Array[AnyRef | Null](_values.nn.length) + val kz = java.util.Arrays.copyOf(_keys, _keys.length) + val vz = new Array[AnyRef | Null](_values.length) var i,j = 0 - while (i < _keys.nn.length & j < _size) { - val k = _keys.nn(i) + while (i < _keys.length & j < _size) { + val k = _keys(i) if (k != -k) { j += 1 - vz(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef | Null] + vz(i) = f(_values(i).asInstanceOf[V]).asInstanceOf[AnyRef | Null] } i += 1 } @@ -552,11 +552,11 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff 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.nn.length & j < _size) { - val k = _keys.nn(i) + while (i < _keys.length & j < _size) { + val k = _keys(i) if (k != -k) { j += 1 - _values.nn(i) = f(_values.nn(i).asInstanceOf[V]).asInstanceOf[AnyRef | Null] + _values(i) = f(_values(i).asInstanceOf[V]).asInstanceOf[AnyRef | Null] } i += 1 } diff --git a/library/src/scala/collection/mutable/UnrolledBuffer.scala b/library/src/scala/collection/mutable/UnrolledBuffer.scala index 5c10264ded18..67b20fd4b6a0 100644 --- a/library/src/scala/collection/mutable/UnrolledBuffer.scala +++ b/library/src/scala/collection/mutable/UnrolledBuffer.scala @@ -269,7 +269,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] private[collection] def this() = this(0, new Array[T](unrolledlength), null, null) 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.nn.calcNextLength(array.length) + private def nextlength = if (buff eq null) unrolledlength else buff.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) { @@ -284,23 +284,23 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] var unrolled: Unrolled[T] | Null = this var i = 0 while (unrolled ne null) { - val chunkarr = unrolled.nn.array - val chunksz = unrolled.nn.size + val chunkarr = unrolled.array + val chunksz = unrolled.size while (i < chunksz) { val elem = chunkarr(i) f(elem) i += 1 } i = 0 - unrolled = unrolled.nn.next + unrolled = unrolled.next } } def mapInPlace(f: T => T): Unit = { var unrolled: Unrolled[T] | Null = this var i = 0 while (unrolled ne null) { - val chunkarr = unrolled.nn.array - val chunksz = unrolled.nn.size + val chunkarr = unrolled.array + val chunksz = unrolled.size while (i < chunksz) { val elem = chunkarr(i) chunkarr(i) = f(elem) @@ -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.nn) + val newhead = new Unrolled[T](buff) newhead append elem newhead.next = this newhead @@ -438,7 +438,7 @@ object UnrolledBuffer extends StrictOptimizedClassTagSeqFactory[UnrolledBuffer] } override def toString: String = - array.take(size).nn.mkString("Unrolled@%08x".format(System.identityHashCode(this)) + "[" + size + "/" + array.length + "](", ", ", ")") + " -> " + (if (next ne null) next.toString else "") + array.take(size).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 198bd381744a..e76c807c8a96 100644 --- a/library/src/scala/concurrent/BatchingExecutor.scala +++ b/library/src/scala/concurrent/BatchingExecutor.scala @@ -159,7 +159,7 @@ private[concurrent] trait BatchingExecutor extends Executor { val f = resubmit(BlockContext.usingBlockContext(this)(this)) if (f != null) - throw f.nn + throw f } /* LOGIC FOR ASYNCHRONOUS BATCHES */ diff --git a/library/src/scala/concurrent/impl/Promise.scala b/library/src/scala/concurrent/impl/Promise.scala index ce254542ec60..5d302a34a55c 100644 --- a/library/src/scala/concurrent/impl/Promise.scala +++ b/library/src/scala/concurrent/impl/Promise.scala @@ -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.nn) + else concatCallbacks(m.rest, result) } - else removeCallback(m.rest, t, if (result == null) m.first else new ManyCallbacks(m.first, result.nn)) + else removeCallback(m.rest, t, if (result == null) m.first else new ManyCallbacks(m.first, result)) } else cs // IMPORTANT: Noop should not be passed in here, `callbacks` cannot be null @@ -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.nn.promise(this) - if ((this ne p) && compareAndSet(state, l.nn)) { + val p = l.promise(this) + if ((this ne p) && compareAndSet(state, l)) { 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]]) */ diff --git a/library/src/scala/io/Codec.scala b/library/src/scala/io/Codec.scala index 0f0e6a2de086..63fd2735589e 100644 --- a/library/src/scala/io/Codec.scala +++ b/library/src/scala/io/Codec.scala @@ -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.nn - if (_onUnmappableCharacter ne null) enc onUnmappableCharacter _onUnmappableCharacter.nn - if (_encodingReplacement ne null) enc replaceWith _encodingReplacement.nn + if (_onMalformedInput ne null) enc onMalformedInput _onMalformedInput + if (_onUnmappableCharacter ne null) enc onUnmappableCharacter _onUnmappableCharacter + if (_encodingReplacement ne null) enc replaceWith _encodingReplacement enc } def decoder: CharsetDecoder = { val dec = charSet.newDecoder() - if (_onMalformedInput ne null) dec onMalformedInput _onMalformedInput.nn - if (_onUnmappableCharacter ne null) dec onUnmappableCharacter _onUnmappableCharacter.nn - if (_decodingReplacement ne null) dec replaceWith _decodingReplacement.nn + if (_onMalformedInput ne null) dec onMalformedInput _onMalformedInput + if (_onUnmappableCharacter ne null) dec onUnmappableCharacter _onUnmappableCharacter + if (_decodingReplacement ne null) dec replaceWith _decodingReplacement dec } diff --git a/library/src/scala/io/Source.scala b/library/src/scala/io/Source.scala index 4dd485982c97..f22ab13c5440 100644 --- a/library/src/scala/io/Source.scala +++ b/library/src/scala/io/Source.scala @@ -162,7 +162,7 @@ object Source { 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.nn + val resetFn = if (reset == null) () => createBufferedSource(inputStream, bufferSize, reset, close)(codec) else reset new BufferedSource(inputStream, bufferSize)(codec) withReset resetFn withClose close } diff --git a/library/src/scala/math/BigInt.scala b/library/src/scala/math/BigInt.scala index ba19357dd613..498cbad8d864 100644 --- a/library/src/scala/math/BigInt.scala +++ b/library/src/scala/math/BigInt.scala @@ -299,7 +299,7 @@ final class BigInt private ( if (this.longEncoding) { if (that.longEncoding) java.lang.Long.compare(this._long, that._long) else -that._bigInteger.nn.signum() } else { - if (that.longEncoding) _bigInteger.nn.signum() else this._bigInteger.nn.compareTo(that._bigInteger.nn) + if (that.longEncoding) _bigInteger.nn.signum() else this._bigInteger.nn.compareTo(that._bigInteger) } /** Addition of BigInts diff --git a/library/src/scala/ref/WeakReference.scala b/library/src/scala/ref/WeakReference.scala index d18fa311e0ca..b28a1ab8d3f2 100644 --- a/library/src/scala/ref/WeakReference.scala +++ b/library/src/scala/ref/WeakReference.scala @@ -36,4 +36,4 @@ object WeakReference { } 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] + extends java.lang.ref.WeakReference[T](value, if (queue == null) null else queue.underlying.asInstanceOf[java.lang.ref.ReferenceQueue[T]]) with ReferenceWithWrapper[T] diff --git a/library/src/scala/reflect/NameTransformer.scala b/library/src/scala/reflect/NameTransformer.scala index 01bb89b78870..a78afcb13b6b 100644 --- a/library/src/scala/reflect/NameTransformer.scala +++ b/library/src/scala/reflect/NameTransformer.scala @@ -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.nn.code, i)) ops = ops.nn.next + while ((ops ne null) && !name.startsWith(ops.code, i)) ops = ops.next if (ops ne null) { if (buf eq null) { buf = new StringBuilder() buf.append(name.substring(0, i)) } - buf.append(ops.nn.op) - i += ops.nn.code.length() + buf.append(ops.op) + i += ops.code.length() } /* Handle the decoding of Unicode glyphs that are * not valid Java/JVM identifiers */ diff --git a/library/src/scala/sys/process/ProcessImpl.scala b/library/src/scala/sys/process/ProcessImpl.scala index a87f4bf3fb27..c120b6607a69 100644 --- a/library/src/scala/sys/process/ProcessImpl.scala +++ b/library/src/scala/sys/process/ProcessImpl.scala @@ -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.nn.interrupt() + private[this] def interrupt(): Unit = if (inputThread != null) inputThread.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/Sorting.scala b/library/src/scala/util/Sorting.scala index 19c8ae111f09..2f44d73ca1cb 100644 --- a/library/src/scala/util/Sorting.scala +++ b/library/src/scala/util/Sorting.scala @@ -182,7 +182,7 @@ object Sorting { 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.nn + val sc = if (scratch eq null) new Array[T](iK - i0) else scratch mergeSort(a, i0, iK, ord, sc) mergeSort(a, iK, iN, ord, sc) mergeSorted(a, i0, iK, iN, ord, sc) diff --git a/library/src/scala/util/Using.scala b/library/src/scala/util/Using.scala index 1e02ed615600..fae9dcb2d865 100644 --- a/library/src/scala/util/Using.scala +++ b/library/src/scala/util/Using.scala @@ -217,7 +217,7 @@ object Using { catch { case t: Throwable => if (toThrow == null) toThrow = t - else toThrow = preferentiallySuppress(toThrow.nn, t) + else toThrow = preferentiallySuppress(toThrow, t) } } if (toThrow != null) throw toThrow From d686933ab2ab4ab47372d02f33f63d7baf0ff4d0 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 16:27:20 +0200 Subject: [PATCH 11/46] Removing remaining unnecessary .nn --- .../collection/immutable/RedBlackTree.scala | 14 +- .../scala/collection/immutable/TreeMap.scala | 18 +-- .../mutable/CollisionProofHashMap.scala | 16 +- .../scala/collection/mutable/HashMap.scala | 16 +- .../scala/collection/mutable/HashSet.scala | 16 +- .../collection/mutable/LinkedHashMap.scala | 2 +- .../collection/mutable/LinkedHashSet.scala | 6 +- .../scala/collection/mutable/ListBuffer.scala | 6 +- .../collection/mutable/RedBlackTree.scala | 146 +++++++++--------- 9 files changed, 120 insertions(+), 120 deletions(-) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index a853ddd1b780..4d547f071f49 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -226,7 +226,7 @@ private[collection] object RedBlackTree { else { val tl = tree.left if (tl eq null) tree.right - else if (tl.nn.isBlack) balLeft(tree, _tail(tl), tree.right) + else if (tl.isBlack) balLeft(tree, _tail(tl), tree.right) else tree.redWithLeft(_tail(tree.left)) } blacken(_tail(tree)) @@ -238,7 +238,7 @@ private[collection] object RedBlackTree { else { val tr = tree.right if (tr eq null) tree.left - else if (tr.nn.isBlack) balRight(tree, tree.left, _init(tr)) + else if (tr.isBlack) balRight(tree, tree.left, _init(tr)) else tree.redWithRight(_init(tr)) } blacken(_init(tree)) @@ -408,7 +408,7 @@ private[collection] object RedBlackTree { val resultLeft = tree.blackWithRight(newRight_left) val resultRight = newRight_right.nn.black - newRight.nn.withLeftRight(resultLeft, resultRight) + newRight.withLeftRight(resultLeft, resultRight) } else { // tree // L KV newRight @@ -976,10 +976,10 @@ private[collection] object RedBlackTree { def transform[A, B, C](t: Tree[A, B] | Null, f: (A, B) => C): Tree[A, C] | Null = if(t eq null) null else { - val k = t.nn.key - val v = t.nn.value - val l = t.nn.left - val r = t.nn.right + val k = t.key + val v = t.value + val l = t.left + val r = t.right val l2 = transform(l, f) val v2 = f(k, v) val r2 = transform(r, f) diff --git a/library/src/scala/collection/immutable/TreeMap.scala b/library/src/scala/collection/immutable/TreeMap.scala index ef9298437b21..70038e6449e2 100644 --- a/library/src/scala/collection/immutable/TreeMap.scala +++ b/library/src/scala/collection/immutable/TreeMap.scala @@ -100,7 +100,7 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( scala.collection.convert.impl.AnyBinaryTreeStepper.from[(K, V), RB.Tree[K, V]]( - size, tree.nn, _.left.nn, _.right.nn, x => (x.key, x.value) + size, tree, _.left.nn, _.right.nn, x => (x.key, x.value) ) ) @@ -108,10 +108,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.nn, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree.nn, _.left.nn, _.right.nn, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree, _.left.nn, _.right.nn, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -120,10 +120,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree.nn, _.left.nn, _.right.nn, _.value.asInstanceOf[V])) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[V])) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/collection/mutable/CollisionProofHashMap.scala b/library/src/scala/collection/mutable/CollisionProofHashMap.scala index 38f9d8446214..28d20860b9e1 100644 --- a/library/src/scala/collection/mutable/CollisionProofHashMap.scala +++ b/library/src/scala/collection/mutable/CollisionProofHashMap.scala @@ -572,7 +572,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double yIsRed = y.red x = y.right - if (y.parent.nn eq z) xParent = y + if (y.parent eq z) xParent = y else { xParent = y.parent root = transplant(root, y, y.right.nn) @@ -729,8 +729,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double case nn: RBNode @uc => (nn.key, nn.hash, nn.value) } val n = new RBNode(key, hash, value, red = false, left, right, null) - if(left ne null) left.nn.parent = n - if(right ne null) right.nn.parent = n + if(left ne null) left.parent = n + if(right ne null) right.parent = n n } f(1, size) @@ -839,7 +839,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { var y = x.parent while ((y ne null) && (x eq y.nn.right)) { x = y - y = y.nn.parent + y = y.parent } y } @@ -870,22 +870,22 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): LLNode[K, V] | Null = { if(h == hash && eq(k, key) /*ord.compare(k, key) == 0*/) this else if((next eq null) || (hash > h)) null - else next.nn.getNode(k, h) + else next.getNode(k, h) } @tailrec def foreach[U](f: ((K, V)) => U): Unit = { f((key, value)) - if(next ne null) next.nn.foreach(f) + if(next ne null) next.foreach(f) } @tailrec def foreachEntry[U](f: (K, V) => U): Unit = { f(key, value) - if(next ne null) next.nn.foreachEntry(f) + if(next ne null) next.foreachEntry(f) } @tailrec def foreachNode[U](f: LLNode[K, V] => U): Unit = { f(this) - if(next ne null) next.nn.foreachNode(f) + if(next ne null) next.foreachNode(f) } } } diff --git a/library/src/scala/collection/mutable/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index 789d3ec3616c..8074b6b77915 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -255,7 +255,7 @@ 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.nn.next = new Node(key, hash, value, prev.nn.next) + else prev.next = new Node(key, hash, value, prev.next) } contentSize += 1 null @@ -410,9 +410,9 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) n = next } lastLow.nn.next = null - if(old ne preLow.nn.next) table(i) = preLow.nn.next.nn + if(old ne preLow.nn.next) table(i) = preLow.nn.next if(preHigh.nn.next ne null) { - table(i + oldlen) = preHigh.nn.next.nn + table(i + oldlen) = preHigh.nn.next lastHigh.nn.next = null } } @@ -504,7 +504,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) var i = 0 while(i < len) { val n = table(i) - if(n ne null) n.nn.foreach(f) + if(n ne null) n.foreach(f) i += 1 } } @@ -514,7 +514,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) var i = 0 while(i < len) { val n = table(i) - if(n ne null) n.nn.foreachEntry(f) + if(n ne null) n.foreachEntry(f) i += 1 } } @@ -529,7 +529,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.nn + head = head.next contentSize -= 1 } @@ -544,7 +544,7 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) prev.next = next.next contentSize -= 1 } - next = next.next.nn + next = next.next } } @@ -563,7 +563,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.nn + n = n.next } i += 1 } diff --git a/library/src/scala/collection/mutable/HashSet.scala b/library/src/scala/collection/mutable/HashSet.scala index 2ba4c9909689..57a1d9c1fc3b 100644 --- a/library/src/scala/collection/mutable/HashSet.scala +++ b/library/src/scala/collection/mutable/HashSet.scala @@ -164,12 +164,12 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) while((n ne null) && n.hash <= hash) { if(n.hash == hash && elem == n.key) return false prev = n - n = n.nn.next + n = n.next } if(prev eq null) table(idx) = new Node(elem, hash, old) else - prev.nn.next = new Node(elem, hash, prev.nn.next) + prev.next = new Node(elem, hash, prev.next) } contentSize += 1 true @@ -195,7 +195,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) return true } prev = next - next = next.nn.next + next = next.next } false } @@ -283,9 +283,9 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) n = next } lastLow.next = null - if(old ne preLow.next) table(i) = preLow.nn.next + if(old ne preLow.next) table(i) = preLow.next if(preHigh.next ne null) { - table(i + oldlen) = preHigh.nn.next + table(i + oldlen) = preHigh.next lastHigh.next = null } } @@ -304,7 +304,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) var head = table(bucket) while ((head ne null) && !p(head.key)) { - head = head.nn.next + head = head.next contentSize -= 1 } @@ -319,7 +319,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) prev.next = next.next contentSize -= 1 } - next = next.nn.next + next = next.next } } @@ -376,7 +376,7 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double) var i = 0 while(i < len) { val n = table(i) - if(n ne null) n.nn.foreach(f) + if(n ne null) n.foreach(f) i += 1 } } diff --git a/library/src/scala/collection/mutable/LinkedHashMap.scala b/library/src/scala/collection/mutable/LinkedHashMap.scala index b3598b2f0609..8fd1f38fca5c 100644 --- a/library/src/scala/collection/mutable/LinkedHashMap.scala +++ b/library/src/scala/collection/mutable/LinkedHashMap.scala @@ -401,7 +401,7 @@ class LinkedHashMap[K, V] table(idx) = nnode } else { nnode.next = prev.next - prev.nn.next = nnode + prev.next = nnode } } contentSize += 1 diff --git a/library/src/scala/collection/mutable/LinkedHashSet.scala b/library/src/scala/collection/mutable/LinkedHashSet.scala index 51c8ff3c68ba..eb5c8713eb8e 100644 --- a/library/src/scala/collection/mutable/LinkedHashSet.scala +++ b/library/src/scala/collection/mutable/LinkedHashSet.scala @@ -129,8 +129,8 @@ class LinkedHashSet[A] override def foreach[U](f: A => U): Unit = { var cur: Entry | Null = firstEntry while (cur ne null) { - f(cur.nn.key) - cur = cur.nn.later + f(cur.key) + cur = cur.later } } @@ -280,7 +280,7 @@ class LinkedHashSet[A] lastLow.next = null if (old ne preLow.next) table(i) = preLow.next.nn if (preHigh.next ne null) { - table(i + oldlen) = preHigh.next.nn + table(i + oldlen) = preHigh.next lastHigh.next = null } } diff --git a/library/src/scala/collection/mutable/ListBuffer.scala b/library/src/scala/collection/mutable/ListBuffer.scala index a6bd7ba9fef4..c026ed254653 100644 --- a/library/src/scala/collection/mutable/ListBuffer.scala +++ b/library/src/scala/collection/mutable/ListBuffer.scala @@ -211,7 +211,7 @@ class ListBuffer[A] if (idx < 0 || idx >= len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) if (idx == 0) { val newElem = new :: (elem, first.tail) - if (last0.nn eq first) { + if (last0 eq first) { last0 = newElem } first = newElem @@ -219,7 +219,7 @@ class ListBuffer[A] // `p` can not be `null` because the case where `idx == 0` is handled above val p = predecessor(idx) val newElem = new :: (elem, p.tail.tail) - if (last0.nn eq p.tail) { + if (last0 eq p.tail) { last0 = newElem } p.asInstanceOf[::[A]].next = newElem @@ -276,7 +276,7 @@ class ListBuffer[A] first = nx.tail if(first.isEmpty) last0 = null } else { - if(last0.nn eq nx) last0 = p + if(last0 eq nx) last0 = p p.next = nx.tail } len -= 1 diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index de4d5d83c3bc..eca8d4436c52 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -106,10 +106,10 @@ private[collection] object RedBlackTree { } private def minNode[A, B](node: Node[A, B] | Null): Node[A, B] | Null = - if (node eq null) null else minNodeNonNull(node.nn) + if (node eq null) null else minNodeNonNull(node) @tailrec def minNodeNonNull[A, B](node: Node[A, B]): Node[A, B] = - if (node.left eq null) node else minNodeNonNull(node.left.nn) + if (node.left eq null) node else minNodeNonNull(node.left) def max[A, B](tree: Tree[A, B]): Option[(A, B)] = maxNode(tree.root) match { case null => None @@ -122,10 +122,10 @@ private[collection] object RedBlackTree { } private def maxNode[A, B](node: Node[A, B] | Null): Node[A, B] | Null = - if (node eq null) null else maxNodeNonNull(node.nn) + if (node eq null) null else maxNodeNonNull(node) @tailrec def maxNodeNonNull[A, B](node: Node[A, B]): Node[A, B] = - if (node.right eq null) node else maxNodeNonNull(node.right.nn) + if (node.right eq null) node else maxNodeNonNull(node.right) /** * Returns the first (lowest) map entry with a key equal or greater than `key`. Returns `None` if there is no such @@ -151,8 +151,8 @@ private[collection] object RedBlackTree { var cmp = 1 while ((x ne null) && cmp != 0) { y = x - cmp = ord.compare(key, x.nn.key) - x = if (cmp < 0) x.nn.left else x.nn.right + cmp = ord.compare(key, x.key) + x = if (cmp < 0) x.left else x.right } if (cmp <= 0) y else successor(y) } @@ -181,8 +181,8 @@ private[collection] object RedBlackTree { var cmp = 1 while ((x ne null) && cmp != 0) { y = x - cmp = ord.compare(key, x.nn.key) - x = if (cmp < 0) x.nn.left else x.nn.right + cmp = ord.compare(key, x.key) + x = if (cmp < 0) x.left else x.right } if (cmp > 0) y else predecessor(y) } @@ -196,8 +196,8 @@ private[collection] object RedBlackTree { var cmp = 1 while ((x ne null) && cmp != 0) { y = x - cmp = ord.compare(key, x.nn.key) - x = if (cmp < 0) x.nn.left else x.nn.right + cmp = ord.compare(key, x.key) + x = if (cmp < 0) x.left else x.right } if (cmp == 0) y.nn.value = value @@ -205,8 +205,8 @@ private[collection] object RedBlackTree { val z = Node.leaf(key, value, red = true, y.nn) if (y eq null) tree.root = z - else if (cmp < 0) y.nn.left = z - else y.nn.right = z + else if (cmp < 0) y.left = z + else y.right = z fixAfterInsert(tree, z) tree.size += 1 @@ -216,7 +216,7 @@ private[collection] object RedBlackTree { private[this] def fixAfterInsert[A, B](tree: Tree[A, B], node: Node[A, B]): Unit = { var z = node while (isRed(z.parent)) { - if (z.parent.nn eq z.parent.nn.parent.nn.left) { + if (z.parent eq z.parent.nn.parent.nn.left) { val y = z.parent.nn.parent.nn.right if (isRed(y)) { z.parent.nn.red = false @@ -259,36 +259,36 @@ private[collection] object RedBlackTree { val z = getNode(tree.root, key) if (z ne null) { var y = z - var yIsRed = y.nn.red + var yIsRed = y.red var x: Node[A, B] | Null = null var xParent: Node[A, B] | Null = null - if (z.nn.left eq null) { - x = z.nn.right - transplant(tree, z.nn, z.nn.right) - xParent = z.nn.parent + if (z.left eq null) { + x = z.right + transplant(tree, z, z.right) + xParent = z.parent } - else if (z.nn.right eq null) { - x = z.nn.left - transplant(tree, z.nn, z.nn.left) - xParent = z.nn.parent + else if (z.right eq null) { + x = z.left + transplant(tree, z, z.left) + xParent = z.left.parent } else { - y = minNodeNonNull(z.nn.right.nn) + y = minNodeNonNull(z.right) yIsRed = y.red x = y.right - if (y.parent eq z.nn) xParent = y + if (y.parent eq z) xParent = y else { xParent = y.parent transplant(tree, y, y.right) - y.right = z.nn.right + y.right = z.right y.right.nn.parent = y } - transplant(tree, z.nn, y) - y.left = z.nn.left + transplant(tree, z, y) + y.left = z.left y.left.nn.parent = y - y.red = z.nn.red + y.red = z.red } if (!yIsRed) fixAfterDelete(tree, x, xParent) @@ -355,7 +355,7 @@ private[collection] object RedBlackTree { } xParent = x.nn.parent } - if (x ne null) x.nn.red = false + if (x ne null) x.red = false } // ---- helpers ---- @@ -366,13 +366,13 @@ private[collection] object RedBlackTree { */ private[this] def successor[A, B](node: Node[A, B] | Null): Node[A, B] | Null = { if (node eq null) null - else if (node.nn.right ne null) minNodeNonNull(node.nn.right.nn) + else if (node.right ne null) minNodeNonNull(node.right) else { var x = node - var y = x.nn.parent + var y = x.parent while ((y ne null) && (x eq y.nn.right)) { x = y - y = y.nn.parent + y = y.parent } y } @@ -384,13 +384,13 @@ private[collection] object RedBlackTree { */ private[this] def predecessor[A, B](node: Node[A, B] | Null): Node[A, B] | Null = { if (node eq null) null - else if (node.nn.left ne null) maxNodeNonNull(node.nn.left.nn) + else if (node.left ne null) maxNodeNonNull(node.left) else { var x = node - var y = x.nn.parent - while ((y ne null) && (x eq y.nn.left)) { + var y = x.parent + while ((y ne null) && (x eq y.left)) { x = y - y = y.nn.parent + y = y.parent } y } @@ -401,12 +401,12 @@ private[collection] object RedBlackTree { val y = x.right x.right = y.nn.left - if (y.nn.left ne null) y.nn.left.nn.parent = x + if (y.nn.left ne null) y.nn.left.parent = x y.nn.parent = x.parent if (x.parent eq null) tree.root = y - else if (x eq x.parent.nn.left) x.parent.nn.left = y - else x.parent.nn.right = y + else if (x eq x.parent.nn.left) x.parent.left = y + else x.parent.right = y y.nn.left = x x.parent = y @@ -417,12 +417,12 @@ private[collection] object RedBlackTree { val y = x.left x.left = y.nn.right - if (y.nn.right ne null) y.nn.right.nn.parent = x + if (y.nn.right ne null) y.nn.right.parent = x y.nn.parent = x.parent if (x.parent eq null) tree.root = y - else if (x eq x.parent.nn.right) x.parent.nn.right = y - else x.parent.nn.left = y + else if (x eq x.parent.right) x.parent.right = y + else x.parent.left = y y.nn.right = x x.parent = y @@ -434,10 +434,10 @@ private[collection] object RedBlackTree { */ private[this] def transplant[A, B](tree: Tree[A, B], to: Node[A, B], from: Node[A, B] | Null): Unit = { if (to.parent eq null) tree.root = from - else if (to eq to.parent.nn.left) to.parent.nn.left = from - else to.parent.nn.right = from + else if (to eq to.parent.nn.left) to.parent.left = from + else to.parent.right = from - if (from ne null) from.nn.parent = to.parent + if (from ne null) from.parent = to.parent } // ---- tree traversal ---- @@ -445,47 +445,47 @@ private[collection] object RedBlackTree { def foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = foreachNode(tree.root, f) private[this] def foreachNode[A, B, U](node: Node[A, B] | Null, f: ((A, B)) => U): Unit = - if (node ne null) foreachNodeNonNull(node.nn, f) + if (node ne null) foreachNodeNonNull(node, f) private[this] def foreachNodeNonNull[A, B, U](node: Node[A, B], f: ((A, B)) => U): Unit = { - if (node.left ne null) foreachNodeNonNull(node.left.nn, f) + if (node.left ne null) foreachNodeNonNull(node.left, f) f((node.key, node.value)) - if (node.right ne null) foreachNodeNonNull(node.right.nn, f) + if (node.right ne null) foreachNodeNonNull(node.right, f) } def foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = { def g(node: Node[A, _]): Unit = { val l = node.left - if(l ne null) g(l.nn) + if(l ne null) g(l) f(node.key) val r = node.right - if(r ne null) g(r.nn) + if(r ne null) g(r) } val r = tree.root - if(r ne null) g(r.nn) + if(r ne null) g(r) } def foreachEntry[A, B, U](tree: Tree[A, B], f: (A, B) => U): Unit = { def g(node: Node[A, B]): Unit = { val l = node.left - if(l ne null) g(l.nn) + if(l ne null) g(l) f(node.key, node.value) val r = node.right - if(r ne null) g(r.nn) + if(r ne null) g(r) } val r = tree.root - if(r ne null) g(r.nn) + if(r ne null) g(r) } def transform[A, B](tree: Tree[A, B], f: (A, B) => B): Unit = transformNode(tree.root, f) private[this] def transformNode[A, B, U](node: Node[A, B] | Null, f: (A, B) => B): Unit = - if (node ne null) transformNodeNonNull(node.nn, f) + if (node ne null) transformNodeNonNull(node, f) private[this] def transformNodeNonNull[A, B, U](node: Node[A, B], f: (A, B) => B): Unit = { - if (node.left ne null) transformNodeNonNull(node.left.nn, f) + if (node.left ne null) transformNodeNonNull(node.left, f) node.value = f(node.key, node.value) - if (node.right ne null) transformNodeNonNull(node.right.nn, f) + if (node.right ne null) transformNodeNonNull(node.right, f) } def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[(A, B)] = @@ -562,9 +562,9 @@ private[collection] object RedBlackTree { def hasProperParentRefs(node: Node[A, B] | Null): Boolean = { if (node eq null) true else { - if ((node.nn.left ne null) && (node.nn.left.nn.parent ne node) || - (node.nn.right ne null) && (node.nn.right.nn.parent ne node)) false - else hasProperParentRefs(node.nn.left) && hasProperParentRefs(node.nn.right) + if ((node.left ne null) && (node.left.parent ne node) || + (node.right ne null) && (node.right.parent ne node)) false + else hasProperParentRefs(node.left) && hasProperParentRefs(node.right) } } @@ -578,9 +578,9 @@ private[collection] object RedBlackTree { private[this] def isValidBST[A, B](node: Node[A, B] | Null)(implicit ord: Ordering[A]): Boolean = { if (node eq null) true else { - if ((node.nn.left ne null) && (ord.compare(node.nn.key, node.nn.left.nn.key) <= 0) || - (node.nn.right ne null) && (ord.compare(node.nn.key, node.nn.right.nn.key) >= 0)) false - else isValidBST(node.nn.left) && isValidBST(node.nn.right) + if ((node.left ne null) && (ord.compare(node.key, node.left.key) <= 0) || + (node.right ne null) && (ord.compare(node.key, node.right.key) >= 0)) false + else isValidBST(node.left) && isValidBST(node.right) } } @@ -592,18 +592,18 @@ private[collection] object RedBlackTree { def noRedAfterRed(node: Node[A, B] | Null): Boolean = { if (node eq null) true - else if (node.nn.red && (isRed(node.nn.left) || isRed(node.nn.right))) false - else noRedAfterRed(node.nn.left) && noRedAfterRed(node.nn.right) + else if (node.red && (isRed(node.left) || isRed(node.right))) false + else noRedAfterRed(node.left) && noRedAfterRed(node.right) } def blackHeight(node: Node[A, B] | Null): Int = { if (node eq null) 1 else { - val lh = blackHeight(node.nn.left) - val rh = blackHeight(node.nn.right) + val lh = blackHeight(node.left) + val rh = blackHeight(node.right) if (lh == -1 || lh != rh) -1 - else if (isRed(node.nn)) lh + else if (isRed(node)) lh else lh + 1 } } @@ -625,7 +625,7 @@ private[collection] object RedBlackTree { val x = xs.next() val right = f(level+1, size-1-leftSize) val n = new Node(x, null, red = false, left, right, null) - if(left ne null) left.nn.parent = n + if(left ne null) left.parent = n right.nn.parent = n n } @@ -646,7 +646,7 @@ private[collection] object RedBlackTree { val (k, v) = xs.next() val right = f(level+1, size-1-leftSize) val n = new Node(k, v, red = false, left, right, null) - if(left ne null) left.nn.parent = n + if(left ne null) left.parent = n right.nn.parent = n n } @@ -655,9 +655,9 @@ private[collection] object RedBlackTree { def copyTree[A, B](n: Node[A, B] | Null): Node[A, B] | Null = if(n eq null) null else { - val c = new Node(n.nn.key, n.nn.value, n.nn.red, copyTree(n.nn.left), copyTree(n.nn.right), null) - if(c.left != null) c.left.nn.parent = c - if(c.right != null) c.right.nn.parent = c + val c = new Node(n.key, n.value, n.red, copyTree(n.left), copyTree(n.right), null) + if(c.left != null) c.left.parent = c + if(c.right != null) c.right.parent = c c } } From f40956a5081844f6acf8a1c560f40c22aaa98546 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 1 Sep 2025 16:49:35 +0200 Subject: [PATCH 12/46] Fix crush --- library/src/scala/collection/mutable/LinkedHashSet.scala | 4 ++-- library/src/scala/collection/mutable/RedBlackTree.scala | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/src/scala/collection/mutable/LinkedHashSet.scala b/library/src/scala/collection/mutable/LinkedHashSet.scala index eb5c8713eb8e..69e24b6164be 100644 --- a/library/src/scala/collection/mutable/LinkedHashSet.scala +++ b/library/src/scala/collection/mutable/LinkedHashSet.scala @@ -58,7 +58,7 @@ class LinkedHashSet[A] * - 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(LinkedHashSet.defaultinitialSize)) + private[this] var table = new Array[Entry | Null](tableSizeFor(LinkedHashSet.defaultinitialSize)) private[this] var threshold: Int = newThreshold(table.length) @@ -278,7 +278,7 @@ class LinkedHashSet[A] n = next } lastLow.next = null - if (old ne preLow.next) table(i) = preLow.next.nn + if (old ne preLow.next) table(i) = preLow.next if (preHigh.next ne null) { table(i + oldlen) = preHigh.next lastHigh.next = null diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index eca8d4436c52..b766089ed858 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -56,10 +56,10 @@ private[collection] object RedBlackTree { object Node { @`inline` def apply[A, B](key: A, value: B, red: Boolean, - left: Node[A, B], right: Node[A, B], parent: Node[A, B]): Node[A, B] = + left: Node[A, B], right: Node[A, B], parent: Node[A, B] | Null): Node[A, B] = new Node(key, value, red, left, right, parent) - @`inline` def leaf[A, B](key: A, value: B, red: Boolean, parent: Node[A, B]): Node[A, B] = + @`inline` def leaf[A, B](key: A, value: B, red: Boolean, parent: Node[A, B] | Null): Node[A, B] = new Node(key, value, red, null, null, parent) def unapply[A, B](t: Node[A, B]) = Some((t.key, t.value, t.left, t.right, t.parent)) @@ -202,7 +202,7 @@ private[collection] object RedBlackTree { if (cmp == 0) y.nn.value = value else { - val z = Node.leaf(key, value, red = true, y.nn) + val z = Node.leaf(key, value, red = true, y) if (y eq null) tree.root = z else if (cmp < 0) y.left = z From 81c69add371ae89520a61e2e82e7dfeff881f481 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 2 Sep 2025 13:04:15 +0200 Subject: [PATCH 13/46] Always apply asInstanceOf with arguments --- library/src/scala/Specializable.scala | 20 ++++++++++---------- library/src/scala/collection/View.scala | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/library/src/scala/Specializable.scala b/library/src/scala/Specializable.scala index 1d885ff50bb6..5728d8c4f03d 100644 --- a/library/src/scala/Specializable.scala +++ b/library/src/scala/Specializable.scala @@ -26,15 +26,15 @@ object Specializable { // Smuggle a list of types by way of a tuple upon which Group is parameterized. class Group[T](value: T) extends SpecializedGroup - 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 Primitives: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit)] = null.asInstanceOf[Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit)]] + final val Everything: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef)] = null.asInstanceOf[Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef)]] + final val Bits32AndUp: Group[(Int, Long, Float, Double)] = null.asInstanceOf[Group[(Int, Long, Float, Double)]] + final val Integral: Group[(Byte, Short, Int, Long, Char)] = null.asInstanceOf[Group[(Byte, Short, Int, Long, Char)]] + final val AllNumeric: Group[(Byte, Short, Int, Long, Char, Float, Double)] = null.asInstanceOf[Group[(Byte, Short, Int, Long, Char, Float, Double)]] + final val BestOfBreed: Group[(Int, Double, Boolean, Unit, AnyRef)] = null.asInstanceOf[Group[(Int, Double, Boolean, Unit, AnyRef)]] + final val Unit: Group[Tuple1[Unit]] = null.asInstanceOf[Group[Tuple1[Unit]]] - 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 + final val Arg: Group[(Int, Long, Float, Double)] = null.asInstanceOf[Group[(Int, Long, Float, Double)]] + final val Args: Group[(Int, Long, Double)] = null.asInstanceOf[Group[(Int, Long, Double)]] + final val Return: Group[(Int, Long, Float, Double, Boolean, Unit)] = null.asInstanceOf[Group[(Int, Long, Float, Double, Boolean, Unit)]] } diff --git a/library/src/scala/collection/View.scala b/library/src/scala/collection/View.scala index 79c88259b953..81a18b2ef08e 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -465,7 +465,7 @@ object View extends IterableFactory[View] { if(pos == maxlen) pos = 0 len += 1 } - underlying = null.asInstanceOf // allow GC of underlying iterator + underlying = null.asInstanceOf[Iterator[A]] // allow GC of underlying iterator if(len > maxlen) len = maxlen pos = pos - len if(pos < 0) pos += maxlen From 84a32d1546d5716e324bc4cd8537ef16a727e568 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 2 Sep 2025 15:06:11 +0200 Subject: [PATCH 14/46] Refine .nn usages --- .../convert/impl/BinaryTreeStepper.scala | 18 ++++---- .../collection/immutable/RedBlackTree.scala | 40 ++++++++--------- .../scala/collection/immutable/TreeMap.scala | 18 ++++---- .../scala/collection/immutable/TreeSet.scala | 8 ++-- .../mutable/CollisionProofHashMap.scala | 44 +++++++++++-------- .../scala/collection/mutable/HashMap.scala | 34 +++++++------- .../scala/collection/mutable/HashSet.scala | 6 +-- .../collection/mutable/LinkedHashSet.scala | 2 +- .../collection/mutable/RedBlackTree.scala | 20 ++++----- .../scala/collection/mutable/TreeMap.scala | 18 ++++---- .../scala/collection/mutable/TreeSet.scala | 8 ++-- .../src/scala/concurrent/impl/Promise.scala | 2 +- library/src/scala/io/Source.scala | 6 ++- 13 files changed, 117 insertions(+), 107 deletions(-) diff --git a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala index 01a3c60865eb..d736044f4f90 100644 --- a/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala +++ b/library/src/scala/collection/convert/impl/BinaryTreeStepper.scala @@ -48,7 +48,7 @@ private[collection] object BinaryTreeStepper { */ 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 + protected val left: T => T | Null, protected val right: T => T | Null ) extends EfficientSplit { /** Unrolls a subtree onto the stack starting from a particular node, returning @@ -144,7 +144,7 @@ extends EfficientSplit { 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 + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T | Null, _right: T => T | Null, protected val extract: T => A ) extends BinaryTreeStepperBase[A, T, AnyStepper[A], AnyBinaryTreeStepper[A, T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with AnyStepper[A] { @@ -161,7 +161,7 @@ with AnyStepper[A] { new AnyBinaryTreeStepper[A, T](maxL, myC, stk, ix, left, right, extract) } private[collection] object AnyBinaryTreeStepper { - def from[A, T <: AnyRef](maxLength: Int, root: T | Null, left: T => T, right: T => T, extract: T => A): AnyBinaryTreeStepper[A, T] = { + def from[A, T <: AnyRef](maxLength: Int, root: T | Null, left: T => T | Null, right: T => T | Null, extract: T => A): AnyBinaryTreeStepper[A, T] = { val ans = new AnyBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans @@ -170,7 +170,7 @@ private[collection] object AnyBinaryTreeStepper { 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 + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T | Null, _right: T => T | Null, protected val extract: T => Double ) extends BinaryTreeStepperBase[Double, T, DoubleStepper, DoubleBinaryTreeStepper[T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with DoubleStepper { @@ -187,7 +187,7 @@ with DoubleStepper { new DoubleBinaryTreeStepper[T](maxL, myC, stk, ix, left, right, extract) } private [collection] object DoubleBinaryTreeStepper { - def from[T <: AnyRef](maxLength: Int, root: T | Null, left: T => T, right: T => T, extract: T => Double): DoubleBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T | Null, left: T => T | Null, right: T => T | Null, extract: T => Double): DoubleBinaryTreeStepper[T] = { val ans = new DoubleBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans @@ -196,7 +196,7 @@ private [collection] object DoubleBinaryTreeStepper { 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 + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T | Null, _right: T => T | Null, protected val extract: T => Int ) extends BinaryTreeStepperBase[Int, T, IntStepper, IntBinaryTreeStepper[T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with IntStepper { @@ -213,7 +213,7 @@ with IntStepper { new IntBinaryTreeStepper[T](maxL, myC, stk, ix, left, right, extract) } private [collection] object IntBinaryTreeStepper { - def from[T <: AnyRef](maxLength: Int, root: T | Null, left: T => T, right: T => T, extract: T => Int): IntBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T | Null, left: T => T | Null, right: T => T | Null, extract: T => Int): IntBinaryTreeStepper[T] = { val ans = new IntBinaryTreeStepper(0, null, BinaryTreeStepper.emptyStack, -1, left, right, extract) ans.initialize(root, maxLength) ans @@ -223,7 +223,7 @@ private [collection] object IntBinaryTreeStepper { 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 + _maxLength: Int, _myCurrent: T | Null, _stack: Array[AnyRef | Null], _index: Int, _left: T => T | Null, _right: T => T | Null, protected val extract: T => Long ) extends BinaryTreeStepperBase[Long, T, LongStepper, LongBinaryTreeStepper[T]](_maxLength, _myCurrent, _stack, _index, _left, _right) with LongStepper { @@ -240,7 +240,7 @@ with LongStepper { new LongBinaryTreeStepper[T](maxL, myC, stk, ix, left, right, extract) } private [collection] object LongBinaryTreeStepper { - def from[T <: AnyRef](maxLength: Int, root: T | Null, left: T => T, right: T => T, extract: T => Long): LongBinaryTreeStepper[T] = { + def from[T <: AnyRef](maxLength: Int, root: T | Null, left: T => T | Null, right: T => T | Null, 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/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 4d547f071f49..2321db612e64 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -1097,26 +1097,26 @@ private[collection] object RedBlackTree { if (tl eq null) tr else if (tr eq null) tl else if (tl.isRed) { - if (tr.isRed) { - //tl is red, tr is red - val bc = append(tl.right, tr.left) - if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left), tr.withLeft(bc.nn.right)) - else tl.withRight(tr.withLeft(bc)) - } else { - //tl is red, tr is black - tl.withRight(append(tl.right, tr)) - } - } else { - if (tr.isBlack) { - //tl is black tr is black - val bc = append(tl.right, tr.left) - if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left), tr.withLeft(bc.nn.right)) - else balLeft(tl, tl.left, tr.withLeft(bc)) - } else { - //tl is black tr is red - tr.withLeft(append(tl, tr.left)) - } - } + if (tr.isRed) { + //tl is red, tr is red + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left), tr.withLeft(bc.nn.right)) + else tl.withRight(tr.withLeft(bc)) + } else { + //tl is red, tr is black + tl.withRight(append(tl.right, tr)) + } + } else { + if (tr.isBlack) { + //tl is black tr is black + val bc = append(tl.right, tr.left) + if (isRedTree(bc)) bc.nn.withLeftRight(tl.withRight(bc.nn.left), tr.withLeft(bc.nn.right)) + else balLeft(tl, tl.left, tr.withLeft(bc)) + } else { + //tl is black tr is red + tr.withLeft(append(tl, tr.left)) + } + } } diff --git a/library/src/scala/collection/immutable/TreeMap.scala b/library/src/scala/collection/immutable/TreeMap.scala index 70038e6449e2..5323ec2a0f90 100644 --- a/library/src/scala/collection/immutable/TreeMap.scala +++ b/library/src/scala/collection/immutable/TreeMap.scala @@ -100,7 +100,7 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( scala.collection.convert.impl.AnyBinaryTreeStepper.from[(K, V), RB.Tree[K, V]]( - size, tree, _.left.nn, _.right.nn, x => (x.key, x.value) + size, tree, _.left, _.right, x => (x.key, x.value) ) ) @@ -108,10 +108,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree, _.left.nn, _.right.nn, _.key)) + 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[K, T](size, tree, _.left, _.right, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -120,10 +120,10 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl import scala.collection.convert.impl._ type T = RB.Tree[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree, _.left.nn, _.right.nn, _.value.asInstanceOf[V])) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.value.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.value.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree, _.left, _.right, _.value.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree, _.left, _.right, _.value.asInstanceOf[V])) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/collection/immutable/TreeSet.scala b/library/src/scala/collection/immutable/TreeSet.scala index 299f29970b78..de5cb9261105 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -138,10 +138,10 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ 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.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree, _.left.nn, _.right.nn, _.key)) + 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)) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/collection/mutable/CollisionProofHashMap.scala b/library/src/scala/collection/mutable/CollisionProofHashMap.scala index 28d20860b9e1..69f2ac4af202 100644 --- a/library/src/scala/collection/mutable/CollisionProofHashMap.scala +++ b/library/src/scala/collection/mutable/CollisionProofHashMap.scala @@ -564,11 +564,11 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double } else if (z.right eq null) { x = z.left - root = transplant(root, z, z.left.nn) + root = transplant(root, z, z.left) xParent = z.parent } else { - y = CollisionProofHashMap.minNodeNonNull(z.right.nn) + y = CollisionProofHashMap.minNodeNonNull(z.right) yIsRed = y.red x = y.right @@ -663,7 +663,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double x.right = y.left val xp = x.parent - if (y.left ne null) y.left.nn.parent = x + if (y.left ne null) y.left.parent = x y.parent = xp if (xp eq null) root = y @@ -681,7 +681,7 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double x.left = y.right val xp = x.parent - if (y.right ne null) y.right.nn.parent = x + if (y.right ne null) y.right.parent = x y.parent = xp if (xp eq null) root = y @@ -700,8 +700,8 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double private[this] def transplant(_root: RBNode, to: RBNode, from: RBNode): RBNode = { var root = _root if (to.parent eq null) root = from - else if (to eq to.parent.nn.left) to.parent.nn.left = from - else to.parent.nn.right = from + else if (to eq to.parent.left) to.parent.left = from + else to.parent.right = from if (from ne null) from.parent = to.parent root } @@ -791,34 +791,42 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { /////////////////////////// Red-Black Tree Node - final class RBNode[K, V](var key: K, var hash: Int, var value: V, var red: Boolean, var left: RBNode[K, V] | Null, var right: RBNode[K, V] | Null, var parent: RBNode[K, V] | Null) extends Node { + final class RBNode[K, V]( + var key: K, var hash: Int, var value: V, var red: Boolean, + @annotation.stableNull + var left: RBNode[K, V] | Null, + @annotation.stableNull + var right: RBNode[K, V] | Null, + @annotation.stableNull + var parent: RBNode[K, V] | Null + ) extends Node { override def toString: String = "RBNode(" + key + ", " + hash + ", " + value + ", " + red + ", " + left + ", " + right + ")" @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): RBNode[K, V] | Null = { val cmp = compare(k, h, this) if (cmp < 0) { - if(left ne null) left.nn.getNode(k, h) else null + if(left ne null) left.getNode(k, h) else null } else if (cmp > 0) { - if(right ne null) right.nn.getNode(k, h) else null + if(right ne null) right.getNode(k, h) else null } else this } def foreach[U](f: ((K, V)) => U): Unit = { - if(left ne null) left.nn.foreach(f) + if(left ne null) left.foreach(f) f((key, value)) - if(right ne null) right.nn.foreach(f) + if(right ne null) right.foreach(f) } def foreachEntry[U](f: (K, V) => U): Unit = { - if(left ne null) left.nn.foreachEntry(f) + if(left ne null) left.foreachEntry(f) f(key, value) - if(right ne null) right.nn.foreachEntry(f) + if(right ne null) right.foreachEntry(f) } def foreachNode[U](f: RBNode[K, V] => U): Unit = { - if(left ne null) left.nn.foreachNode(f) + if(left ne null) left.foreachNode(f) f(this) - if(right ne null) right.nn.foreachNode(f) + if(right ne null) right.foreachNode(f) } } @@ -826,18 +834,18 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { new RBNode(key, hash, value, red, null, null, parent) @tailrec private def minNodeNonNull[A, B](node: RBNode[A, B]): RBNode[A, B] = - if (node.left eq null) node else minNodeNonNull(node.left.nn) + if (node.left eq null) node else minNodeNonNull(node.left) /** * Returns the node that follows `node` in an in-order tree traversal. If `node` has the maximum key (and is, * therefore, the last node), this method returns `null`. */ private def successor[A, B](node: RBNode[A, B]): RBNode[A, B] | Null = { - if (node.right ne null) minNodeNonNull(node.right.nn) + if (node.right ne null) minNodeNonNull(node.right) else { var x = node var y = x.parent - while ((y ne null) && (x eq y.nn.right)) { + while ((y ne null) && (x eq y.right)) { x = y y = y.parent } diff --git a/library/src/scala/collection/mutable/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index 8074b6b77915..cd38ac065c8a 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -384,8 +384,8 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) if(size == 0) table = new Array[Node[K, V] | Null](newlen) else { table = java.util.Arrays.copyOf(table, newlen) - 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) + 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) // 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) { @@ -393,27 +393,27 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) while (i < oldlen) { val old = table(i) if(old ne null) { - preLow.nn.next = null - preHigh.nn.next = null - var lastLow: Node[K, V] | Null = preLow - var lastHigh: Node[K, V] | Null = preHigh + preLow.next = null + preHigh.next = null + var lastLow: Node[K, V] = preLow + var lastHigh: Node[K, V] = preHigh var n: Node[K, V] | Null = old while(n ne null) { val next = n.next if((n.hash & oldlen) == 0) { // keep low - lastLow.nn.next = n + lastLow.next = n lastLow = n } else { // move to high - lastHigh.nn.next = n + lastHigh.next = n lastHigh = n } n = next } - lastLow.nn.next = null - if(old ne preLow.nn.next) table(i) = preLow.nn.next - if(preHigh.nn.next ne null) { - table(i + oldlen) = preHigh.nn.next - lastHigh.nn.next = null + 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 } } i += 1 @@ -626,7 +626,7 @@ 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] | Null) { + private[collection] final class Node[K, V](_key: K, _hash: Int, private[this] var _value: V, @annotation.stableNull private[this] var _next: Node[K, V] | Null) { def key: K = _key def hash: Int = _hash def value: V = _value @@ -638,18 +638,18 @@ object HashMap extends MapFactory[HashMap] { 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.nn.findNode(k, h) + else _next.findNode(k, h) @tailrec def foreach[U](f: ((K, V)) => U): Unit = { f((_key, _value)) - if(_next ne null) _next.nn.foreach(f) + if(_next ne null) _next.foreach(f) } @tailrec def foreachEntry[U](f: (K, V) => U): Unit = { f(_key, _value) - if(_next ne null) _next.nn.foreachEntry(f) + if(_next ne null) _next.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 57a1d9c1fc3b..5dff2155b385 100644 --- a/library/src/scala/collection/mutable/HashSet.scala +++ b/library/src/scala/collection/mutable/HashSet.scala @@ -436,7 +436,7 @@ 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] | Null) { + private[collection] final class Node[K](_key: K, _hash: Int, @annotation.stableNull private[this] var _next: Node[K] | Null) { def key: K = _key def hash: Int = _hash def next: Node[K] | Null = _next @@ -446,12 +446,12 @@ object HashSet extends IterableFactory[HashSet] { 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.nn.findNode(k, h) + else _next.findNode(k, h) @tailrec def foreach[U](f: K => U): Unit = { f(_key) - if(_next ne null) _next.nn.foreach(f) + if(_next ne null) _next.foreach(f) } override def toString = s"Node($key, $hash) -> $next" diff --git a/library/src/scala/collection/mutable/LinkedHashSet.scala b/library/src/scala/collection/mutable/LinkedHashSet.scala index 69e24b6164be..e31cdceb0053 100644 --- a/library/src/scala/collection/mutable/LinkedHashSet.scala +++ b/library/src/scala/collection/mutable/LinkedHashSet.scala @@ -222,7 +222,7 @@ class LinkedHashSet[A] case null => false case nd if nd.hash == hash && nd.key == elem => // first element matches - table(idx) = nd.next.nn + table(idx) = nd.next deleteEntry(nd) contentSize -= 1 true diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index b766089ed858..a9645431ea5b 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -398,33 +398,33 @@ private[collection] object RedBlackTree { private[this] def rotateLeft[A, B](tree: Tree[A, B], x: Node[A, B]): Unit = if (x ne null) { // assert(x.right ne null) - val y = x.right - x.right = y.nn.left + val y = x.right.nn + x.right = y.left - if (y.nn.left ne null) y.nn.left.parent = x - y.nn.parent = x.parent + if (y.left ne null) y.left.parent = x + y.parent = x.parent if (x.parent eq null) tree.root = y else if (x eq x.parent.nn.left) x.parent.left = y else x.parent.right = y - y.nn.left = x + y.left = x x.parent = y } private[this] def rotateRight[A, B](tree: Tree[A, B], x: Node[A, B]): Unit = if (x ne null) { // assert(x.left ne null) - val y = x.left - x.left = y.nn.right + val y = x.left.nn + x.left = y.right - if (y.nn.right ne null) y.nn.right.parent = x - y.nn.parent = x.parent + if (y.right ne null) y.right.parent = x + y.parent = x.parent if (x.parent eq null) tree.root = y else if (x eq x.parent.right) x.parent.right = y else x.parent.left = y - y.nn.right = x + y.right = x x.parent = y } diff --git a/library/src/scala/collection/mutable/TreeMap.scala b/library/src/scala/collection/mutable/TreeMap.scala index 7ec62e57037a..04bd71a424d6 100644 --- a/library/src/scala/collection/mutable/TreeMap.scala +++ b/library/src/scala/collection/mutable/TreeMap.scala @@ -82,7 +82,7 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( scala.collection.convert.impl.AnyBinaryTreeStepper.from[(K, V), RB.Node[K, V]]( - size, tree.root, _.left.nn, _.right.nn, x => (x.key, x.value) + size, tree.root, _.left, _.right, x => (x.key, x.value) ) ) @@ -90,10 +90,10 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: import scala.collection.convert.impl._ type T = RB.Node[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree.root, _.left.nn, _.right.nn, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left, _.right, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[K, T](size, tree.root, _.left, _.right, _.key)) } s.asInstanceOf[S with EfficientSplit] } @@ -102,10 +102,10 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: import scala.collection.convert.impl._ type T = RB.Node[K, V] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.value.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.value.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.value.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree.root, _.left.nn, _.right.nn, _.value)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.value.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.value.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.value.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[V, T] (size, tree.root, _.left, _.right, _.value)) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/collection/mutable/TreeSet.scala b/library/src/scala/collection/mutable/TreeSet.scala index 66141c9982e8..f54423cbe12d 100644 --- a/library/src/scala/collection/mutable/TreeSet.scala +++ b/library/src/scala/collection/mutable/TreeSet.scala @@ -59,10 +59,10 @@ sealed class TreeSet[A] private (private val tree: RB.Tree[A, Null])(implicit va import scala.collection.convert.impl._ type T = RB.Node[A, Null] val s = shape.shape match { - case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Int]) - case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Long]) - case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left.nn, _.right.nn, _.key.asInstanceOf[Double]) - case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.root, _.left.nn, _.right.nn, _.key)) + case StepperShape.IntShape => IntBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Int]) + case StepperShape.LongShape => LongBinaryTreeStepper.from[T] (size, tree.root, _.left, _.right, _.key.asInstanceOf[Long]) + case StepperShape.DoubleShape => DoubleBinaryTreeStepper.from[T](size, tree.root, _.left, _.right, _.key.asInstanceOf[Double]) + case _ => shape.parUnbox(AnyBinaryTreeStepper.from[A, T](size, tree.root, _.left, _.right, _.key)) } s.asInstanceOf[S with EfficientSplit] } diff --git a/library/src/scala/concurrent/impl/Promise.scala b/library/src/scala/concurrent/impl/Promise.scala index 5d302a34a55c..d9bf2879e155 100644 --- a/library/src/scala/concurrent/impl/Promise.scala +++ b/library/src/scala/concurrent/impl/Promise.scala @@ -274,7 +274,7 @@ private[concurrent] object Promise { override final def isCompleted: Boolean = value0 ne null - override final def value: Some[Try[T]] = Some(value0.asInstanceOf[Try[T]]) + override final def value: Option[Try[T]] = Option(value0).asInstanceOf[Option[Try[T]]] @tailrec // returns null if not completed private final def value0: Try[T] | Null = { diff --git a/library/src/scala/io/Source.scala b/library/src/scala/io/Source.scala index f22ab13c5440..49c965d46bc8 100644 --- a/library/src/scala/io/Source.scala +++ b/library/src/scala/io/Source.scala @@ -344,7 +344,9 @@ abstract class Source extends Iterator[Char] with Closeable { report(pos, "warning! " + msg, out) } + @annotation.stableNull private[this] var resetFunction: (() => Source) | Null = null + @annotation.stableNull private[this] var closeFunction: (() => Unit) | Null = null private[this] var positioner: Positioner = RelaxedPositioner @@ -372,11 +374,11 @@ abstract class Source extends Iterator[Char] with Closeable { /** The close() method closes the underlying resource. */ def close(): Unit = { - if (closeFunction != null) closeFunction.nn() + if (closeFunction != null) closeFunction() } /** The reset() method creates a fresh copy of this Source. */ def reset(): Source = - if (resetFunction != null) resetFunction.nn() + if (resetFunction != null) resetFunction() else throw new UnsupportedOperationException("Source's reset() method was not set.") } From 119adf5aba05f85814833b4a7d76a4cf5ce0afd9 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 8 Sep 2025 14:47:19 +0200 Subject: [PATCH 15/46] Address some review comments --- library/src/scala/collection/immutable/RedBlackTree.scala | 2 +- library/src/scala/collection/mutable/AnyRefMap.scala | 2 +- library/src/scala/collection/mutable/LongMap.scala | 2 +- library/src/scala/util/Properties.scala | 6 +++--- library/src/scala/util/Using.scala | 7 +++---- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 2321db612e64..cb7e2a3fc9ed 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -424,7 +424,7 @@ private[collection] object RedBlackTree { } 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: Tree[A, B1] | Null, null: Tree[A, B1] | Null) + RedTree[A, B1](k, v, null, null) } else if (k.asInstanceOf[AnyRef] eq tree.key.asInstanceOf[AnyRef]) { if (overwrite) tree.withV(v) diff --git a/library/src/scala/collection/mutable/AnyRefMap.scala b/library/src/scala/collection/mutable/AnyRefMap.scala index 8228254ddfe2..09786cdcb517 100644 --- a/library/src/scala/collection/mutable/AnyRefMap.scala +++ b/library/src/scala/collection/mutable/AnyRefMap.scala @@ -202,7 +202,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi */ 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(i).asInstanceOf[V | Null] } /** Retrieves the value associated with a key. diff --git a/library/src/scala/collection/mutable/LongMap.scala b/library/src/scala/collection/mutable/LongMap.scala index 3b3f7983e9e5..959544f53bea 100644 --- a/library/src/scala/collection/mutable/LongMap.scala +++ b/library/src/scala/collection/mutable/LongMap.scala @@ -230,7 +230,7 @@ final class LongMap[V] private[collection] (defaultEntry: Long -> V, initialBuff } else { val i = seekEntry(key) - if (i < 0) null else _values(i).asInstanceOf[V] + if (i < 0) null else _values(i).asInstanceOf[V | Null] } } diff --git a/library/src/scala/util/Properties.scala b/library/src/scala/util/Properties.scala index aae9358f50ac..c0bb94f82476 100644 --- a/library/src/scala/util/Properties.scala +++ b/library/src/scala/util/Properties.scala @@ -54,10 +54,10 @@ 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 | Null) = Option(System.getProperty(name)).getOrElse(alt) + def propOrNone(name: String): Option[String] = Option[String](System.getProperty(name)) + def propOrElse(name: String, alt: => String) = propOrNone(name).getOrElse(alt) def propOrEmpty(name: String) = propOrElse(name, "") - def propOrNull(name: String): String | Null = propOrElse(name, null) - def propOrNone(name: String) = Option(propOrNull(name)) + def propOrNull(name: String): String | Null = propOrNone(name).orNull 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/Using.scala b/library/src/scala/util/Using.scala index fae9dcb2d865..0f022bacd896 100644 --- a/library/src/scala/util/Using.scala +++ b/library/src/scala/util/Using.scala @@ -177,8 +177,7 @@ object Using { import Manager._ private var closed = false - @annotation.stableNull - private[this] var resources: List[Resource[_]] | Null = Nil + private[this] var resources: List[Resource[_]] = Nil /** Registers the specified resource with this manager, so that * the resource is released when the manager is closed, and then @@ -195,7 +194,7 @@ 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.nn + resources = new Resource(resource) :: resources } private def manage[A](op: Manager => A): A = { @@ -209,7 +208,7 @@ object Using { } finally { closed = true var rs = resources - resources = null // allow GC, in case something is holding a reference to `this` + resources = null.asInstanceOf[List[Resource[_]]] // allow GC, in case something is holding a reference to `this` while (rs != null && rs.nonEmpty) { val resource = rs.head rs = rs.tail From 6c06d5c63b9206b9f2c5ccd33474dc572e9f9fef Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 11 Sep 2025 11:20:12 +0200 Subject: [PATCH 16/46] Make wrappers and convertors non-nullable --- library/src/scala/Array.scala | 2 +- library/src/scala/StringContext.scala | 8 +- library/src/scala/collection/ArrayOps.scala | 6 +- library/src/scala/collection/Iterator.scala | 2 +- .../src/scala/collection/JavaConverters.scala | 106 +++++++++--------- library/src/scala/collection/SeqView.scala | 2 +- .../collection/convert/AsJavaConverters.scala | 78 ++++++------- .../collection/convert/AsJavaExtensions.scala | 46 ++++---- .../convert/AsScalaConverters.scala | 58 +++++----- .../convert/AsScalaExtensions.scala | 40 +++---- .../convert/ImplicitConversions.scala | 46 ++++---- .../convert/JavaCollectionWrappers.scala | 14 +-- .../scala/collection/immutable/ArraySeq.scala | 8 +- library/src/scala/sys/SystemProperties.scala | 2 +- library/src/scala/util/Properties.scala | 2 +- 15 files changed, 210 insertions(+), 210 deletions(-) diff --git a/library/src/scala/Array.scala b/library/src/scala/Array.scala index e712da22f123..bb23b79eb1a4 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)).nn // clones the array, also if n == 0 + def drop(n: Int): scala.Seq[T] = ArraySeq.unsafeWrapArray(a.drop(n)) // clones the array, also if n == 0 def toSeq: scala.Seq[T] = a.toSeq // clones the array } } diff --git a/library/src/scala/StringContext.scala b/library/src/scala/StringContext.scala index 992c8fc3f639..6f891fb2ffd2 100644 --- a/library/src/scala/StringContext.scala +++ b/library/src/scala/StringContext.scala @@ -95,7 +95,7 @@ case class StringContext(parts: String*) { object s { /** The simple string matcher. * - * Attempts to match the input string to the given interpolated patterns via + * Attempts to match the input string to the given interpolated patterns via * a naive globbing, that is the reverse of the simple interpolator. * * Here is an example usage: @@ -206,7 +206,7 @@ object StringContext { * separated by wildcards * @param input The input you wish to match against * @return None if there is no match, Some containing the sequence of matched - * wildcard strings if there is a match + * wildcard strings if there is a match */ def glob(patternChunks: Seq[String], input: String): Option[Seq[String]] = { var patternIndex = 0 @@ -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 @@ -317,7 +317,7 @@ object StringContext { val len = src.length() def loop(uindex: Int): (Char, Int) = { def loopCP(dindex: Int, codepoint: Int): (Char, Int) = { - //supports BMP + surrogate escapes + //supports BMP + surrogate escapes //but only in four hex-digit code units (uxxxx) if(dindex >= 4) { val usRead = uindex - startindex diff --git a/library/src/scala/collection/ArrayOps.scala b/library/src/scala/collection/ArrayOps.scala index 91a663443647..056dd1e9e5c2 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).nn.mkString("ArrayView(", ", ", ")") + override def toString: String = immutable.ArraySeq.unsafeWrapArray(xs).mkString("ArrayView(", ", ", ")") } /** A lazy filtered array. No filtering is applied until one of `foreach`, `map` or `flatMap` is called. */ @@ -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).nn, that) + def lazyZip[B](that: Iterable[B]^): LazyZip2[A, B, Array[A]]^{that} = new LazyZip2(xs, immutable.ArraySeq.unsafeWrapArray(xs), 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)).nn + immutable.ArraySeq.unsafeWrapArray(Array.copyOf(xs, xs.length)) /** 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 a1cd708d94a5..5cc06ae2069c 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -278,7 +278,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite 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 diff --git a/library/src/scala/collection/JavaConverters.scala b/library/src/scala/collection/JavaConverters.scala index ede74707f250..00c20aa59a78 100644 --- a/library/src/scala/collection/JavaConverters.scala +++ b/library/src/scala/collection/JavaConverters.scala @@ -81,64 +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] | Null): ju.Iterator[A] | Null = asJava(i) + def asJavaIterator[A](i: Iterator[A]): ju.Iterator[A] = asJava(i) @deprecated("Use `asJava` instead", "2.13.0") - def asJavaIterable[A](i: Iterable[A] | Null): jl.Iterable[A] | Null = asJava(i) + def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = asJava(i) @deprecated("Use `asJava` instead", "2.13.0") - def bufferAsJavaList[A](b: mutable.Buffer[A] | Null): ju.List[A] | Null = asJava(b) + def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = asJava(b) @deprecated("Use `asJava` instead", "2.13.0") - def mutableSeqAsJavaList[A](s: mutable.Seq[A] | Null): ju.List[A] | Null = asJava(s) + def mutableSeqAsJavaList[A](s: mutable.Seq[A]): ju.List[A] = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def seqAsJavaList[A](s: Seq[A] | Null): ju.List[A] | Null = asJava(s) + def seqAsJavaList[A](s: Seq[A]): ju.List[A] = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def mutableSetAsJavaSet[A](s: mutable.Set[A] | Null): ju.Set[A] | Null = asJava(s) + def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def setAsJavaSet[A](s: Set[A] | Null): ju.Set[A] | Null = asJava(s) + def setAsJavaSet[A](s: Set[A]): ju.Set[A] = asJava(s) @deprecated("Use `asJava` instead", "2.13.0") - def mutableMapAsJavaMap[K, V](m: mutable.Map[K, V] | Null): ju.Map[K, V] | Null = asJava(m) + def mutableMapAsJavaMap[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = asJava(m) @deprecated("Use `asJava` instead", "2.13.0") - def mapAsJavaMap[K, V](m: Map[K, V] | Null): ju.Map[K, V] | Null = asJava(m) + def mapAsJavaMap[K, V](m: Map[K, V]): ju.Map[K, V] = asJava(m) @deprecated("Use `asJava` instead", "2.13.0") - def mapAsJavaConcurrentMap[K, V](m: concurrent.Map[K, V] | Null): juc.ConcurrentMap[K, V] | Null = asJava(m) + def mapAsJavaConcurrentMap[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = asJava(m) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaIterator[A](i: ju.Iterator[A] | Null): Iterator[A] | Null = asScala(i) + def asScalaIterator[A](i: ju.Iterator[A]): Iterator[A] = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def enumerationAsScalaIterator[A](i: ju.Enumeration[A] | Null): Iterator[A] | Null = asScala(i) + def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def iterableAsScalaIterable[A](i: jl.Iterable[A] | Null): Iterable[A] | Null = asScala(i) + def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def collectionAsScalaIterable[A](i: ju.Collection[A] | Null): Iterable[A] | Null = asScala(i) + def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaBuffer[A](s: ju.List[A] | Null): mutable.Buffer[A] | Null = asScala(s) + def asScalaBuffer[A](s: ju.List[A]): mutable.Buffer[A] = asScala(s) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaSet[A](s: ju.Set[A] | Null): mutable.Set[A] | Null = asScala(s) + def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = asScala(s) @deprecated("Use `asScala` instead", "2.13.0") - def mapAsScalaMap[A, B](m: ju.Map[A, B] | Null): mutable.Map[A, B] | Null = asScala(m) + def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = asScala(m) @deprecated("Use `asScala` instead", "2.13.0") - def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B] | Null): concurrent.Map[A, B] | Null = asScala(m) + def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = asScala(m) @deprecated("Use `asScala` instead", "2.13.0") - def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B] | Null): mutable.Map[A, B] | Null = asScala(p) + def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = asScala(p) @deprecated("Use `asScala` instead", "2.13.0") - def propertiesAsScalaMap(p: ju.Properties | Null): mutable.Map[String, String] | Null = asScala(p) + def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = asScala(p) // Deprecated implicit conversions for code that directly imports them @@ -146,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] | Null): AsJava[ju.Iterator[A]] = + implicit def asJavaIteratorConverter[A](i : Iterator[A]): 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] | Null): AsJavaEnumeration[A] = + implicit def asJavaEnumerationConverter[A](i : Iterator[A]): 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] | Null): AsJava[jl.Iterable[A]] = + implicit def asJavaIterableConverter[A](i : Iterable[A]): 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] | Null): AsJavaCollection[A] = + implicit def asJavaCollectionConverter[A](i : Iterable[A]): 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] | Null): AsJava[ju.List[A]] = + implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): 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] | Null): AsJava[ju.List[A]] = + implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): 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] | Null): AsJava[ju.List[A]] = + implicit def seqAsJavaListConverter[A](b : Seq[A]): 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] | Null): AsJava[ju.Set[A]] = + implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): 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] | Null): AsJava[ju.Set[A]] = + implicit def setAsJavaSetConverter[A](s : Set[A]): 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] | Null): AsJava[ju.Map[K, V]] = + implicit def mutableMapAsJavaMapConverter[K, V](m : mutable.Map[K, V]): 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] | Null): AsJavaDictionary[K, V] = + implicit def asJavaDictionaryConverter[K, V](m : mutable.Map[K, V]): 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] | Null): AsJava[ju.Map[K, V]] = + implicit def mapAsJavaMapConverter[K, V](m : Map[K, V]): 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] | Null): AsJava[juc.ConcurrentMap[K, V]] = + implicit def mapAsJavaConcurrentMapConverter[K, V](m: concurrent.Map[K, V]): AsJava[juc.ConcurrentMap[K, V]] = new AsJava(mapAsJavaConcurrentMap(m)) @@ -238,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] | Null): AsScala[Iterator[A]] = + implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): 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] | Null): AsScala[Iterator[A]] = + implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): 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] | Null): AsScala[Iterable[A]] = + implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): 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] | Null): AsScala[Iterable[A]] = + implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): 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] | Null): AsScala[mutable.Buffer[A]] = + implicit def asScalaBufferConverter[A](l : ju.List[A]): 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] | Null): AsScala[mutable.Set[A]] = + implicit def asScalaSetConverter[A](s : ju.Set[A]): 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] | Null): AsScala[mutable.Map[K, V]] = + implicit def mapAsScalaMapConverter[K, V](m : ju.Map[K, V]): 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] | Null): AsScala[concurrent.Map[K, V]] = + implicit def mapAsScalaConcurrentMapConverter[K, V](m: juc.ConcurrentMap[K, V]): 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] | Null): AsScala[mutable.Map[K, V]] = + implicit def dictionaryAsScalaMapConverter[K, V](p: ju.Dictionary[K, V]): 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 | Null): AsScala[mutable.Map[String, String]] = + implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = new AsScala(propertiesAsScalaMap(p)) /** Generic class containing the `asJava` converter method */ - class AsJava[A](op: => A | Null) { + class AsJava[A](op: => A) { /** Converts a Scala collection to the corresponding Java collection */ - def asJava: A | Null = op + def asJava: A = op } /** Generic class containing the `asScala` converter method */ - class AsScala[A](op: => A | Null) { + class AsScala[A](op: => A) { /** Converts a Java collection to the corresponding Scala collection */ - def asScala: A | Null = op + def asScala: A = op } /** Generic class containing the `asJavaCollection` converter method */ - class AsJavaCollection[A](i: Iterable[A] | Null) { + class AsJavaCollection[A](i: Iterable[A]) { /** Converts a Scala `Iterable` to a Java `Collection` */ - def asJavaCollection: ju.Collection[A] | Null = JavaConverters.asJavaCollection(i) + def asJavaCollection: ju.Collection[A] = JavaConverters.asJavaCollection(i) } /** Generic class containing the `asJavaEnumeration` converter method */ - class AsJavaEnumeration[A](i: Iterator[A] | Null) { + class AsJavaEnumeration[A](i: Iterator[A]) { /** Converts a Scala `Iterator` to a Java `Enumeration` */ - def asJavaEnumeration: ju.Enumeration[A] | Null = JavaConverters.asJavaEnumeration(i) + def asJavaEnumeration: ju.Enumeration[A] = JavaConverters.asJavaEnumeration(i) } /** Generic class containing the `asJavaDictionary` converter method */ - class AsJavaDictionary[K, V](m : mutable.Map[K, V] | Null) { + class AsJavaDictionary[K, V](m : mutable.Map[K, V]) { /** Converts a Scala `Map` to a Java `Dictionary` */ - def asJavaDictionary: ju.Dictionary[K, V] | Null = JavaConverters.asJavaDictionary(m) + def asJavaDictionary: ju.Dictionary[K, V] = JavaConverters.asJavaDictionary(m) } } diff --git a/library/src/scala/collection/SeqView.scala b/library/src/scala/collection/SeqView.scala index c97a1962ef1c..335e48a18b70 100644 --- a/library/src/scala/collection/SeqView.scala +++ b/library/src/scala/collection/SeqView.scala @@ -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]]).nn + immutable.ArraySeq.unsafeWrapArray(arr.asInstanceOf[Array[A]]) } } evaluated = true diff --git a/library/src/scala/collection/convert/AsJavaConverters.scala b/library/src/scala/collection/convert/AsJavaConverters.scala index 1ee8742b9356..b84d746ac89c 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] | Null): ju.Iterator[A] | Null = i match { - case null => null + def asJava[A](i: Iterator[A]): ju.Iterator[A] = i match { + case null => null.asInstanceOf[ju.Iterator[A]] case wrapper: JIteratorWrapper[A @uc] => wrapper.underlying - case _ => new IteratorWrapper(i.nn) + case _ => new IteratorWrapper(i) } /** @@ -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] | Null): ju.Enumeration[A] | Null = i match { - case null => null + def asJavaEnumeration[A](i: Iterator[A]): ju.Enumeration[A] = i match { + case null => null.asInstanceOf[ju.Enumeration[A]] case wrapper: JEnumerationWrapper[A @uc] => wrapper.underlying - case _ => new IteratorWrapper(i.nn) + case _ => new IteratorWrapper(i) } /** @@ -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] | Null): jl.Iterable[A] | Null = i match { - case null => null + def asJava[A](i: Iterable[A]): jl.Iterable[A] = i match { + case null => null.asInstanceOf[jl.Iterable[A]] case wrapper: JIterableWrapper[A @uc] => wrapper.underlying - case _ => new IterableWrapper(i.nn) + case _ => new IterableWrapper(i) } /** @@ -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] | Null): ju.Collection[A] | Null = i match { - case null => null + def asJavaCollection[A](i: Iterable[A]): ju.Collection[A] = i match { + case null => null.asInstanceOf[ju.Collection[A]] case wrapper: JCollectionWrapper[A @uc] => wrapper.underlying - case _ => new IterableWrapper(i.nn) + case _ => new IterableWrapper(i) } /** @@ -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] | Null): ju.List[A] | Null = b match { - case null => null + def asJava[A](b: mutable.Buffer[A]): ju.List[A] = b match { + case null => null.asInstanceOf[ju.List[A]] case wrapper: JListWrapper[A @uc] => wrapper.underlying - case _ => new MutableBufferWrapper(b.nn) + case _ => new MutableBufferWrapper(b) } /** @@ -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] | Null): ju.List[A] | Null = s match { - case null => null + def asJava[A](s: mutable.Seq[A]): ju.List[A] = s match { + case null => null.asInstanceOf[ju.List[A]] case wrapper: JListWrapper[A @uc] => wrapper.underlying - case _ => new MutableSeqWrapper(s.nn) + case _ => new MutableSeqWrapper(s) } /** @@ -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] | Null): ju.List[A] | Null = s match { - case null => null + def asJava[A](s: Seq[A]): ju.List[A] = s match { + case null => null.asInstanceOf[ju.List[A]] case wrapper: JListWrapper[A @uc] => wrapper.underlying - case _ => new SeqWrapper(s.nn) + case _ => new SeqWrapper(s) } /** @@ -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] | Null): ju.Set[A] | Null = s match { - case null => null + def asJava[A](s: mutable.Set[A]): ju.Set[A] = s match { + case null => null.asInstanceOf[ju.Set[A]] case wrapper: JSetWrapper[A @uc] => wrapper.underlying - case _ => new MutableSetWrapper(s.nn) + case _ => new MutableSetWrapper(s) } /** @@ -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] | Null): ju.Set[A] | Null = s match { - case null => null + def asJava[A](s: Set[A]): ju.Set[A] = s match { + case null => null.asInstanceOf[ju.Set[A]] case wrapper: JSetWrapper[A @uc] => wrapper.underlying - case _ => new SetWrapper(s.nn) + case _ => new SetWrapper(s) } /** @@ -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] | Null): ju.Map[K, V] | Null = m match { - case null => null + def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = m match { + case null => null.asInstanceOf[ju.Map[K, V]] case wrapper: JMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new MutableMapWrapper(m.nn) + case _ => new MutableMapWrapper(m) } /** @@ -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] | Null): ju.Dictionary[K, V] | Null = m match { - case null => null + def asJavaDictionary[K, V](m: mutable.Map[K, V]): ju.Dictionary[K, V] = m match { + case null => null.asInstanceOf[ju.Dictionary[K, V]] case wrapper: JDictionaryWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new DictionaryWrapper(m.nn) + case _ => new DictionaryWrapper(m) } /** @@ -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] | Null): ju.Map[K, V] | Null = m match { - case null => null + def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = m match { + case null => null.asInstanceOf[ju.Map[K, V]] case wrapper: JMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new MapWrapper(m.nn) + case _ => new MapWrapper(m) } /** @@ -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] | Null): juc.ConcurrentMap[K, V] | Null = m match { - case null => null + def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = m match { + case null => null.asInstanceOf[juc.ConcurrentMap[K, V]] case wrapper: JConcurrentMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new ConcurrentMapWrapper(m.nn) + case _ => new ConcurrentMapWrapper(m) } } diff --git a/library/src/scala/collection/convert/AsJavaExtensions.scala b/library/src/scala/collection/convert/AsJavaExtensions.scala index fc9aa48d5d51..67f127d9e042 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] | Null) { + implicit class IteratorHasAsJava[A](i: Iterator[A]) { /** 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] | Null = conv.asJava(i) + def asJava: ju.Iterator[A] = conv.asJava(i) /** Converts a Scala `Iterator` to a Java `Enumeration`, see * [[AsJavaConverters.asJavaEnumeration `scala.jdk.javaapi.CollectionConverters.asJavaEnumeration`]]. */ - def asJavaEnumeration: ju.Enumeration[A] | Null = conv.asJavaEnumeration(i) + def asJavaEnumeration: ju.Enumeration[A] = conv.asJavaEnumeration(i) } - implicit class IterableHasAsJava[A](i: Iterable[A] | Null) { + implicit class IterableHasAsJava[A](i: Iterable[A]) { /** 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] | Null = conv.asJava(i) + def asJava: jl.Iterable[A] = conv.asJava(i) /** Converts a Scala `Iterator` to a Java `Collection`, see * [[AsJavaConverters.asJavaCollection `scala.jdk.javaapi.CollectionConverters.asJavaCollection`]]. */ - def asJavaCollection: ju.Collection[A] | Null = conv.asJavaCollection(i) + def asJavaCollection: ju.Collection[A] = conv.asJavaCollection(i) } - implicit class BufferHasAsJava[A](b: mutable.Buffer[A] | Null) { + implicit class BufferHasAsJava[A](b: mutable.Buffer[A]) { /** 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] | Null = conv.asJava(b) + def asJava: ju.List[A] = conv.asJava(b) } - implicit class MutableSeqHasAsJava[A](s: mutable.Seq[A] | Null) { + implicit class MutableSeqHasAsJava[A](s: mutable.Seq[A]) { /** 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] | Null = conv.asJava(s) + def asJava: ju.List[A] = conv.asJava(s) } - implicit class SeqHasAsJava[A](s: Seq[A] | Null) { + implicit class SeqHasAsJava[A](s: Seq[A]) { /** 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] | Null = conv.asJava(s) + def asJava: ju.List[A] = conv.asJava(s) } - implicit class MutableSetHasAsJava[A](s: mutable.Set[A] | Null) { + implicit class MutableSetHasAsJava[A](s: mutable.Set[A]) { /** 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] | Null = conv.asJava(s) + def asJava: ju.Set[A] = conv.asJava(s) } - implicit class SetHasAsJava[A](s: Set[A] | Null) { + implicit class SetHasAsJava[A](s: Set[A]) { /** 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] | Null = conv.asJava(s) + def asJava: ju.Set[A] = conv.asJava(s) } - implicit class MutableMapHasAsJava[K, V](m: mutable.Map[K, V] | Null) { + implicit class MutableMapHasAsJava[K, V](m: mutable.Map[K, V]) { /** 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] | Null = conv.asJava(m) + def asJava: ju.Map[K, V] = 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] | Null = conv.asJavaDictionary(m) + def asJavaDictionary: ju.Dictionary[K, V] = conv.asJavaDictionary(m) } - implicit class MapHasAsJava[K, V](m: Map[K, V] | Null) { + implicit class MapHasAsJava[K, V](m: Map[K, V]) { /** 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] | Null = conv.asJava(m) + def asJava: ju.Map[K, V] = conv.asJava(m) } - implicit class ConcurrentMapHasAsJava[K, V](m: concurrent.Map[K, V] | Null) { + implicit class ConcurrentMapHasAsJava[K, V](m: concurrent.Map[K, V]) { /** 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] | Null = conv.asJava(m) + def asJava: juc.ConcurrentMap[K, V] = conv.asJava(m) } } diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index 2c7fa3d788cd..ec55a242f303 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] | Null): Iterator[A] | Null = i match { - case null => null + def asScala[A](i: ju.Iterator[A]): Iterator[A] = i match { + case null => null.asInstanceOf[Iterator[A]] case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JIteratorWrapper(i.nn) + case _ => new JIteratorWrapper(i) } /** @@ -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] | Null): Iterator[A] | Null = e match { - case null => null + def asScala[A](e: ju.Enumeration[A]): Iterator[A] = e match { + case null => null.asInstanceOf[Iterator[A]] case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JEnumerationWrapper(e.nn) + case _ => new JEnumerationWrapper(e) } /** @@ -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] | Null): Iterable[A] | Null = i match { - case null => null + def asScala[A](i: jl.Iterable[A]): Iterable[A] = i match { + case null => null.asInstanceOf[Iterable[A]] case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JIterableWrapper(i.nn) + case _ => new JIterableWrapper(i) } /** @@ -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] | Null): Iterable[A] | Null = c match { - case null => null + def asScala[A](c: ju.Collection[A]): Iterable[A] = c match { + case null => null.asInstanceOf[Iterable[A]] case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe - case _ => new JCollectionWrapper(c.nn) + case _ => new JCollectionWrapper(c) } /** @@ -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] | Null): mutable.Buffer[A] | Null = l match { - case null => null + def asScala[A](l: ju.List[A]): mutable.Buffer[A] = l match { + case null => null.asInstanceOf[mutable.Buffer[A]] case wrapper: MutableBufferWrapper[A @uc] => wrapper.underlying - case _ => new JListWrapper(l.nn) + case _ => new JListWrapper(l) } /** @@ -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] | Null): mutable.Set[A] | Null = s match { - case null => null + def asScala[A](s: ju.Set[A]): mutable.Set[A] = s match { + case null => null.asInstanceOf[mutable.Set[A]] case wrapper: MutableSetWrapper[A @uc] => wrapper.underlying - case _ => new JSetWrapper(s.nn) + case _ => new JSetWrapper(s) } /** @@ -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] | Null): mutable.Map[K, V] | Null = m match { - case null => null + def asScala[K, V](m: ju.Map[K, V]): mutable.Map[K, V] = m match { + case null => null.asInstanceOf[mutable.Map[K, V]] case wrapper: MutableMapWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new JMapWrapper(m.nn) + case _ => new JMapWrapper(m) } /** @@ -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] | Null): concurrent.Map[K, V] | Null = m match { - case null => null + def asScala[K, V](m: juc.ConcurrentMap[K, V]): concurrent.Map[K, V] = m match { + case null => null.asInstanceOf[concurrent.Map[K, V]] case wrapper: ConcurrentMapWrapper[K @uc, V @uc] => wrapper.underlyingConcurrentMap - case _ => new JConcurrentMapWrapper(m.nn) + case _ => new JConcurrentMapWrapper(m) } /** @@ -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] | Null): mutable.Map[K, V] | Null = d match { - case null => null + def asScala[K, V](d: ju.Dictionary[K, V]): mutable.Map[K, V] = d match { + case null => null.asInstanceOf[mutable.Map[K, V]] case wrapper: DictionaryWrapper[K @uc, V @uc] => wrapper.underlying - case _ => new JDictionaryWrapper(d.nn) + case _ => new JDictionaryWrapper(d) } /** @@ -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 | Null): mutable.Map[String, String] | Null = p match { - case null => null + def asScala(p: ju.Properties): mutable.Map[String, String] = p match { + case null => null.asInstanceOf[mutable.Map[String, String]] case _ => new JPropertiesWrapper(p) } } diff --git a/library/src/scala/collection/convert/AsScalaExtensions.scala b/library/src/scala/collection/convert/AsScalaExtensions.scala index cf33c5a12cd3..3ef08f0690f3 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] | Null) { + implicit class IteratorHasAsScala[A](i: ju.Iterator[A]) { /** 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] | Null = conv.asScala(i) + def asScala: Iterator[A] = conv.asScala(i) } - implicit class EnumerationHasAsScala[A](e: ju.Enumeration[A] | Null) { + implicit class EnumerationHasAsScala[A](e: ju.Enumeration[A]) { /** 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] | Null = conv.asScala(e) + def asScala: Iterator[A] = conv.asScala(e) } - implicit class IterableHasAsScala[A](i: jl.Iterable[A] | Null) { + implicit class IterableHasAsScala[A](i: jl.Iterable[A]) { /** Converts a Java `Iterable` to a Scala `Iterable`, see * [[AsScalaConverters.asScala[A](i:Iterable[A])* `scala.jdk.javaapi.CollectionConverters.asScala`]]. */ - def asScala: Iterable[A] | Null = conv.asScala(i) + def asScala: Iterable[A] = conv.asScala(i) } - implicit class CollectionHasAsScala[A](c: ju.Collection[A] | Null) { + implicit class CollectionHasAsScala[A](c: ju.Collection[A]) { /** 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] | Null = conv.asScala(c) + def asScala: Iterable[A] = conv.asScala(c) } - implicit class ListHasAsScala[A](l: ju.List[A] | Null) { + implicit class ListHasAsScala[A](l: ju.List[A]) { /** 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] | Null = conv.asScala(l) + def asScala: mutable.Buffer[A] = conv.asScala(l) } - implicit class SetHasAsScala[A](s: ju.Set[A] | Null) { + implicit class SetHasAsScala[A](s: ju.Set[A]) { /** 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] | Null = conv.asScala(s) + def asScala: mutable.Set[A] = conv.asScala(s) } - implicit class MapHasAsScala[K, V](m: ju.Map[K, V] | Null) { + implicit class MapHasAsScala[K, V](m: ju.Map[K, V]) { /** 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] | Null = conv.asScala(m) + def asScala: mutable.Map[K, V] = conv.asScala(m) } - implicit class ConcurrentMapHasAsScala[K, V](m: juc.ConcurrentMap[K, V] | Null) { + implicit class ConcurrentMapHasAsScala[K, V](m: juc.ConcurrentMap[K, V]) { /** 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] | Null = conv.asScala(m) + def asScala: concurrent.Map[K, V] = conv.asScala(m) } - implicit class DictionaryHasAsScala[K, V](d: ju.Dictionary[K, V] | Null) { + implicit class DictionaryHasAsScala[K, V](d: ju.Dictionary[K, V]) { /** 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] | Null = conv.asScala(d) + def asScala: mutable.Map[K, V] = conv.asScala(d) } - implicit class PropertiesHasAsScala(i: ju.Properties | Null) { + implicit class PropertiesHasAsScala(i: ju.Properties) { /** 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] | Null = conv.asScala(i) + def asScala: mutable.Map[String, String] = conv.asScala(i) } } diff --git a/library/src/scala/collection/convert/ImplicitConversions.scala b/library/src/scala/collection/convert/ImplicitConversions.scala index be4c764cf3c4..b2ebd48f16e9 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] | Null): Iterator[A] | Null = asScalaIterator(it) + implicit def `iterator asScala`[A](it: ju.Iterator[A]): Iterator[A] = asScalaIterator(it) /** Implicitly converts a Java `Enumeration` to a Scala `Iterator`. * @see [[JavaConverters.enumerationAsScalaIterator]] */ - implicit def `enumeration AsScalaIterator`[A](i: ju.Enumeration[A] | Null): Iterator[A] | Null = enumerationAsScalaIterator(i) + implicit def `enumeration AsScalaIterator`[A](i: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(i) /** Implicitly converts a Java `Iterable` to a Scala `Iterable`. * @see [[JavaConverters.iterableAsScalaIterable]] */ - implicit def `iterable AsScalaIterable`[A](i: jl.Iterable[A] | Null): Iterable[A] | Null = iterableAsScalaIterable(i) + implicit def `iterable AsScalaIterable`[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i) /** Implicitly converts a Java `Collection` to an Scala `Iterable`. * @see [[JavaConverters.collectionAsScalaIterable]] */ - implicit def `collection AsScalaIterable`[A](i: ju.Collection[A] | Null): Iterable[A] | Null = collectionAsScalaIterable(i) + implicit def `collection AsScalaIterable`[A](i: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(i) /** Implicitly converts a Java `List` to a Scala mutable `Buffer`. * @see [[JavaConverters.asScalaBuffer]] */ - implicit def `list asScalaBuffer`[A](l: ju.List[A] | Null): mutable.Buffer[A] | Null = asScalaBuffer(l) + implicit def `list asScalaBuffer`[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l) /** Implicitly converts a Java `Set` to a Scala mutable `Set`. * @see [[JavaConverters.asScalaSet]] */ - implicit def `set asScala`[A](s: ju.Set[A] | Null): mutable.Set[A] | Null = asScalaSet(s) + implicit def `set asScala`[A](s: ju.Set[A]): mutable.Set[A] = 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] | Null): mutable.Map[K, V] | Null = mapAsScalaMap(m) + implicit def `map AsScala`[K, V](m: ju.Map[K, V]): mutable.Map[K, V] = 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] | Null): concurrent.Map[K, V] | Null = mapAsScalaConcurrentMap(m) + implicit def `map AsScalaConcurrentMap`[K, V](m: juc.ConcurrentMap[K, V]): concurrent.Map[K, V] = 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] | Null): mutable.Map[K, V] | Null = dictionaryAsScalaMap(p) + implicit def `dictionary AsScalaMap`[K, V](p: ju.Dictionary[K, V]): mutable.Map[K, V] = dictionaryAsScalaMap(p) /** Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`. * @see [[JavaConverters.propertiesAsScalaMap]] */ - implicit def `properties AsScalaMap`(p: ju.Properties | Null): mutable.Map[String, String] | Null = propertiesAsScalaMap(p) + implicit def `properties AsScalaMap`(p: ju.Properties): mutable.Map[String, String] = 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] | Null): ju.Iterator[A] | Null = asJavaIterator(it) + implicit def `iterator asJava`[A](it: Iterator[A]): ju.Iterator[A] = asJavaIterator(it) /** Implicitly converts a Scala `Iterator` to a Java `Enumeration`. * @see [[JavaConverters.asJavaEnumeration]] */ - implicit def `enumeration asJava`[A](it: Iterator[A] | Null): ju.Enumeration[A] | Null = asJavaEnumeration(it) + implicit def `enumeration asJava`[A](it: Iterator[A]): ju.Enumeration[A] = asJavaEnumeration(it) /** Implicitly converts a Scala `Iterable` to a Java `Iterable`. * @see [[JavaConverters.asJavaIterable]] */ - implicit def `iterable asJava`[A](i: Iterable[A] | Null): jl.Iterable[A] | Null = asJavaIterable(i) + implicit def `iterable asJava`[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i) /** Implicitly converts a Scala `Iterable` to an immutable Java `Collection`. * @see [[JavaConverters.asJavaCollection]] */ - implicit def `collection asJava`[A](it: Iterable[A] | Null): ju.Collection[A] | Null = asJavaCollection(it) + implicit def `collection asJava`[A](it: Iterable[A]): ju.Collection[A] = asJavaCollection(it) /** Implicitly converts a Scala mutable `Buffer` to a Java `List`. * @see [[JavaConverters.bufferAsJavaList]] */ - implicit def `buffer AsJavaList`[A](b: mutable.Buffer[A] | Null): ju.List[A] | Null = bufferAsJavaList(b) + implicit def `buffer AsJavaList`[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b) /** Implicitly converts a Scala mutable `Seq` to a Java `List`. * @see [[JavaConverters.mutableSeqAsJavaList]] */ - implicit def `mutableSeq AsJavaList`[A](seq: mutable.Seq[A] | Null): ju.List[A] | Null = mutableSeqAsJavaList(seq) + implicit def `mutableSeq AsJavaList`[A](seq: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(seq) /** Implicitly converts a Scala `Seq` to a Java `List`. * @see [[JavaConverters.seqAsJavaList]] */ - implicit def `seq AsJavaList`[A](seq: Seq[A] | Null): ju.List[A] | Null = seqAsJavaList(seq) + implicit def `seq AsJavaList`[A](seq: Seq[A]): ju.List[A] = seqAsJavaList(seq) /** Implicitly converts a Scala mutable `Set` to a Java `Set`. * @see [[JavaConverters.mutableSetAsJavaSet]] */ - implicit def `mutableSet AsJavaSet`[A](s: mutable.Set[A] | Null): ju.Set[A] | Null = mutableSetAsJavaSet(s) + implicit def `mutableSet AsJavaSet`[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s) /** Implicitly converts a Scala `Set` to a Java `Set`. * @see [[JavaConverters.setAsJavaSet]] */ - implicit def `set AsJavaSet`[A](s: Set[A] | Null): ju.Set[A] | Null = setAsJavaSet(s) + implicit def `set AsJavaSet`[A](s: Set[A]): ju.Set[A] = 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] | Null): ju.Map[K, V] | Null = mutableMapAsJavaMap(m) + implicit def `mutableMap AsJavaMap`[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = 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] | Null): ju.Dictionary[K, V] | Null = asJavaDictionary(m) + implicit def `dictionary asJava`[K, V](m: mutable.Map[K, V]): ju.Dictionary[K, V] = asJavaDictionary(m) /** Implicitly converts a Scala `Map` to a Java `Map`. * @see [[JavaConverters.mapAsJavaMap]] */ - implicit def `map AsJavaMap`[K, V](m: Map[K, V] | Null): ju.Map[K, V] | Null = mapAsJavaMap(m) + implicit def `map AsJavaMap`[K, V](m: Map[K, V]): ju.Map[K, V] = 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] | Null): juc.ConcurrentMap[K, V] | Null = mapAsJavaConcurrentMap(m) + implicit def `map AsJavaConcurrentMap`[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m) } /** diff --git a/library/src/scala/collection/convert/JavaCollectionWrappers.scala b/library/src/scala/collection/convert/JavaCollectionWrappers.scala index a891f7787454..2be956516c3b 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.nn + def iterator = underlying.iterator.asScala 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: Iterator[A] = underlying.iterator.asScala.nn + def iterator: Iterator[A] = underlying.iterator.asScala 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.nn + override def iterator: Iterator[A] = underlying.iterator.asScala 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.nn + def iterator: Iterator[A] = underlying.iterator.asScala 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.nn - def elements: ju.Enumeration[V] = underlying.valuesIterator.asJavaEnumeration.nn + def keys: ju.Enumeration[K] = underlying.keysIterator.asJavaEnumeration + def elements: ju.Enumeration[V] = underlying.valuesIterator.asJavaEnumeration 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.nn map (k => (k, underlying get k)) + def iterator = underlying.keys.asScala map (k => (k, underlying get k)) override def clear() = iterator.foreach(entry => underlying.remove(entry._1)) diff --git a/library/src/scala/collection/immutable/ArraySeq.scala b/library/src/scala/collection/immutable/ArraySeq.scala index 1ef38604435a..88ec33e729d8 100644 --- a/library/src/scala/collection/immutable/ArraySeq.scala +++ b/library/src/scala/collection/immutable/ArraySeq.scala @@ -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)).nn + case _ => unsafeWrapArray(Array.from[A](it)) } def newBuilder[A : ClassTag]: Builder[A, ArraySeq[A]] = - ArrayBuffer.newBuilder[A].mapResult(b => unsafeWrapArray[A](b.toArray).nn) + ArrayBuffer.newBuilder[A].mapResult(b => unsafeWrapArray[A](b.toArray)) 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).nn + ArraySeq.unsafeWrapArray(elements) } /** @@ -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] | Null): ArraySeq[T] | Null = ((x: @unchecked) match { + def unsafeWrapArray[T](x: Array[T]): ArraySeq[T] = ((x: @unchecked) match { case null => null case x: Array[AnyRef] => new ofRef[AnyRef](x) case x: Array[Int] => new ofInt(x) diff --git a/library/src/scala/sys/SystemProperties.scala b/library/src/scala/sys/SystemProperties.scala index 6daac4493a78..24c935e85e5c 100644 --- a/library/src/scala/sys/SystemProperties.scala +++ b/library/src/scala/sys/SystemProperties.scala @@ -41,7 +41,7 @@ extends mutable.AbstractMap[String, String | Null] { override def isEmpty: Boolean = iterator.isEmpty def names: Iterator[String] = wrapAccess ( - System.getProperties().stringPropertyNames().asScala.nn.iterator + System.getProperties().stringPropertyNames().asScala.iterator ) getOrElse Iterator.empty def get(key: String): Option[String] = diff --git a/library/src/scala/util/Properties.scala b/library/src/scala/util/Properties.scala index c0bb94f82476..50cde5fcff6a 100644 --- a/library/src/scala/util/Properties.scala +++ b/library/src/scala/util/Properties.scala @@ -58,7 +58,7 @@ private[scala] trait PropertiesTrait { def propOrElse(name: String, alt: => String) = propOrNone(name).getOrElse(alt) def propOrEmpty(name: String) = propOrElse(name, "") def propOrNull(name: String): String | Null = propOrNone(name).orNull - def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.nn.toLowerCase) + def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.toLowerCase) def setProp(name: String, value: String) = System.setProperty(name, value) def clearProp(name: String) = System.clearProperty(name) From e9663f4c791a98fa3587190f4ebf0d8c4b269f1f Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 15 Sep 2025 21:41:28 +0200 Subject: [PATCH 17/46] Fix NPEs revealed by tests --- .../dotty/tools/dotc/CompilationTests.scala | 4 -- .../collection/immutable/RedBlackTree.scala | 38 ++++++++++--------- .../scala/collection/immutable/TreeMap.scala | 8 ++-- .../scala/collection/immutable/TreeSet.scala | 4 +- .../collection/mutable/UnrolledBuffer.scala | 2 +- library/src/scala/util/matching/Regex.scala | 10 ++--- 6 files changed, 32 insertions(+), 34 deletions(-) diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index baf1b4d66306..a0288d671a11 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -205,7 +205,6 @@ class CompilationTests { ).checkCompile() // Explicit nulls tests - @Ignore @Test def explicitNullsNeg: Unit = { implicit val testGroup: TestGroup = TestGroup("explicitNullsNeg") aggregateTests( @@ -225,7 +224,6 @@ class CompilationTests { } } - @Ignore @Test def explicitNullsPos: Unit = { implicit val testGroup: TestGroup = TestGroup("explicitNullsPos") aggregateTests( @@ -245,13 +243,11 @@ class CompilationTests { } } - @Ignore @Test def explicitNullsWarn: Unit = { implicit val testGroup: TestGroup = TestGroup("explicitNullsWarn") compileFilesInDir("tests/explicit-nulls/warn", explicitNullsOptions) }.checkWarnings() - @Ignore @Test def explicitNullsRun: Unit = { implicit val testGroup: TestGroup = TestGroup("explicitNullsRun") compileFilesInDir("tests/explicit-nulls/run", explicitNullsOptions) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index cb7e2a3fc9ed..c8d7cc21f633 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -311,9 +311,9 @@ private[collection] object RedBlackTree { if (tree.right ne null) _foreachEntry(tree.right.nn, f) } - def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) - def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) - def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) + def iterator[A: Ordering, B](tree: Tree[A, B] | Null, start: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start) + def keysIterator[A: Ordering](tree: Tree[A, _] | Null, start: Option[A] = None): Iterator[A] = new KeysIterator(tree, start) + def valuesIterator[A: Ordering, B](tree: Tree[A, B] | Null, start: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start) @tailrec def nth[A, B](tree: Tree[A, B], n: Int): Tree[A, B] = { @@ -927,16 +927,16 @@ private[collection] object RedBlackTree { equal && (this.lookahead eq null) && (that.lookahead eq null) } } - private[this] class EntriesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, (A, B)](tree, focus) { - override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) + private[this] class EntriesIterator[A: Ordering, B](tree: Tree[A, B] | Null, focus: Option[A]) extends TreeIterator[A, B, (A, B)](tree, focus) { + override def nextResult(tree: Tree[A, B]) = (tree.nn.key, tree.nn.value) } - private[this] class KeysIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, A](tree, focus) { - override def nextResult(tree: Tree[A, B]) = tree.key + private[this] class KeysIterator[A: Ordering, B](tree: Tree[A, B] | Null, focus: Option[A]) extends TreeIterator[A, B, A](tree, focus) { + override def nextResult(tree: Tree[A, B]) = tree.nn.key } - private[this] class ValuesIterator[A: Ordering, B](tree: Tree[A, B], focus: Option[A]) extends TreeIterator[A, B, B](tree, focus) { - override def nextResult(tree: Tree[A, B]) = tree.value + private[this] class ValuesIterator[A: Ordering, B](tree: Tree[A, B] | Null, focus: Option[A]) extends TreeIterator[A, B, B](tree, focus) { + override def nextResult(tree: Tree[A, B]) = tree.nn.value } /** Build a Tree suitable for a TreeSet from an ordered sequence of keys */ @@ -1139,33 +1139,35 @@ private[collection] object RedBlackTree { else 2*bh-1 } - private[this] def joinRight[A, B](tl: Tree[A, B], k: A, v: B, tr: Tree[A, B], bhtl: Int, rtr: Int): Tree[A, B] = { + private[this] def joinRight[A, B](tl: Tree[A, B] | Null, k: A, v: B, tr: Tree[A, B] | Null, bhtl: Int, rtr: Int): Tree[A, B] = { val rtl = rank(tl, bhtl) if(rtl == (rtr/2)*2) RedTree(k, v, tl, tr) else { + val tlnn = tl.nn val tlBlack = isBlackTree(tl) val bhtlr = if(tlBlack) bhtl-1 else bhtl - val ttr = joinRight(tl.right.nn, k, v, tr, bhtlr, rtr) + val ttr = joinRight(tlnn.right, k, v, tr, bhtlr, rtr) if(tlBlack && isRedTree(ttr) && isRedTree(ttr.right)) RedTree(ttr.key, ttr.value, - BlackTree(tl.key, tl.value, tl.left, ttr.left), + BlackTree(tlnn.key, tlnn.value, tlnn.left, ttr.left), ttr.right.nn.black) - else mkTree(tlBlack, tl.key, tl.value, tl.left, ttr) + else mkTree(tlBlack, tlnn.key, tlnn.value, tlnn.left, ttr) } } - private[this] def joinLeft[A, B](tl: Tree[A, B], k: A, v: B, tr: Tree[A, B], rtl: Int, bhtr: Int): Tree[A, B] = { + private[this] def joinLeft[A, B](tl: Tree[A, B] | Null, k: A, v: B, tr: Tree[A, B] | Null, rtl: Int, bhtr: Int): Tree[A, B] = { val rtr = rank(tr, bhtr) if(rtr == (rtl/2)*2) RedTree(k, v, tl, tr) else { + val trnn = tr.nn val trBlack = isBlackTree(tr) val bhtrl = if(trBlack) bhtr-1 else bhtr - val ttl = joinLeft(tl, k, v, tr.left.nn, rtl, bhtrl) + val ttl = joinLeft(tl, k, v, trnn.left, rtl, bhtrl) if(trBlack && isRedTree(ttl) && isRedTree(ttl.left)) RedTree(ttl.key, ttl.value, ttl.left.nn.black, - BlackTree(tr.key, tr.value, ttl.right, tr.right)) - else mkTree(trBlack, tr.key, tr.value, ttl, tr.right) + BlackTree(trnn.key, trnn.value, ttl.right, trnn.right)) + else mkTree(trBlack, trnn.key, trnn.value, ttl, trnn.right) } } @@ -1175,7 +1177,7 @@ private[collection] object RedBlackTree { val bhtl = h(tl, 0) val bhtr = h(tr, 0) if(bhtl > bhtr) { - val tt = joinRight(tl.nn, k, v, tr.nn, bhtl, rank(tr, bhtr)) + val tt = joinRight(tl.nn, k, v, tr.nn, bhtl, rank(tr, bhtr)) // todo: nullable if(isRedTree(tt) && isRedTree(tt.right)) tt.black else tt } else if(bhtr > bhtl) { diff --git a/library/src/scala/collection/immutable/TreeMap.scala b/library/src/scala/collection/immutable/TreeMap.scala index 5323ec2a0f90..810c01ca2e5f 100644 --- a/library/src/scala/collection/immutable/TreeMap.scala +++ b/library/src/scala/collection/immutable/TreeMap.scala @@ -87,15 +87,15 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V] | Null)(impl override def sortedMapFactory: SortedMapFactory[TreeMap] = TreeMap - def iterator: Iterator[(K, V)] = RB.iterator(tree.nn) + def iterator: Iterator[(K, V)] = RB.iterator(tree) - def keysIteratorFrom(start: K): Iterator[K] = RB.keysIterator(tree.nn, Some(start)) + def keysIteratorFrom(start: K): Iterator[K] = RB.keysIterator(tree, Some(start)) override def keySet: TreeSet[K] = new TreeSet(tree)(ordering) - def iteratorFrom(start: K): Iterator[(K, V)] = RB.iterator(tree.nn, Some(start)) + def iteratorFrom(start: K): Iterator[(K, V)] = RB.iterator(tree, Some(start)) - override def valuesIteratorFrom(start: K): Iterator[V] = RB.valuesIterator(tree.nn, Some(start)) + override def valuesIteratorFrom(start: K): Iterator[V] = RB.valuesIterator(tree, Some(start)) override def stepper[S <: Stepper[_]](implicit shape: StepperShape[(K, V), S]): S with EfficientSplit = shape.parUnbox( diff --git a/library/src/scala/collection/immutable/TreeSet.scala b/library/src/scala/collection/immutable/TreeSet.scala index de5cb9261105..6b1a5561935d 100644 --- a/library/src/scala/collection/immutable/TreeSet.scala +++ b/library/src/scala/collection/immutable/TreeSet.scala @@ -130,9 +130,9 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[ if (v eq null) Option.empty else Some(v.key) } - def iterator: Iterator[A] = RB.keysIterator(tree.nn) + def iterator: Iterator[A] = RB.keysIterator(tree) - def iteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree.nn, Some(start)) + def iteratorFrom(start: A): Iterator[A] = RB.keysIterator(tree, Some(start)) override def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S with EfficientSplit = { import scala.collection.convert.impl._ diff --git a/library/src/scala/collection/mutable/UnrolledBuffer.scala b/library/src/scala/collection/mutable/UnrolledBuffer.scala index 67b20fd4b6a0..a3d34d4d06a3 100644 --- a/library/src/scala/collection/mutable/UnrolledBuffer.scala +++ b/library/src/scala/collection/mutable/UnrolledBuffer.scala @@ -264,7 +264,7 @@ 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] | Null, 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 = null) { this: Unrolled[T]^{} => private[collection] def this() = this(0, new Array[T](unrolledlength), null, null) private[collection] def this(b: UnrolledBuffer[T] | Null) = this(0, new Array[T](unrolledlength), null, b) diff --git a/library/src/scala/util/matching/Regex.scala b/library/src/scala/util/matching/Regex.scala index 7b90fb28d749..17dafbe148b0 100644 --- a/library/src/scala/util/matching/Regex.scala +++ b/library/src/scala/util/matching/Regex.scala @@ -284,7 +284,7 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends * @param s The string to match * @return The matches */ - def unapplySeq(s: CharSequence): Option[List[String]] = { + def unapplySeq(s: CharSequence): Option[List[String | Null]] = { val m = pattern.matcher(s) if (runMatcher(m)) Some(List.tabulate(m.groupCount) { i => m.group(i + 1) }) else None @@ -338,7 +338,7 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends * Otherwise, this Regex is applied to the previously matched input, * and the result of that match is used. */ - def unapplySeq(m: Match): Option[List[String]] = + def unapplySeq(m: Match): Option[List[String | Null]] = if (m.matched == null) None else if (m.matcher.pattern == this.pattern) Regex.extractGroupsFromMatch(m) else unapplySeq(m.matched.nn) @@ -783,13 +783,13 @@ object Regex { * }}} */ object Groups { - def unapplySeq(m: Match): Option[Seq[String]] = { + def unapplySeq(m: Match): Option[Seq[String | Null]] = { if (m.groupCount > 0) extractGroupsFromMatch(m) else None } } - @inline private def extractGroupsFromMatch(m: Match): Option[List[String]] = - Some(List.tabulate(m.groupCount) { i => m.group(i + 1).nn }) + @inline private def extractGroupsFromMatch(m: Match): Option[List[String | Null]] = + Some(List.tabulate(m.groupCount) { i => m.group(i + 1) }) /** A class to step through a sequence of regex matches. * From ef97e0d9c79762c23b50738dea9d4520d28718fe Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 15 Sep 2025 21:44:02 +0200 Subject: [PATCH 18/46] Fix a missing comment --- library/src/scala/collection/immutable/RedBlackTree.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index c8d7cc21f633..8eabe65cca37 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -1177,11 +1177,11 @@ private[collection] object RedBlackTree { val bhtl = h(tl, 0) val bhtr = h(tr, 0) if(bhtl > bhtr) { - val tt = joinRight(tl.nn, k, v, tr.nn, bhtl, rank(tr, bhtr)) // todo: nullable + val tt = joinRight(tl, k, v, tr, bhtl, rank(tr, bhtr)) if(isRedTree(tt) && isRedTree(tt.right)) tt.black else tt } else if(bhtr > bhtl) { - val tt = joinLeft(tl.nn, k, v, tr.nn, rank(tl, bhtl), bhtr) + val tt = joinLeft(tl, k, v, tr, rank(tl, bhtl), bhtr) if(isRedTree(tt) && isRedTree(tt.left)) tt.black else tt } else mkTree(isRedTree(tl) || isRedTree(tr), k, v, tl, tr) From f1c5d1994cbd19ce816dc92c825f6dceb9d28a9a Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 15 Sep 2025 21:50:30 +0200 Subject: [PATCH 19/46] Remove some unnecessary .nn --- .../src/scala/collection/convert/StreamExtensions.scala | 8 ++++---- library/src/scala/collection/immutable/RedBlackTree.scala | 6 +++--- library/src/scala/sys/package.scala | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/src/scala/collection/convert/StreamExtensions.scala b/library/src/scala/collection/convert/StreamExtensions.scala index f601feca9e13..0865ab6ea0df 100644 --- a/library/src/scala/collection/convert/StreamExtensions.scala +++ b/library/src/scala/collection/convert/StreamExtensions.scala @@ -272,7 +272,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.nn) + else factory.fromSpecific(stream.iterator.asScala) } /** Convert a generic Java Stream wrapping a primitive type to a corresponding primitive @@ -304,7 +304,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.nn) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Int]].asScala) } } @@ -331,7 +331,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.nn) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Long]].asScala) } } @@ -358,7 +358,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.nn) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Double]].asScala) } } } diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 8eabe65cca37..d7524b39b0a4 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -928,15 +928,15 @@ private[collection] object RedBlackTree { } } private[this] class EntriesIterator[A: Ordering, B](tree: Tree[A, B] | Null, focus: Option[A]) extends TreeIterator[A, B, (A, B)](tree, focus) { - override def nextResult(tree: Tree[A, B]) = (tree.nn.key, tree.nn.value) + override def nextResult(tree: Tree[A, B]) = (tree.key, tree.value) } private[this] class KeysIterator[A: Ordering, B](tree: Tree[A, B] | Null, focus: Option[A]) extends TreeIterator[A, B, A](tree, focus) { - override def nextResult(tree: Tree[A, B]) = tree.nn.key + override def nextResult(tree: Tree[A, B]) = tree.key } private[this] class ValuesIterator[A: Ordering, B](tree: Tree[A, B] | Null, focus: Option[A]) extends TreeIterator[A, B, B](tree, focus) { - override def nextResult(tree: Tree[A, B]) = tree.nn.value + override def nextResult(tree: Tree[A, B]) = tree.value } /** Build a Tree suitable for a TreeSet from an ordered sequence of keys */ diff --git a/library/src/scala/sys/package.scala b/library/src/scala/sys/package.scala index 252d5205d59e..3329e53e0d0b 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.nn).withDefault { v => + def env: Map[String, String] = Map.from(System.getenv().asScala).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).nn.take(got) + ArraySeq.unsafeWrapArray(tarray).take(got) } } From 8068f4f580f0ec562d96df3bf7755a8eaddf8493 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 15 Sep 2025 22:49:27 +0200 Subject: [PATCH 20/46] Try to migrate sjs library --- library-js/src/scala/Console.scala | 2 +- library-js/src/scala/Enumeration.scala | 14 ++++----- .../collection/mutable/ArrayBuilder.scala | 28 +++++++++--------- .../src/scala/runtime/ScalaRunTime.scala | 29 ++++++++++--------- library/src/scala/Enumeration.scala | 6 ++-- project/Build.scala | 1 + 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/library-js/src/scala/Console.scala b/library-js/src/scala/Console.scala index 7eb19b1012ac..bb8aa8f699c8 100644 --- a/library-js/src/scala/Console.scala +++ b/library-js/src/scala/Console.scala @@ -131,7 +131,7 @@ import scala.util.DynamicVariable object Console extends AnsiColor { private[this] val outVar = new DynamicVariable[PrintStream](java.lang.System.out) private[this] val errVar = new DynamicVariable[PrintStream](java.lang.System.err) - private[this] val inVar = new DynamicVariable[BufferedReader](null) + private[this] val inVar = new DynamicVariable[BufferedReader](null.asInstanceOf[BufferedReader]) //new BufferedReader(new InputStreamReader(java.lang.System.in))) protected def setOutDirect(out: PrintStream): Unit = outVar.value = out diff --git a/library-js/src/scala/Enumeration.scala b/library-js/src/scala/Enumeration.scala index 94aec25a60f2..2408cfb2af04 100644 --- a/library-js/src/scala/Enumeration.scala +++ b/library-js/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 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 @@ -192,7 +192,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`. @@ -202,7 +202,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) /** The type of the enumerated values. */ @SerialVersionUID(7091335633555234129L) @@ -231,9 +231,9 @@ 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(name: String | Null) = this(nextId, name) def this() = this(nextId) assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) diff --git a/library-js/src/scala/collection/mutable/ArrayBuilder.scala b/library-js/src/scala/collection/mutable/ArrayBuilder.scala index 4a6f81502474..e494fb5afb4b 100644 --- a/library-js/src/scala/collection/mutable/ArrayBuilder.scala +++ b/library-js/src/scala/collection/mutable/ArrayBuilder.scala @@ -32,7 +32,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] + protected[this] def elems: Array[T] | Null // may not be allocated at size = capacity = 0 protected var size: Int = 0 def length: Int = size @@ -60,7 +60,7 @@ sealed abstract class ArrayBuilder[T] /** Add a slice of an array */ def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = { ensureSize(this.size + length) - Array.copy(xs, offset, elems, this.size, length) + Array.copy(xs, offset, elems.nn, this.size, length) size += length this } @@ -70,8 +70,8 @@ sealed abstract class ArrayBuilder[T] if(k > 0) { ensureSize(this.size + k) xs match { - case xs: Iterable[T] => xs.copyToArray(elems, this.size) - case _ => xs.iterator.copyToArray(elems, this.size) + case xs: Iterable[T] => xs.copyToArray(elems.nn, this.size) + case _ => xs.iterator.copyToArray(elems.nn, this.size) } size += k } else if(k < 0) super.addAll(xs) @@ -227,7 +227,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] = _ @@ -253,7 +253,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[T]] res } else mkArray(size) @@ -300,7 +300,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Byte]] res } else mkArray(size) @@ -342,7 +342,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Short]] res } else mkArray(size) @@ -384,7 +384,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Char]] res } else mkArray(size) @@ -426,7 +426,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Int]] res } else mkArray(size) @@ -468,7 +468,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Long]] res } else mkArray(size) @@ -510,7 +510,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Float]] res } else mkArray(size) @@ -552,7 +552,7 @@ object ArrayBuilder { if (capacity != 0 && capacity == size) { capacity = 0 val res = elems - elems = null + elems = null.asInstanceOf[Array[Double]] res } else mkArray(size) @@ -594,7 +594,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-js/src/scala/runtime/ScalaRunTime.scala b/library-js/src/scala/runtime/ScalaRunTime.scala index 4247002cce6b..716b466cb8e3 100644 --- a/library-js/src/scala/runtime/ScalaRunTime.scala +++ b/library-js/src/scala/runtime/ScalaRunTime.scala @@ -254,22 +254,25 @@ object ScalaRunTime { case s => s + "\n" } + // 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 + // Convert arrays to immutable.ArraySeq for use with Java varargs: def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = - if (xs eq null) null - else ArraySeq.unsafeWrapArray(xs) - def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = { - if (xs eq null) null + mapNull(xs, ArraySeq.unsafeWrapArray(xs)) + def wrapRefArray[T <: AnyRef | Null](xs: Array[T]): ArraySeq[T] = { + if (xs eq null) null.asInstanceOf[ArraySeq[T]] else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] else new ArraySeq.ofRef[T](xs) } - def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = if (xs ne null) new ArraySeq.ofInt(xs) else null - def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = if (xs ne null) new ArraySeq.ofDouble(xs) else null - def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = if (xs ne null) new ArraySeq.ofLong(xs) else null - def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = if (xs ne null) new ArraySeq.ofFloat(xs) else null - def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = if (xs ne null) new ArraySeq.ofChar(xs) else null - def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = if (xs ne null) new ArraySeq.ofByte(xs) else null - def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = if (xs ne null) new ArraySeq.ofShort(xs) else null - def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = if (xs ne null) new ArraySeq.ofBoolean(xs) else null - def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = if (xs ne null) new ArraySeq.ofUnit(xs) else null + def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = mapNull(xs, new ArraySeq.ofInt(xs)) + def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = mapNull(xs, new ArraySeq.ofDouble(xs)) + def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = mapNull(xs, new ArraySeq.ofLong(xs)) + def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = mapNull(xs, new ArraySeq.ofFloat(xs)) + def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = mapNull(xs, new ArraySeq.ofChar(xs)) + def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = mapNull(xs, new ArraySeq.ofByte(xs)) + def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = mapNull(xs, new ArraySeq.ofShort(xs)) + def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = mapNull(xs, new ArraySeq.ofBoolean(xs)) + def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = mapNull(xs, new ArraySeq.ofUnit(xs)) } diff --git a/library/src/scala/Enumeration.scala b/library/src/scala/Enumeration.scala index f4fdd1716862..2e5347472826 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 @annotation.stableNull private var vset: ValueSet | Null = null + @transient private var vset: ValueSet | Null = null @transient @volatile private var vsetDefined = false /** The mapping from the integer used to identify values to their @@ -190,7 +190,7 @@ abstract class Enumeration (initial: Int) extends Serializable { 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] = { + @tailrec def getFields(clazz: Class[_] | Null, acc: Array[JField]): Array[JField] = { if (clazz == null) acc else @@ -250,7 +250,7 @@ abstract class Enumeration (initial: Int) extends Serializable { @SerialVersionUID(0 - 3501153230598116017L) 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(name: String | Null) = this(nextId, name) def this() = this(nextId) assert(!vmap.isDefinedAt(i), "Duplicate id: " + i) diff --git a/project/Build.scala b/project/Build.scala index 91cc669e2c38..f02e2bf89ea1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -2028,6 +2028,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", "-nowarn"), Compile / scalacOptions += "-Yno-stdlib-patches", + Compile / scalacOptions += "-Yexplicit-nulls", Compile / scalacOptions += "-scalajs", // Packaging configuration of the stdlib Compile / packageBin / publishArtifact := true, From aec822144bd193cf2c6aa9f54372984c6946ecfc Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 15 Sep 2025 23:51:39 +0200 Subject: [PATCH 21/46] Update tests about Regex --- tests/explicit-nulls/flexible-types-common/i7883.scala | 2 +- tests/explicit-nulls/neg/i7883.check | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/explicit-nulls/flexible-types-common/i7883.scala b/tests/explicit-nulls/flexible-types-common/i7883.scala index 9ee92553b60d..df7f7cd696ef 100644 --- a/tests/explicit-nulls/flexible-types-common/i7883.scala +++ b/tests/explicit-nulls/flexible-types-common/i7883.scala @@ -1,7 +1,7 @@ import scala.util.matching.Regex object Test extends App { - def head(s: String, r: Regex): Option[(String, String)] = + def head(s: String, r: Regex): Option[(String | Null, String | Null)] = s.trim match { case r(hd, tl) => Some((hd, tl)) // error // error // error case _ => None diff --git a/tests/explicit-nulls/neg/i7883.check b/tests/explicit-nulls/neg/i7883.check index f14e5d4e7481..3cedc51eb274 100644 --- a/tests/explicit-nulls/neg/i7883.check +++ b/tests/explicit-nulls/neg/i7883.check @@ -2,9 +2,9 @@ 8 | case r(hd, tl) => Some((hd, tl)) // error // error // error | ^ | None of the overloaded alternatives of method unapplySeq in class Regex with types - | (m: scala.util.matching.Regex.Match): Option[List[String]] + | (m: scala.util.matching.Regex.Match): Option[List[String | Null]] | (c: Char): Option[List[Char]] - | (s: CharSequence): Option[List[String]] + | (s: CharSequence): Option[List[String | Null]] | match arguments (String | Null) -- [E006] Not Found Error: tests/explicit-nulls/neg/i7883.scala:8:30 --------------------------------------------------- 8 | case r(hd, tl) => Some((hd, tl)) // error // error // error From f6e084c39e61c960014b7cc1567af735be3b1d8e Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 18 Sep 2025 14:23:43 +0200 Subject: [PATCH 22/46] Update required type signatures in sjs --- compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala index e42502fe715b..ca8c93d9c4e0 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala @@ -289,15 +289,15 @@ final class JSDefinitions()(using Context) { @threadUnsafe lazy val EnumerationClass = requiredClass("scala.Enumeration") @threadUnsafe lazy val Enumeration_Value_NoArg = EnumerationClass.requiredValue(nmeValue) @threadUnsafe lazy val Enumeration_Value_IntArg = EnumerationClass.requiredMethod(nmeValue, List(defn.IntType)) - @threadUnsafe lazy val Enumeration_Value_StringArg = EnumerationClass.requiredMethod(nmeValue, List(defn.StringType)) - @threadUnsafe lazy val Enumeration_Value_IntStringArg = EnumerationClass.requiredMethod(nmeValue, List(defn.IntType, defn.StringType)) + @threadUnsafe lazy val Enumeration_Value_StringArg = EnumerationClass.requiredMethod(nmeValue, List(OrNull(defn.StringType))) + @threadUnsafe lazy val Enumeration_Value_IntStringArg = EnumerationClass.requiredMethod(nmeValue, List(defn.IntType, OrNull(defn.StringType))) @threadUnsafe lazy val Enumeration_nextName = EnumerationClass.requiredMethod(termName("nextName")) @threadUnsafe lazy val EnumerationValClass = EnumerationClass.requiredClass("Val") @threadUnsafe lazy val Enumeration_Val_NoArg = EnumerationValClass.requiredMethod(nme.CONSTRUCTOR, Nil) @threadUnsafe lazy val Enumeration_Val_IntArg = EnumerationValClass.requiredMethod(nme.CONSTRUCTOR, List(defn.IntType)) - @threadUnsafe lazy val Enumeration_Val_StringArg = EnumerationValClass.requiredMethod(nme.CONSTRUCTOR, List(defn.StringType)) - @threadUnsafe lazy val Enumeration_Val_IntStringArg = EnumerationValClass.requiredMethod(nme.CONSTRUCTOR, List(defn.IntType, defn.StringType)) + @threadUnsafe lazy val Enumeration_Val_StringArg = EnumerationValClass.requiredMethod(nme.CONSTRUCTOR, List(OrNull(defn.StringType))) + @threadUnsafe lazy val Enumeration_Val_IntStringArg = EnumerationValClass.requiredMethod(nme.CONSTRUCTOR, List(defn.IntType, OrNull(defn.StringType))) def isValueMethod(sym: Symbol)(using Context): Boolean = sym.name == nmeValue && sym.owner == EnumerationClass From 76bee084f66cbb5ea79bc53d13ca8c2424e2687d Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 18 Sep 2025 15:11:06 +0200 Subject: [PATCH 23/46] NO IDEA FOR NOW :) --- project/MiMaFilters.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index bc842ae86039..63aab22018eb 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -569,6 +569,8 @@ object MiMaFilters { // NO IDEA FOR NOW :) ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.mutable.ArrayDequeOps.scala$collection$mutable$ArrayDequeOps$$super$sliding"), + ProblemFilters.exclude[DirectAbstractMethodProblem]("java.util.Dictionary.get"), + ProblemFilters.exclude[DirectAbstractMethodProblem]("java.util.Dictionary.remove"), ), // Breaking changes since last LTS From 66acc44a4127d985e4115b193b919a737210c3de Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 23 Sep 2025 12:30:44 +0200 Subject: [PATCH 24/46] Fix MiMa issue --- .../src/scala/collection/convert/JavaCollectionWrappers.scala | 4 ++-- project/MiMaFilters.scala | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/library/src/scala/collection/convert/JavaCollectionWrappers.scala b/library/src/scala/collection/convert/JavaCollectionWrappers.scala index 2be956516c3b..54dadc6bf772 100644 --- a/library/src/scala/collection/convert/JavaCollectionWrappers.scala +++ b/library/src/scala/collection/convert/JavaCollectionWrappers.scala @@ -526,7 +526,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { def isEmpty: Boolean = underlying.isEmpty def keys: ju.Enumeration[K] = underlying.keysIterator.asJavaEnumeration def elements: ju.Enumeration[V] = underlying.valuesIterator.asJavaEnumeration - def get(key: AnyRef) = try { + def get(key: AnyRef): V = try { underlying get key.asInstanceOf[K] match { case None => null.asInstanceOf[V] case Some(v) => v @@ -538,7 +538,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { case Some(v) => v case None => null.asInstanceOf[V] } - override def remove(key: AnyRef) = try { + override def remove(key: AnyRef): V = try { underlying remove key.asInstanceOf[K] match { case None => null.asInstanceOf[V] case Some(v) => v diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index 63aab22018eb..bc842ae86039 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -569,8 +569,6 @@ object MiMaFilters { // NO IDEA FOR NOW :) ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.mutable.ArrayDequeOps.scala$collection$mutable$ArrayDequeOps$$super$sliding"), - ProblemFilters.exclude[DirectAbstractMethodProblem]("java.util.Dictionary.get"), - ProblemFilters.exclude[DirectAbstractMethodProblem]("java.util.Dictionary.remove"), ), // Breaking changes since last LTS From 2d899efa6bbecb3647dab7adf162984b8c5f2934 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Wed, 24 Sep 2025 15:10:14 +0200 Subject: [PATCH 25/46] Keep Yflexify-tasty tests disabled --- .../dotty/tools/dotc/CompilationTests.scala | 31 ++++++++++--------- .../flexible-unpickle/pos/Flexible_2.scala | 1 + 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index a0288d671a11..8626d823aa4f 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -213,15 +213,16 @@ class CompilationTests { compileFilesInDir("tests/explicit-nulls/unsafe-common", explicitNullsOptions `and` "-Yno-flexible-types", FileFilter.exclude(TestSources.negExplicitNullsScala2LibraryTastyExcludelisted)), ).checkExpectedErrors() - locally { - val unsafeFile = compileFile("tests/explicit-nulls/flexible-unpickle/neg/Unsafe_1.scala", explicitNullsOptions without "-Yexplicit-nulls") - val flexibleFile = compileFile("tests/explicit-nulls/flexible-unpickle/neg/Flexible_2.scala", - explicitNullsOptions.and("-Yflexify-tasty").withClasspath(defaultOutputDir + testGroup + "/Unsafe_1/neg/Unsafe_1")) + // locally { + // val unsafeFile = compileFile("tests/explicit-nulls/flexible-unpickle/neg/Unsafe_1.scala", explicitNullsOptions without "-Yexplicit-nulls") + // val flexibleFile = compileFile("tests/explicit-nulls/flexible-unpickle/neg/Flexible_2.scala", + // explicitNullsOptions.and("-Yflexify-tasty").withClasspath(defaultOutputDir + testGroup + "/Unsafe_1/neg/Unsafe_1")) - flexibleFile.keepOutput.checkExpectedErrors() + // unsafeFile.keepOutput.checkCompile() + // flexibleFile.keepOutput.checkExpectedErrors() - List(unsafeFile, flexibleFile).foreach(_.delete()) - } + // List(unsafeFile, flexibleFile).foreach(_.delete()) + // } } @Test def explicitNullsPos: Unit = { @@ -232,15 +233,15 @@ class CompilationTests { compileFilesInDir("tests/explicit-nulls/unsafe-common", explicitNullsOptions `and` "-language:unsafeNulls" `and` "-Yno-flexible-types"), ).checkCompile() - locally { - val tests = List( - compileFile("tests/explicit-nulls/flexible-unpickle/pos/Unsafe_1.scala", explicitNullsOptions `without` "-Yexplicit-nulls"), - compileFile("tests/explicit-nulls/flexible-unpickle/pos/Flexible_2.scala", - explicitNullsOptions.and("-Yflexify-tasty").withClasspath(defaultOutputDir + testGroup + "/Unsafe_1/pos/Unsafe_1")), - ).map(_.keepOutput.checkCompile()) + // locally { + // val tests = List( + // compileFile("tests/explicit-nulls/flexible-unpickle/pos/Unsafe_1.scala", explicitNullsOptions without "-Yexplicit-nulls"), + // compileFile("tests/explicit-nulls/flexible-unpickle/pos/Flexible_2.scala", + // explicitNullsOptions.and("-Yflexify-tasty").withClasspath(defaultOutputDir + testGroup + "/Unsafe_1/pos/Unsafe_1")), + // ).map(_.keepOutput.checkCompile()) - tests.foreach(_.delete()) - } + // tests.foreach(_.delete()) + // } } @Test def explicitNullsWarn: Unit = { diff --git a/tests/explicit-nulls/flexible-unpickle/pos/Flexible_2.scala b/tests/explicit-nulls/flexible-unpickle/pos/Flexible_2.scala index 55c5dc90ac78..6ee339ab3507 100644 --- a/tests/explicit-nulls/flexible-unpickle/pos/Flexible_2.scala +++ b/tests/explicit-nulls/flexible-unpickle/pos/Flexible_2.scala @@ -1,6 +1,7 @@ import unsafeNulls.Foo.* import unsafeNulls.Unsafe_1 import unsafeNulls.{A, B, C, F, G, H, I, J, L, M, N, S, T, U, expects} +import unsafeNulls.ZIO import scala.reflect.Selectable.reflectiveSelectable import scala.quoted.* From 44182550734a1e64446a4416c134fe9c3d9088a1 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Sun, 28 Sep 2025 23:40:28 +0200 Subject: [PATCH 26/46] Resolve some review comments --- .../collection/mutable/ArrayBuilder.scala | 92 +++++++++--------- library/src/scala/IArray.scala | 94 +++++++++++++++---- library/src/scala/Predef.scala | 15 +-- library/src/scala/collection/Iterator.scala | 9 +- .../src/scala/collection/JavaConverters.scala | 2 +- library/src/scala/collection/SeqView.scala | 3 +- .../scala/collection/concurrent/TrieMap.scala | 3 +- .../convert/impl/BitSetStepper.scala | 9 +- .../scala/collection/immutable/LazyList.scala | 4 +- .../collection/mutable/ArrayBuilder.scala | 92 +++++++++--------- .../scala/collection/mutable/ListBuffer.scala | 2 +- library/src/scala/runtime/ScalaRunTime.scala | 2 +- 12 files changed, 197 insertions(+), 130 deletions(-) diff --git a/library-js/src/scala/collection/mutable/ArrayBuilder.scala b/library-js/src/scala/collection/mutable/ArrayBuilder.scala index e494fb5afb4b..f8a5b6abc47f 100644 --- a/library-js/src/scala/collection/mutable/ArrayBuilder.scala +++ b/library-js/src/scala/collection/mutable/ArrayBuilder.scala @@ -229,10 +229,10 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofRef[T <: AnyRef | Null](implicit ct: ClassTag[T]) extends ArrayBuilder[T] { - protected var elems: Array[T] = _ + protected var elems: Array[T] | Null = null private def mkArray(size: Int): Array[T] = { - if (capacity == size && capacity > 0) elems + if (capacity == size && capacity > 0) elems.nn else if (elems eq null) new Array[T](size) else java.util.Arrays.copyOf[T](elems, size) } @@ -244,7 +244,7 @@ object ArrayBuilder { def addOne(elem: T): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -252,8 +252,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[T]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -276,11 +276,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofByte extends ArrayBuilder[Byte] { - protected var elems: Array[Byte] = _ + protected var elems: Array[Byte] | Null = null private def mkArray(size: Int): Array[Byte] = { val newelems = new Array[Byte](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -291,7 +291,7 @@ object ArrayBuilder { def addOne(elem: Byte): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -299,8 +299,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Byte]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -318,11 +318,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofShort extends ArrayBuilder[Short] { - protected var elems: Array[Short] = _ + protected var elems: Array[Short] | Null = null private def mkArray(size: Int): Array[Short] = { val newelems = new Array[Short](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -333,7 +333,7 @@ object ArrayBuilder { def addOne(elem: Short): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -341,8 +341,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Short]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -360,11 +360,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofChar extends ArrayBuilder[Char] { - protected var elems: Array[Char] = _ + protected var elems: Array[Char] | Null = null private def mkArray(size: Int): Array[Char] = { val newelems = new Array[Char](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -375,7 +375,7 @@ object ArrayBuilder { def addOne(elem: Char): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -383,8 +383,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Char]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -402,11 +402,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofInt extends ArrayBuilder[Int] { - protected var elems: Array[Int] = _ + protected var elems: Array[Int] | Null = null private def mkArray(size: Int): Array[Int] = { val newelems = new Array[Int](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -417,7 +417,7 @@ object ArrayBuilder { def addOne(elem: Int): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -425,8 +425,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Int]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -444,11 +444,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofLong extends ArrayBuilder[Long] { - protected var elems: Array[Long] = _ + protected var elems: Array[Long] | Null = null private def mkArray(size: Int): Array[Long] = { val newelems = new Array[Long](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -459,7 +459,7 @@ object ArrayBuilder { def addOne(elem: Long): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -467,8 +467,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Long]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -486,11 +486,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofFloat extends ArrayBuilder[Float] { - protected var elems: Array[Float] = _ + protected var elems: Array[Float] | Null = null private def mkArray(size: Int): Array[Float] = { val newelems = new Array[Float](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -501,7 +501,7 @@ object ArrayBuilder { def addOne(elem: Float): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -509,8 +509,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Float]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -528,11 +528,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofDouble extends ArrayBuilder[Double] { - protected var elems: Array[Double] = _ + protected var elems: Array[Double] | Null = null private def mkArray(size: Int): Array[Double] = { val newelems = new Array[Double](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -543,7 +543,7 @@ object ArrayBuilder { def addOne(elem: Double): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -551,8 +551,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Double]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -570,11 +570,11 @@ object ArrayBuilder { @SerialVersionUID(3L) class ofBoolean extends ArrayBuilder[Boolean] { - protected var elems: Array[Boolean] = _ + protected var elems: Array[Boolean] | Null = null private def mkArray(size: Int): Array[Boolean] = { val newelems = new Array[Boolean](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -585,7 +585,7 @@ object ArrayBuilder { def addOne(elem: Boolean): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -593,8 +593,8 @@ object ArrayBuilder { def result() = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Boolean]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -612,7 +612,7 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofUnit extends ArrayBuilder[Unit] { - protected def elems: Array[Unit] = throw new UnsupportedOperationException() + protected def elems: Array[Unit] | Null = throw new UnsupportedOperationException() def addOne(elem: Unit): this.type = { size += 1 diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 128f2732772e..ebb4f5aa94a4 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -330,15 +330,23 @@ object IArray: extension [T, U >: T: ClassTag](x: T) def +:(arr: IArray[U]): IArray[U] = genericArrayOps(arr).prepended(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 - - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def genericWrapArray[T](arr: IArray[T]): ArraySeq[T] = - mapNull(arr, ArraySeq.unsafeWrapArray(arr)).asInstanceOf[ArraySeq[T]] + mapNull(arr, ArraySeq.unsafeWrapArray(arr)) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ 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 @@ -348,39 +356,93 @@ object IArray: else ArraySeq.ofRef(arr.asInstanceOf[Array[T]]) ) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapIntArray(arr: IArray[Int]): ArraySeq.ofInt = mapNull(arr, new ArraySeq.ofInt(arr.asInstanceOf[Array[Int]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapDoubleIArray(arr: IArray[Double]): ArraySeq.ofDouble = mapNull(arr, new ArraySeq.ofDouble(arr.asInstanceOf[Array[Double]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapLongIArray(arr: IArray[Long]): ArraySeq.ofLong = mapNull(arr, new ArraySeq.ofLong(arr.asInstanceOf[Array[Long]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapFloatIArray(arr: IArray[Float]): ArraySeq.ofFloat = mapNull(arr, new ArraySeq.ofFloat(arr.asInstanceOf[Array[Float]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapCharIArray(arr: IArray[Char]): ArraySeq.ofChar = mapNull(arr, new ArraySeq.ofChar(arr.asInstanceOf[Array[Char]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapByteIArray(arr: IArray[Byte]): ArraySeq.ofByte = mapNull(arr, new ArraySeq.ofByte(arr.asInstanceOf[Array[Byte]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapShortIArray(arr: IArray[Short]): ArraySeq.ofShort = mapNull(arr, new ArraySeq.ofShort(arr.asInstanceOf[Array[Short]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapBooleanIArray(arr: IArray[Boolean]): ArraySeq.ofBoolean = mapNull(arr, new ArraySeq.ofBoolean(arr.asInstanceOf[Array[Boolean]])) - /** Conversion from IArray to immutable.ArraySeq */ + /** Conversion from IArray to immutable.ArraySeq. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. + */ implicit def wrapUnitIArray(arr: IArray[Unit]): ArraySeq.ofUnit = mapNull(arr, new ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]])) diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index 8ea81f8b2ae2..6b4c0523c8a9 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -597,6 +597,14 @@ object Predef extends LowPriorityImplicits { @experimental inline def fromNullable[T](t: T | Null): Option[T] = Option(t).asInstanceOf[Option[T]] + // For backward compatibility with code compiled without -Yexplicit-nulls. + // If `a` is null, return null; otherwise, return `f`. + private[scala] inline def mapNull[A, B](a: A, inline f: B): B = + if((a: A | Null) == null) null.asInstanceOf[B] else f + + // Use `null` in places where we want to make sure the reference is cleared. + private[scala] inline def nullForGC[T]: T = null.asInstanceOf[T] + /** A type supporting Self-based type classes. * * A is TC @@ -656,10 +664,6 @@ 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] = mapNull(xs, ArraySeq.make(xs)) @@ -699,6 +703,5 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2 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.asInstanceOf[IndexedSeq[T]] - else new ArrayOps(xs).toIndexedSeq + mapNull(xs, new ArrayOps(xs).toIndexedSeq) } diff --git a/library/src/scala/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 5cc06ae2069c..6df7c189cadb 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -272,14 +272,15 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite if (!fill()) Iterator.empty.next() else { filled = false + val buffer = this.buffer.nn // if stepping, retain overlap in prev if (step < size) { - 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) + if (first) prev = buffer.drop(step) + else if (buffer.length == size) Array.copy(src = buffer, srcPos = step, dest = prev.nn, destPos = 0, length = size - step) else prev = null } - val res = immutable.ArraySeq.unsafeWrapArray(buffer.nn).asInstanceOf[immutable.ArraySeq[B]] - buffer = null + val res = immutable.ArraySeq.unsafeWrapArray(buffer).asInstanceOf[immutable.ArraySeq[B]] + this.buffer = null first = false res } diff --git a/library/src/scala/collection/JavaConverters.scala b/library/src/scala/collection/JavaConverters.scala index 00c20aa59a78..15efa3e12f54 100644 --- a/library/src/scala/collection/JavaConverters.scala +++ b/library/src/scala/collection/JavaConverters.scala @@ -123,7 +123,7 @@ object JavaConverters extends AsJavaConverters with AsScalaConverters { def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = asScala(i) @deprecated("Use `asScala` instead", "2.13.0") - def asScalaBuffer[A](s: ju.List[A]): mutable.Buffer[A] = asScala(s) + def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = asScala(l) @deprecated("Use `asScala` instead", "2.13.0") def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = asScala(s) diff --git a/library/src/scala/collection/SeqView.scala b/library/src/scala/collection/SeqView.scala index 335e48a18b70..7269982227f0 100644 --- a/library/src/scala/collection/SeqView.scala +++ b/library/src/scala/collection/SeqView.scala @@ -192,8 +192,7 @@ object SeqView { } private[this] def elems: SomeSeqOps[A]^{this} = { - val orig: SomeSeqOps[A]^{this} = underlying.nn - if (evaluated) _sorted else orig + if (evaluated) _sorted else underlying.nn } def apply(i: Int): A = _sorted.apply(i) diff --git a/library/src/scala/collection/concurrent/TrieMap.scala b/library/src/scala/collection/concurrent/TrieMap.scala index dd07a4205441..f44e7c869cd7 100644 --- a/library/src/scala/collection/concurrent/TrieMap.scala +++ b/library/src/scala/collection/concurrent/TrieMap.scala @@ -73,7 +73,8 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e else GCAS_Complete(m, ct) } else { // try to abort - m.CAS_PREV(prev, new FailedNode(prev.nn)) + // we know `vn eq prev` and `prev ne null` + m.CAS_PREV(prev, new FailedNode(vn)) GCAS_Complete(/*READ*/mainnode, ct) } } diff --git a/library/src/scala/collection/convert/impl/BitSetStepper.scala b/library/src/scala/collection/convert/impl/BitSetStepper.scala index d653e969a001..70d59d2d2555 100644 --- a/library/src/scala/collection/convert/impl/BitSetStepper.scala +++ b/library/src/scala/collection/convert/impl/BitSetStepper.scala @@ -19,6 +19,7 @@ import scala.collection.{BitSetOps, IntStepper, Stepper} private[collection] final class BitSetStepper( + @annotation.stableNull private var underlying: BitSetOps[_] | Null, private var cache0: Long, private var cache1: Long, _i0: Int, _iN: Int, @@ -55,8 +56,8 @@ with IntStepper { } else { cacheIndex = ix - cache0 = underlying.nn.word(cacheIndex) - cache1 = if ((iN - 1) >> LogWL == ix) -1L else underlying.nn.word(cacheIndex+1) + cache0 = underlying.word(cacheIndex) + cache1 = if ((iN - 1) >> LogWL == ix) -1L else underlying.word(cacheIndex+1) findNext() } } @@ -79,8 +80,8 @@ with IntStepper { // Advance old stepper to breakpoint val ixOld0 = half >> LogWL if (ixOld0 > cacheIndex + 1) { - cache0 = underlying.nn.word(ixOld0) - cache1 = if (((iN - 1) >> LogWL) == ixOld0) -1L else underlying.nn.word(ixOld0+1) + cache0 = underlying.word(ixOld0) + cache1 = if (((iN - 1) >> LogWL) == ixOld0) -1L else underlying.word(ixOld0+1) cacheIndex = ixOld0 i0 = half found = false diff --git a/library/src/scala/collection/immutable/LazyList.scala b/library/src/scala/collection/immutable/LazyList.scala index b056fab200ec..82c1402999f4 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 | Null /* Uninitialized | A */ = + @volatile private[this] var _head: Any /* Uninitialized | A */ = if (lazyState eq EmptyMarker) null else Uninitialized // when `_head eq Uninitialized` @@ -296,7 +296,7 @@ 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 | Null /* () => LazyList[A] | MidEvaluation.type | LazyList[A] */ = + private[this] var _tail: AnyRef | Null /* () => LazyList[A] | MidEvaluation.type | LazyList[A] | Null */ = if (lazyState eq EmptyMarker) null else lazyState private def rawHead: Any = _head diff --git a/library/src/scala/collection/mutable/ArrayBuilder.scala b/library/src/scala/collection/mutable/ArrayBuilder.scala index f3f007e8569b..c1af54f73af0 100644 --- a/library/src/scala/collection/mutable/ArrayBuilder.scala +++ b/library/src/scala/collection/mutable/ArrayBuilder.scala @@ -113,10 +113,10 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofRef[T <: AnyRef | Null](implicit ct: ClassTag[T]) extends ArrayBuilder[T] { - protected var elems: Array[T] = _ + protected var elems: Array[T] | Null = null private def mkArray(size: Int): Array[T] = { - if (capacity == size && capacity > 0) elems + if (capacity == size && capacity > 0) elems.nn else if (elems eq null) new Array[T](size) else java.util.Arrays.copyOf[T](elems, size) } @@ -128,7 +128,7 @@ object ArrayBuilder { def addOne(elem: T): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -136,8 +136,8 @@ object ArrayBuilder { def result(): Array[T] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[T]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -160,11 +160,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofByte extends ArrayBuilder[Byte] { - protected var elems: Array[Byte] = _ + protected var elems: Array[Byte] | Null = null private def mkArray(size: Int): Array[Byte] = { val newelems = new Array[Byte](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -175,7 +175,7 @@ object ArrayBuilder { def addOne(elem: Byte): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -183,8 +183,8 @@ object ArrayBuilder { def result(): Array[Byte] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Byte]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -202,11 +202,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofShort extends ArrayBuilder[Short] { - protected var elems: Array[Short] = _ + protected var elems: Array[Short] | Null = null private def mkArray(size: Int): Array[Short] = { val newelems = new Array[Short](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -217,7 +217,7 @@ object ArrayBuilder { def addOne(elem: Short): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -225,8 +225,8 @@ object ArrayBuilder { def result(): Array[Short] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Short]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -244,11 +244,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofChar extends ArrayBuilder[Char] { - protected var elems: Array[Char] = _ + protected var elems: Array[Char] | Null = null private def mkArray(size: Int): Array[Char] = { val newelems = new Array[Char](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -259,7 +259,7 @@ object ArrayBuilder { def addOne(elem: Char): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -267,8 +267,8 @@ object ArrayBuilder { def result(): Array[Char] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Char]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -286,11 +286,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofInt extends ArrayBuilder[Int] { - protected var elems: Array[Int] = _ + protected var elems: Array[Int] | Null = null private def mkArray(size: Int): Array[Int] = { val newelems = new Array[Int](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -301,7 +301,7 @@ object ArrayBuilder { def addOne(elem: Int): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -309,8 +309,8 @@ object ArrayBuilder { def result(): Array[Int] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Int]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -328,11 +328,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofLong extends ArrayBuilder[Long] { - protected var elems: Array[Long] = _ + protected var elems: Array[Long] | Null = null private def mkArray(size: Int): Array[Long] = { val newelems = new Array[Long](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -343,7 +343,7 @@ object ArrayBuilder { def addOne(elem: Long): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -351,8 +351,8 @@ object ArrayBuilder { def result(): Array[Long] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Long]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -370,11 +370,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofFloat extends ArrayBuilder[Float] { - protected var elems: Array[Float] = _ + protected var elems: Array[Float] | Null = null private def mkArray(size: Int): Array[Float] = { val newelems = new Array[Float](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -385,7 +385,7 @@ object ArrayBuilder { def addOne(elem: Float): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -393,8 +393,8 @@ object ArrayBuilder { def result(): Array[Float] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Float]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -412,11 +412,11 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofDouble extends ArrayBuilder[Double] { - protected var elems: Array[Double] = _ + protected var elems: Array[Double] | Null = null private def mkArray(size: Int): Array[Double] = { val newelems = new Array[Double](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -427,7 +427,7 @@ object ArrayBuilder { def addOne(elem: Double): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -435,8 +435,8 @@ object ArrayBuilder { def result(): Array[Double] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Double]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -455,11 +455,11 @@ object ArrayBuilder { class ofBoolean extends ArrayBuilder[Boolean] { this: ofBoolean^{} => - protected var elems: Array[Boolean] = _ + protected var elems: Array[Boolean] | Null = null private def mkArray(size: Int): Array[Boolean] = { val newelems = new Array[Boolean](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) + if (this.size > 0) Array.copy(elems.nn, 0, newelems, 0, this.size) newelems } @@ -470,7 +470,7 @@ object ArrayBuilder { def addOne(elem: Boolean): this.type = { ensureSize(size + 1) - elems(size) = elem + elems.nn(size) = elem size += 1 this } @@ -478,8 +478,8 @@ object ArrayBuilder { def result(): Array[Boolean] = { if (capacity != 0 && capacity == size) { capacity = 0 - val res = elems - elems = null.asInstanceOf[Array[Boolean]] + val res = elems.nn + elems = null res } else mkArray(size) @@ -497,7 +497,7 @@ object ArrayBuilder { @SerialVersionUID(3L) final class ofUnit extends ArrayBuilder[Unit] { - protected def elems: Array[Unit] = throw new UnsupportedOperationException() + protected def elems: Array[Unit] | Null = throw new UnsupportedOperationException() def addOne(elem: Unit): this.type = { val newSize = size + 1 diff --git a/library/src/scala/collection/mutable/ListBuffer.scala b/library/src/scala/collection/mutable/ListBuffer.scala index c026ed254653..e818de4d546d 100644 --- a/library/src/scala/collection/mutable/ListBuffer.scala +++ b/library/src/scala/collection/mutable/ListBuffer.scala @@ -217,7 +217,7 @@ class ListBuffer[A] first = newElem } else { // `p` can not be `null` because the case where `idx == 0` is handled above - val p = predecessor(idx) + val p = predecessor(idx).nn val newElem = new :: (elem, p.tail.tail) if (last0 eq p.tail) { last0 = newElem diff --git a/library/src/scala/runtime/ScalaRunTime.scala b/library/src/scala/runtime/ScalaRunTime.scala index 8bafd7598205..7bd1022a95d2 100644 --- a/library/src/scala/runtime/ScalaRunTime.scala +++ b/library/src/scala/runtime/ScalaRunTime.scala @@ -286,7 +286,7 @@ 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).asInstanceOf[ArraySeq[T]] + def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = ArraySeq.unsafeWrapArray(xs) 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) From 95c32b90fe7e1db21e3e7df23fe80dc4bebef50f Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Sun, 28 Sep 2025 23:55:55 +0200 Subject: [PATCH 27/46] Update comment in LazyListIterable --- library/src/scala/collection/immutable/LazyListIterable.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/scala/collection/immutable/LazyListIterable.scala b/library/src/scala/collection/immutable/LazyListIterable.scala index c74cbf4d5abc..da64bfa51e15 100644 --- a/library/src/scala/collection/immutable/LazyListIterable.scala +++ b/library/src/scala/collection/immutable/LazyListIterable.scala @@ -294,7 +294,7 @@ 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} | Null /* () => LazyListIterable[A] | MidEvaluation.type | LazyListIterable[A] */ = + private[this] var _tail: AnyRef^{this} | Null /* () => LazyListIterable[A] | MidEvaluation.type | LazyListIterable[A] | Null */ = if (lazyState eq EmptyMarker) null else lazyState private def rawHead: Any = _head From a57cec53c9c79c7f00f36609184e83f2d9fa3e8d Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 30 Sep 2025 13:55:19 +0200 Subject: [PATCH 28/46] Migrate scaladoc-new --- library/src/scala/IArray.scala | 6 ++++++ project/Build.scala | 2 +- scaladoc/src/dotty/tools/scaladoc/PathBased.scala | 2 +- scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala | 6 +++--- scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala | 6 +++--- scaladoc/src/dotty/tools/scaladoc/compat.scala | 4 ++-- .../tools/scaladoc/parsers/WikiCodeBlockParser.scala | 8 +++----- .../dotty/tools/scaladoc/renderers/SiteRenderer.scala | 4 ++-- .../src/dotty/tools/scaladoc/renderers/Writer.scala | 2 +- .../src/dotty/tools/scaladoc/site/BlogParser.scala | 4 ++-- .../dotty/tools/scaladoc/site/StaticSiteContext.scala | 6 +++--- .../dotty/tools/scaladoc/site/StaticSiteLoader.scala | 6 +++--- .../tools/scaladoc/snippets/SnippetCompiler.scala | 2 +- scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala | 4 ++-- .../dotty/tools/scaladoc/tasty/comments/Cleaner.scala | 2 +- .../dotty/tools/scaladoc/tasty/comments/Comments.scala | 2 +- .../tools/scaladoc/tasty/comments/Preparser.scala | 10 +++++----- .../tasty/comments/markdown/SnippetRenderer.scala | 2 +- .../tools/scaladoc/tasty/comments/wiki/Entities.scala | 2 +- .../tools/scaladoc/tasty/comments/wiki/Parser.scala | 2 +- scaladoc/src/dotty/tools/scaladoc/util/escape.scala | 4 ++-- 21 files changed, 45 insertions(+), 41 deletions(-) diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index ebb4f5aa94a4..23b0035a2299 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -330,6 +330,12 @@ object IArray: extension [T, U >: T: ClassTag](x: T) def +:(arr: IArray[U]): IArray[U] = genericArrayOps(arr).prepended(x) + // For backward compatibility with code compiled without -Yexplicit-nulls. + // If `a` is null, return null; otherwise, return `f`. + // Have to add a private mapNull here to avoid errors + private inline def mapNull[A, B](a: A, inline f: B): B = + if((a: A | Null) == null) null.asInstanceOf[B] else f + /** Conversion from IArray to immutable.ArraySeq. * * Note: Both the parameter and the return type are non-nullable. However, if a null diff --git a/project/Build.scala b/project/Build.scala index f02e2bf89ea1..6512e63d6a43 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -2691,7 +2691,7 @@ object Build { Compile / scalacOptions := Seq("-deprecation", "-feature", "-unchecked", "-encoding", "UTF8", "-language:implicitConversions"), Compile / scalacOptions += "-experimental", // TODO: Enable these flags when the new stdlib is explicitelly null checked - //Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), + Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), // Make sure that the produced artifacts have the minimum JVM version in the bytecode Compile / javacOptions ++= Seq("--release", Versions.minimumJVMVersion), Compile / scalacOptions ++= Seq("--java-output-version", Versions.minimumJVMVersion), diff --git a/scaladoc/src/dotty/tools/scaladoc/PathBased.scala b/scaladoc/src/dotty/tools/scaladoc/PathBased.scala index 5e24623b43d5..a3ff29ba5269 100644 --- a/scaladoc/src/dotty/tools/scaladoc/PathBased.scala +++ b/scaladoc/src/dotty/tools/scaladoc/PathBased.scala @@ -24,7 +24,7 @@ object PathBased: def parse[T](args: Seq[String], projectRoot: Path = Paths.get("").toAbsolutePath())(using parser: ArgParser[T]): ParsingResult[T] = { val parsed = args.map { - case PathExtractor(path, arg) => parser.parse(arg).map(elem => Entry(Some(Paths.get(path)), elem)) + case PathExtractor(path: String, arg: String) => parser.parse(arg).map(elem => Entry(Some(Paths.get(path)), elem)) case arg => parser.parse(arg).map(elem => Entry(None, elem)) } val errors = parsed.collect { diff --git a/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala b/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala index 50e7589d92fe..abf073aa53aa 100644 --- a/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala +++ b/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala @@ -19,7 +19,7 @@ object Scaladoc: tastyFiles: Seq[File] = Nil, classpath: String = "", bootclasspath: String = "", - output: File, + output: File | Null, docsRoot: Option[String] = None, projectVersion: Option[String] = None, projectLogo: Option[String] = None, @@ -66,13 +66,13 @@ object Scaladoc: if !ctx.reporter.hasErrors then val updatedArgs = parsedArgs.copy(tastyDirs = parsedArgs.tastyDirs, tastyFiles = tastyFiles) - if (parsedArgs.output.exists()) util.IO.delete(parsedArgs.output) + if (parsedArgs.output.nn.exists()) util.IO.delete(parsedArgs.output) run(updatedArgs) report.inform("Done") else report.error("Failure") - if parsedArgs.generateInkuire then dumpInkuireDB(parsedArgs.output.getAbsolutePath, parsedArgs) + if parsedArgs.generateInkuire then dumpInkuireDB(parsedArgs.output.nn.getAbsolutePath, parsedArgs) } ctx.reporter diff --git a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala index b3732bcbc946..9a79c5a84fe1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala +++ b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala @@ -73,9 +73,9 @@ class SourceLinkParser(revision: Option[String]) extends ArgParser[SourceLink]: if unsupported.nonEmpty then Left(s"Unsupported patterns from scaladoc format are used: ${unsupported.mkString(" ")}") else Right(TemplateSourceLink(supported.foldLeft(string)((template, pattern) => template.replace(pattern, SupportedScalaDocPatternReplacements(pattern))))) - case KnownProvider(name, organization, repo, rawRevision, rawSubPath) => - val subPath = Option(rawSubPath).fold("")("/" + _.drop(1)) - val pathRev = Option(rawRevision).map(_.drop(1)).orElse(revision) + case KnownProvider(name: String, organization: String, repo: String, rawRevision, rawSubPath) => + val subPath = Option.fromNullable(rawSubPath).fold("")("/" + _.drop(1)) + val pathRev = Option.fromNullable(rawRevision).map(_.drop(1)).orElse(revision) def withRevision(template: String => SourceLink) = pathRev.fold(Left(s"No revision provided"))(r => Right(template(r))) diff --git a/scaladoc/src/dotty/tools/scaladoc/compat.scala b/scaladoc/src/dotty/tools/scaladoc/compat.scala index d2095b9cc98c..50c2686d8dd6 100644 --- a/scaladoc/src/dotty/tools/scaladoc/compat.scala +++ b/scaladoc/src/dotty/tools/scaladoc/compat.scala @@ -17,10 +17,10 @@ type JMap[K, V] = java.util.Map[K, V] type JHashMap[K, V] = java.util.HashMap[K, V] type JMapEntry[K, V] = java.util.Map.Entry[K, V] -private val emptyListInst = Collections.emptyList +private val emptyListInst: JList[AnyRef] = Collections.emptyList def JNil[A] = emptyListInst.asInstanceOf[JList[A]] -private val emptyMapInst = Collections.emptyMap +private val emptyMapInst: JMap[AnyRef, AnyRef] = Collections.emptyMap def emptyJMap[A, B] = emptyMapInst.asInstanceOf[JMap[A, B]] enum DocLink: diff --git a/scaladoc/src/dotty/tools/scaladoc/parsers/WikiCodeBlockParser.scala b/scaladoc/src/dotty/tools/scaladoc/parsers/WikiCodeBlockParser.scala index e6ebe0d2cc7a..2f47046bf81a 100644 --- a/scaladoc/src/dotty/tools/scaladoc/parsers/WikiCodeBlockParser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/parsers/WikiCodeBlockParser.scala @@ -55,10 +55,9 @@ object WikiCodeBlockParser { def tryStart(state: ParserState, matchedBlockParser: MatchedBlockParser): BlockStart = { val nextNonSpace = state.getNextNonSpaceIndex val line = state.getLine - var matcher: Matcher = null if state.getIndent < 4 then { val trySequence = line.subSequence(nextNonSpace, line.length) - matcher = OPENING_FENCE.matcher(trySequence) + val matcher = OPENING_FENCE.matcher(trySequence) if matcher.find then { val fenceLength = matcher.group(0).length val blockParser = @@ -93,14 +92,13 @@ class WikiCodeBlockParser( val nextNonSpace = state.getNextNonSpaceIndex var newIndex = state.getIndex val line = state.getLine - var matcher: Matcher = null val matches = state.getIndent <= 3 && nextNonSpace < line.length if matches then { val trySequence = line.subSequence(nextNonSpace, line.length) - matcher = WikiCodeBlockParser.CLOSING_FENCE.matcher(trySequence) + val matcher = WikiCodeBlockParser.CLOSING_FENCE.matcher(trySequence) if matcher.find then { val foundFenceLength = matcher.group(0).length if (foundFenceLength >= fenceLength) { // closing fence - we're at end of line, so we can finalize now @@ -150,7 +148,7 @@ class WikiCodeBlockParser( } else block.setContent(content) block.setCharsFromContent - content = null + content = null.asInstanceOf[BlockContent] // release for GC } } diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala index 71b0a1b572ac..f15e13e4a443 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala @@ -33,7 +33,7 @@ trait SiteRenderer(using DocContext) extends Locations: def tryAsDriPlain(str: String): Option[String] = val (path, prefix) = str match - case HashRegex(path, prefix) => (path, prefix) + case HashRegex(path: String, prefix: String) => (path, prefix) case _ => (str, "") val res = ctx.driForLink(content.template.file, path).filter(driExists) res.headOption.map(pathToPage(pageDri, _) + prefix) @@ -46,7 +46,7 @@ trait SiteRenderer(using DocContext) extends Locations: case _ => str val (path, prefix) = newStr match - case HashRegex(path, prefix) => (path, prefix) + case HashRegex(path: String, prefix: String) => (path, prefix) case _ => (newStr, "") val res = ctx.driForLink(content.template.file, path).filter(driExists) diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/Writer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/Writer.scala index 029da21bdda7..af81b05aadc5 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/Writer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/Writer.scala @@ -14,7 +14,7 @@ trait Writer(using ctx: DocContext) extends Locations: private val args = summon[DocContext].args private def dest(path: String) = - val absPath = args.output.toPath.resolve(path) + val absPath = args.output.nn.toPath.resolve(path) if !Files.exists(absPath.getParent) then Files.createDirectories(absPath.getParent) absPath diff --git a/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala b/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala index 68e709a339b2..04a9ee7d9084 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala @@ -8,8 +8,8 @@ import scala.beans.{BooleanBeanProperty, BeanProperty} import scala.util.Try case class BlogConfig( - @BeanProperty input: String, - @BeanProperty output: String, + @BeanProperty input: String | Null, + @BeanProperty output: String | Null, @BooleanBeanProperty hidden: Boolean ): def this() = this(null, null, false) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala index a610e41f12f0..6e2e21c089d0 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala @@ -19,8 +19,8 @@ class StaticSiteContext( var memberLinkResolver: String => Option[DRI] = _ => None - val docsPath = root.toPath.resolve("_docs") - val blogPath = root.toPath.resolve("_blog") + val docsPath: Path = root.toPath.resolve("_docs") + val blogPath: Path = root.toPath.resolve("_blog") def resolveNewBlogPath(stringPath: String): Path = if stringPath.nonEmpty then root.toPath.resolve(stringPath) @@ -114,7 +114,7 @@ class StaticSiteContext( DRI.forPath(relativePath) - def pathFromRoot(myTemplate: LoadedTemplate) = root.toPath.relativize(myTemplate.file.toPath) + def pathFromRoot(myTemplate: LoadedTemplate): Path = root.toPath.relativize(myTemplate.file.toPath) val projectWideProperties = Seq("projectName" -> args.name) ++ diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index e25639c36183..e0834ee78ecf 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -116,8 +116,8 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite def loadBlog(): Option[LoadedTemplate] = { val blogConfig = BlogParser.readYml(root) - val rootPath = Option(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) - val defaultDirectory = Option(blogConfig.output).getOrElse("blog") + val rootPath = Option.fromNullable(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) + val defaultDirectory = Option.fromNullable(blogConfig.output).getOrElse("blog") type Date = (String, String, String) if (!Files.exists(rootPath) || blogConfig.hidden) None @@ -138,7 +138,7 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite val indexDest = ctx.docsPath.resolve(defaultDirectory).resolve("index.html") val regex = raw"(\d*)-(\d*)-(\d*)-(.*)".r def splitDateName(tf: TemplateFile): (Date, String) = tf.file.getName match - case regex(year, month, day, name) => ((year, month, day), name) + case regex(year: String, month: String, day: String, name: String) => ((year, month, day), name) case name => report.warn("Incorrect file name for blog post. Post file name should be in format ---", tf.file) (("1900","01","01"), name) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala index 1648dbe2917b..514155165ea7 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala @@ -48,7 +48,7 @@ class SnippetCompiler( private def newRun(using ctx: Context): Run = scala3Compiler.newRun - private def nullableMessage(msgOrNull: String): String = + private def nullableMessage(msgOrNull: String | Null): String = if (msgOrNull == null) "" else msgOrNull private def createReportMessage(wrappedSnippet: WrappedSnippet, arg: SnippetCompilerArg, diagnostics: Seq[Diagnostic], sourceFile: SourceFile): Seq[SnippetCompilerMessage] = { diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala index 969b1d6462c2..a84137caa5a7 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala @@ -214,7 +214,7 @@ end SymOps class SymOpsWithLinkCache: import SymOps.* - private val externalLinkCache: scala.collection.mutable.Map[AbstractFile, Option[ExternalDocLink]] = MMap() + private val externalLinkCache: scala.collection.mutable.Map[AbstractFile | Null, Option[ExternalDocLink]] = MMap() extension (using Quotes)(sym: reflect.Symbol) @@ -277,7 +277,7 @@ class SymOpsWithLinkCache: then externalLinkCache(csym.associatedFile) else { def calculatePath(file: AbstractFile): String = file.underlyingSource.filter(_ != file).fold("")(f => calculatePath(f) + "/") + file.path - val calculatedLink = Option(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => + val calculatedLink = Option.fromNullable(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => dctx.externalDocumentationLinks.find(_.originRegexes.exists(r => r.matches(path))) } externalLinkCache += (csym.associatedFile -> calculatedLink) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Cleaner.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Cleaner.scala index e495e90018cd..88ca3534fcee 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Cleaner.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Cleaner.scala @@ -13,7 +13,7 @@ object Cleaner { def cleanLine(line: String): String = { // Remove trailing whitespaces TrailingWhitespace.replaceAllIn(line, "") match { - case CleanCommentLine(ctl) => ctl + case CleanCommentLine(ctl: String) => ctl case tl => tl } } diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala index 44a1c3630a5f..5b72e9eb5c42 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala @@ -83,7 +83,7 @@ abstract class MarkupConversion[T](val repr: Repr)(using dctx: DocContext) { lazy val snippetChecker = dctx.snippetChecker - val qctx: repr.qctx.type = if repr == null then null else repr.qctx // TODO why we do need null? + val qctx: repr.qctx.type = if repr == null then null.asInstanceOf[repr.qctx.type] else repr.qctx // TODO why we do need null? val owner: qctx.reflect.Symbol = if repr == null then null.asInstanceOf[qctx.reflect.Symbol] else repr.sym private given qctx.type = qctx diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Preparser.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Preparser.scala index 9fad9e22eeb9..22873d8c424c 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Preparser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Preparser.scala @@ -34,7 +34,7 @@ object Preparser { remaining: List[String], inCodeBlock: Boolean, )(using strippedLinesBeforeNo: Int = 0): PreparsedComment = remaining match { - case CodeBlockStartRegex(before, marker, after) :: ls if !inCodeBlock => + case CodeBlockStartRegex(before: String, marker: String, after: String) :: ls if !inCodeBlock => if (!before.trim.isEmpty && !after.trim.isEmpty && marker == "```") go(docBody, tags, lastTagKey, before :: (marker + after) :: ls, inCodeBlock = false) else if (!before.trim.isEmpty && !after.trim.isEmpty) @@ -55,7 +55,7 @@ object Preparser { go(docBody append endOfLine append (marker + after), tags, lastTagKey, ls, inCodeBlock = true) } - case CodeBlockEndRegex(before, marker, after) :: ls => + case CodeBlockEndRegex(before: String, marker: String, after: String) :: ls => if (!before.trim.isEmpty && !after.trim.isEmpty) go(docBody, tags, lastTagKey, before :: marker :: after :: ls, inCodeBlock = true) else if (!before.trim.isEmpty) @@ -75,18 +75,18 @@ object Preparser { } - case SymbolTagRegex(name, sym, body) :: ls if !inCodeBlock => + case SymbolTagRegex(name: String, sym: String, body: String) :: ls if !inCodeBlock => val key = SymbolTagKey(name, sym) val value = body :: tags.getOrElse(key, Nil) go(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) - case SimpleTagRegex(name, body) :: ls if !inCodeBlock => + case SimpleTagRegex(name: String, body: String) :: ls if !inCodeBlock => val key = SimpleTagKey(name) val value = body :: tags.getOrElse(key, Nil) go(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) - case SingleTagRegex(name) :: ls if !inCodeBlock => + case SingleTagRegex(name: String) :: ls if !inCodeBlock => val key = SimpleTagKey(name) val value = "" :: tags.getOrElse(key, Nil) go(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala index 312d30a6ca19..d8cf57c2f1b9 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SnippetRenderer.scala @@ -44,7 +44,7 @@ object SnippetRenderer: private def wrapImportedSection(snippetLines: Seq[SnippetLine]): Seq[SnippetLine] = val mRes = cutBetweenSymbols(importedStartSymbol, importedEndSymbol, snippetLines) { case (begin, mid, end) => - val name = importedRegex.findFirstMatchIn(mid.head.content).fold("")(_.group(1)) + val name = importedRegex.findFirstMatchIn(mid.head.content).fold("")(_.group(1)).nn begin ++ mid.drop(1).dropRight(1).map(_.withClass("hideable").withClass("include").withAttribute("name", name)) ++ wrapImportedSection(end) } mRes.getOrElse(snippetLines) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Entities.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Entities.scala index 86e7298226ea..229fb2840d33 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Entities.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Entities.scala @@ -85,7 +85,7 @@ object RepresentationLink { final case class HtmlTag(data: String) extends Inline { private val Pattern = """(?ms)\A<(/?)(.*?)[\s>].*\z""".r private val (isEnd, tagName) = data match { - case Pattern(s1, s2) => + case Pattern(s1: String, s2: String) => (! s1.isEmpty, Some(s2.toLowerCase)) case _ => (false, None) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala index 125bca102fba..f1d628ca8929 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala @@ -429,7 +429,7 @@ final class Parser( val CLOSE_TAG = "^$".r private def readHTMLFrom(begin: HtmlTag): String = { val list = mutable.ListBuffer.empty[String] - val stack = mutable.ListBuffer.empty[String] + val stack = mutable.ListBuffer.empty[String | Null] begin.close match { case Some(HtmlTag(CLOSE_TAG(s))) => diff --git a/scaladoc/src/dotty/tools/scaladoc/util/escape.scala b/scaladoc/src/dotty/tools/scaladoc/util/escape.scala index 5d4bf02e8b38..129b62720fb1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/util/escape.scala +++ b/scaladoc/src/dotty/tools/scaladoc/util/escape.scala @@ -1,10 +1,10 @@ package dotty.tools.scaladoc.util object Escape: - def escapeUrl(url: String) = url + def escapeUrl(url: String): String = url .replace("#","%23") - def escapeFilename(filename: String) = + def escapeFilename(filename: String): String = // from compiler/src/dotty/tools/dotc/util/NameTransformer.scala val escaped = filename .replace("~", "$tilde") From 183af31c4d0d487b64c246f1eb52c6795aa1e40c Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 30 Sep 2025 14:28:29 +0200 Subject: [PATCH 29/46] Re-enable explicit nulls in compiler --- compiler/src/dotty/tools/MainGenericCompiler.scala | 4 ++-- compiler/src/dotty/tools/MainGenericRunner.scala | 2 +- compiler/src/dotty/tools/dotc/core/Comments.scala | 2 +- compiler/src/dotty/tools/dotc/reporting/messages.scala | 2 +- compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala | 2 +- .../dotty/tools/dotc/transform/localopt/FormatChecker.scala | 4 +++- compiler/src/dotty/tools/repl/ParseResult.scala | 2 +- compiler/src/dotty/tools/scripting/Main.scala | 4 ++-- compiler/src/dotty/tools/scripting/StringDriver.scala | 2 +- library/src/scala/Predef.scala | 2 +- project/Build.scala | 4 ++-- 11 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/src/dotty/tools/MainGenericCompiler.scala b/compiler/src/dotty/tools/MainGenericCompiler.scala index 98bd9078c397..ad522a9f6810 100644 --- a/compiler/src/dotty/tools/MainGenericCompiler.scala +++ b/compiler/src/dotty/tools/MainGenericCompiler.scala @@ -131,9 +131,9 @@ object MainGenericCompiler { val tStopAtLvl="-XX:TieredStopAtLevel=1" println(s"ignoring deprecated -Oshort flag, please add `-J$addTC` and `-J$tStopAtLvl` flags manually") process(tail, settings) - case javaOption(stripped) :: tail => + case javaOption(stripped: String) :: tail => process(tail, settings.withJavaArgs(stripped)) - case javaPropOption(opt, value) :: tail => + case javaPropOption(opt: String, value: String) :: tail => process(tail, settings.withJavaProps(opt -> value)) case arg :: tail => process(tail, settings.withResidualArgs(arg)) diff --git a/compiler/src/dotty/tools/MainGenericRunner.scala b/compiler/src/dotty/tools/MainGenericRunner.scala index 9ff96f812bca..3f645ea803a4 100644 --- a/compiler/src/dotty/tools/MainGenericRunner.scala +++ b/compiler/src/dotty/tools/MainGenericRunner.scala @@ -143,7 +143,7 @@ object MainGenericRunner { processArgs(tail, settings.noSave) case "-with-compiler" :: tail => processArgs(tail, settings.withCompiler) - case (o @ javaOption(striped)) :: tail => + case (o @ javaOption(striped: String)) :: tail => processArgs(tail, settings.withJavaArgs(striped).withScalaArgs(o)) case (o @ scalaOption(_*)) :: tail => val remainingArgs = CommandLineParser.expandArg(o) ++ tail diff --git a/compiler/src/dotty/tools/dotc/core/Comments.scala b/compiler/src/dotty/tools/dotc/core/Comments.scala index cafe09673684..b742e3cf8f32 100644 --- a/compiler/src/dotty/tools/dotc/core/Comments.scala +++ b/compiler/src/dotty/tools/dotc/core/Comments.scala @@ -404,7 +404,7 @@ object Comments { val raw = ctx.docCtx.flatMap(_.docstring(sym).map(_.raw)).getOrElse("") defs(sym) ++= defines(raw).map { str => val start = skipWhitespace(str, "@define".length) - val (key, Trim(value)) = str.splitAt(skipVariable(str, start)): @unchecked + val (key, Trim(value: String)) = str.splitAt(skipVariable(str, start)): @unchecked variableName(key.drop(start)) -> value.replaceAll("\\s+\\*+$", "") } } diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 9c4ee9926bf2..efbe9c405d26 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -3000,7 +3000,7 @@ class MissingImplicitArgument( val idx = paramNames.indexOf(name) if (idx >= 0) Some(i"${args(idx)}") else None """\$\{\s*([^}\s]+)\s*\}""".r.replaceAllIn(raw, (_: Regex.Match) match - case Regex.Groups(v) => quoteReplacement(translate(v).getOrElse("?" + v)).nn + case Regex.Groups(v: String) => quoteReplacement(translate(v).getOrElse("?" + v)).nn ) /** @param rawMsg Message template with variables, e.g. "Variable A is ${A}" diff --git a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala index 3d81408e8482..6ef42b6f9775 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala @@ -382,7 +382,7 @@ object Scala3: object LocalSymbol: def unapply(symbolInfo: SymbolInformation): Option[Int] = symbolInfo.symbol match - case locals(ints) => + case locals(ints: String) => val bi = BigInt(ints) if bi.isValidInt then Some(bi.toInt) diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala index 83ec7fb8399e..4184407d07a8 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala @@ -126,7 +126,9 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List def at(g: SpecGroup): Int = descriptor.start(g.ordinal) def end(g: SpecGroup): Int = descriptor.end(g.ordinal) def offset(g: SpecGroup, i: Int = 0): Int = at(g) + i - def group(g: SpecGroup): Option[String] = Option(descriptor.group(g.ordinal)) + def group(g: SpecGroup): Option[String] = + // Unable to use @experimental fromNullable now + Option(descriptor.group(g.ordinal)).asInstanceOf[Option[String]] def stringOf(g: SpecGroup): String = group(g).getOrElse("") def intOf(g: SpecGroup): Option[Int] = group(g).map(_.toInt) diff --git a/compiler/src/dotty/tools/repl/ParseResult.scala b/compiler/src/dotty/tools/repl/ParseResult.scala index 2b7740152fa4..24aa07c707a7 100644 --- a/compiler/src/dotty/tools/repl/ParseResult.scala +++ b/compiler/src/dotty/tools/repl/ParseResult.scala @@ -180,7 +180,7 @@ object ParseResult { val sourceCode = source.content().mkString sourceCode match { case "" => Newline - case CommandExtract(cmd, arg) => { + case CommandExtract(cmd: String, arg: String) => { val matchingCommands = commands.filter((command, _) => command.startsWith(cmd)) matchingCommands match { case Nil => UnknownCommand(cmd) diff --git a/compiler/src/dotty/tools/scripting/Main.scala b/compiler/src/dotty/tools/scripting/Main.scala index 16e2fe35e6f1..daf69e8384a9 100755 --- a/compiler/src/dotty/tools/scripting/Main.scala +++ b/compiler/src/dotty/tools/scripting/Main.scala @@ -78,7 +78,7 @@ object Main: writer.close() end writeJarfile - def pathsep = sys.props("path.separator") + def pathsep: String = sys.props("path.separator").nn extension(path: String) { // Normalize path separator, convert relative path to absolute @@ -102,4 +102,4 @@ object Main: def secondChar: String = path.take(2).drop(1).mkString("") } - lazy val userDir = sys.props("user.dir").norm + lazy val userDir: String = sys.props("user.dir").nn.norm diff --git a/compiler/src/dotty/tools/scripting/StringDriver.scala b/compiler/src/dotty/tools/scripting/StringDriver.scala index 6d4fac719be2..222c2c1dd357 100755 --- a/compiler/src/dotty/tools/scripting/StringDriver.scala +++ b/compiler/src/dotty/tools/scripting/StringDriver.scala @@ -31,7 +31,7 @@ class StringDriver(compilerArgs: Array[String], scalaSource: String) extends Dri try val classpath = s"${ctx.settings.classpath.value}${pathsep}${sys.props("java.class.path")}" val classpathEntries: Seq[Path] = ClassPath.expandPath(classpath, expandStar=true).map { Paths.get(_) } - sys.props("java.class.path") = classpathEntries.map(_.toString).mkString(pathsep) + sys.props("java.class.path") = classpathEntries.map(_.toString).mkString(pathsep.nn) detectMainClassAndMethod(outDir, classpathEntries, scalaSource) match case Right((mainClass, mainMethod)) => mainMethod.invoke(null, Array.empty[String]) diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index 6b4c0523c8a9..d256f850a90b 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -517,7 +517,7 @@ object Predef extends LowPriorityImplicits { @inline implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps(xs) @inline implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps(xs) @inline implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps(xs) - @inline implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps(xs) + @inline implicit def refArrayOps[T <: AnyRef | Null](xs: Array[T]): ArrayOps[T] = new ArrayOps(xs) @inline implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps(xs) @inline implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps(xs) diff --git a/project/Build.scala b/project/Build.scala index 6512e63d6a43..c4c2a3dcb74a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -2338,7 +2338,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"), // TODO: Enable these flags when the new stdlib is explicitelly null checked - //Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), + Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), // Make sure that the produced artifacts have the minimum JVM version in the bytecode Compile / javacOptions ++= Seq("--release", Versions.minimumJVMVersion), Compile / scalacOptions ++= Seq("--java-output-version", Versions.minimumJVMVersion), @@ -2512,7 +2512,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"), // TODO: Enable these flags when the new stdlib is explicitelly null checked - //Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), + Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), // Make sure that the produced artifacts have the minimum JVM version in the bytecode Compile / javacOptions ++= Seq("--release", Versions.minimumJVMVersion), Compile / scalacOptions ++= Seq("--java-output-version", Versions.minimumJVMVersion), From 87e29c9f0300a0f3697c8a70cc003d4a6c0fd2a1 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 30 Sep 2025 14:51:29 +0200 Subject: [PATCH 30/46] Update test code --- .../test/dotty/tools/debug/DebugStepAssert.scala | 12 ++++++------ .../tools/dotc/profile/TraceNameManglingTest.scala | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/test/dotty/tools/debug/DebugStepAssert.scala b/compiler/test/dotty/tools/debug/DebugStepAssert.scala index f3c3d8af405f..bc9d67d7d3f5 100644 --- a/compiler/test/dotty/tools/debug/DebugStepAssert.scala +++ b/compiler/test/dotty/tools/debug/DebugStepAssert.scala @@ -49,17 +49,17 @@ private[debug] object DebugStepAssert: given location: CheckFileLocation = CheckFileLocation(checkFile, allLines.size - lines.size + 1) lines match case Nil => acc.reverse - case break(className , lineStr) :: tail => + case break(className: String, lineStr: String) :: tail => val breakpointLine = lineStr.toInt val step = DebugStepAssert(Break(className, breakpointLine), checkClassAndLine(className, breakpointLine)) loop(tail, step :: acc) - case step(pattern) :: tail => + case step(pattern: String) :: tail => val step = DebugStepAssert(Step, checkLineOrMethod(pattern)) loop(tail, step :: acc) - case next(pattern) :: tail => + case next(pattern: String) :: tail => val step = DebugStepAssert(Next, checkLineOrMethod(pattern)) loop(tail, step :: acc) - case eval(expr) :: tail0 => + case eval(expr: String) :: tail0 => val (assertion, tail1) = parseEvalAssertion(tail0) val step = DebugStepAssert(Eval(expr), assertion) loop(tail1, step :: acc) @@ -78,8 +78,8 @@ private[debug] object DebugStepAssert: lines match case Nil => throw new Exception(s"Missing result or error") case trailing() :: tail => parseEvalAssertion(tail) - case result(expected) :: tail => (checkResult(expected), tail) - case error(expected) :: tail => (checkError(Seq(expected)), tail) + case result(expected: String) :: tail => (checkResult(expected), tail) + case error(expected: String) :: tail => (checkError(Seq(expected)), tail) case multiLineError() :: tail0 => val (expected, tail1) = tail0.span(_.startsWith(" ")) (checkError(expected.map(_.stripPrefix(" "))), tail1) diff --git a/compiler/test/dotty/tools/dotc/profile/TraceNameManglingTest.scala b/compiler/test/dotty/tools/dotc/profile/TraceNameManglingTest.scala index f1f570cc85d4..30915682cd16 100644 --- a/compiler/test/dotty/tools/dotc/profile/TraceNameManglingTest.scala +++ b/compiler/test/dotty/tools/dotc/profile/TraceNameManglingTest.scala @@ -27,7 +27,7 @@ class TraceNameManglingTest extends DottyTest { } @Test def escapeBackslashes(): Unit = { - val isWindows = sys.props("os.name").toLowerCase(Locale.ROOT).nn.contains("windows") + val isWindows = sys.props("os.name").nn.toLowerCase(Locale.ROOT).nn.contains("windows") // It is not possible to create a file with backslash in name on Windows val filename = if isWindows then "test.scala" else "\\.scala" checkTraceEvents( From 926393d6d5148f146f50e846b607a4c98f2ceba1 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 30 Sep 2025 15:17:53 +0200 Subject: [PATCH 31/46] Use hack to compile scala3-library for now --- library/src/scala/IArray.scala | 5 ++++- project/Build.scala | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 23b0035a2299..cab175ecb002 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -353,13 +353,16 @@ object IArray: * keep this signature to discourage passing nulls implicitly while preserving the * previous behavior for backward compatibility. */ + // TODO!!! only for stdliib migration! + import scala.language.unsafeNulls 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. + // import scala.language.unsafeNulls mapNull(arr, if (arr.length == 0) ArraySeq.empty[AnyRef | Null].asInstanceOf[ArraySeq.ofRef[T]] - else ArraySeq.ofRef(arr.asInstanceOf[Array[T]]) + else ArraySeq.ofRef[AnyRef](arr.asInstanceOf[Array[AnyRef]]).asInstanceOf[ArraySeq.ofRef[T]] ) /** Conversion from IArray to immutable.ArraySeq. diff --git a/project/Build.scala b/project/Build.scala index c4c2a3dcb74a..4cf7bbb592df 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -241,7 +241,7 @@ object Build { "-deprecation", "-unchecked", //"-Wconf:cat=deprecation&msg=Unsafe:s", // example usage - "-Werror", + // "-Werror", //"-Wunused:all", //"-rewrite", // requires -Werror:false since no rewrites are applied with errors "-encoding", "UTF8", From c3ba233a7e83d8d1ee9061fb70e8fa3daf2a31c1 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Wed, 1 Oct 2025 00:41:34 +0200 Subject: [PATCH 32/46] Add comments --- .../src/scala/runtime/ScalaRunTime.scala | 9 +- library/src/scala/IArray.scala | 96 ++++--------------- library/src/scala/StringContext.scala | 7 +- .../src/scala/collection/JavaConverters.scala | 1 + .../collection/convert/AsJavaConverters.scala | 5 + .../convert/AsScalaConverters.scala | 5 + 6 files changed, 39 insertions(+), 84 deletions(-) diff --git a/library-js/src/scala/runtime/ScalaRunTime.scala b/library-js/src/scala/runtime/ScalaRunTime.scala index 716b466cb8e3..d63a8e5b61ce 100644 --- a/library-js/src/scala/runtime/ScalaRunTime.scala +++ b/library-js/src/scala/runtime/ScalaRunTime.scala @@ -254,10 +254,17 @@ object ScalaRunTime { case s => s + "\n" } - // For backwards compatibility with code compiled without -Yexplicit-nulls + // For backward compatibility with code compiled without -Yexplicit-nulls. + // If `a` is null, return null; otherwise, return `f`. + // Have to add a private mapNull here to avoid errors private inline def mapNull[A, B](a: A, inline f: B): B = if((a: A | Null) == null) null.asInstanceOf[B] else f + // For the following functions, both the parameter and the return type are non-nullable. + // However, if a null reference is passed explicitly, this method will still return null. + // We intentionally keep this signature to discourage passing nulls implicitly while + // preserving the previous behavior for backward compatibility. + // Convert arrays to immutable.ArraySeq for use with Java varargs: def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = mapNull(xs, ArraySeq.unsafeWrapArray(xs)) diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index cab175ecb002..bb89926c55ac 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -336,25 +336,17 @@ object IArray: private inline def mapNull[A, B](a: A, inline f: B): B = if((a: A | Null) == null) null.asInstanceOf[B] else f - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + // For the following functions, both the parameter and the return type are non-nullable. + // However, if a null reference is passed explicitly, this method will still return null. + // We intentionally keep this signature to discourage passing nulls implicitly while + // preserving the previous behavior for backward compatibility. + + /** Conversion from IArray to immutable.ArraySeq */ implicit def genericWrapArray[T](arr: IArray[T]): ArraySeq[T] = mapNull(arr, ArraySeq.unsafeWrapArray(arr)) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ - // TODO!!! only for stdliib migration! - import scala.language.unsafeNulls + /** Conversion from IArray to immutable.ArraySeq */ + import scala.language.unsafeNulls // TODO!!! only for stdliib migration! 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 @@ -365,93 +357,39 @@ object IArray: else ArraySeq.ofRef[AnyRef](arr.asInstanceOf[Array[AnyRef]]).asInstanceOf[ArraySeq.ofRef[T]] ) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapIntArray(arr: IArray[Int]): ArraySeq.ofInt = mapNull(arr, new ArraySeq.ofInt(arr.asInstanceOf[Array[Int]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapDoubleIArray(arr: IArray[Double]): ArraySeq.ofDouble = mapNull(arr, new ArraySeq.ofDouble(arr.asInstanceOf[Array[Double]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapLongIArray(arr: IArray[Long]): ArraySeq.ofLong = mapNull(arr, new ArraySeq.ofLong(arr.asInstanceOf[Array[Long]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapFloatIArray(arr: IArray[Float]): ArraySeq.ofFloat = mapNull(arr, new ArraySeq.ofFloat(arr.asInstanceOf[Array[Float]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapCharIArray(arr: IArray[Char]): ArraySeq.ofChar = mapNull(arr, new ArraySeq.ofChar(arr.asInstanceOf[Array[Char]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapByteIArray(arr: IArray[Byte]): ArraySeq.ofByte = mapNull(arr, new ArraySeq.ofByte(arr.asInstanceOf[Array[Byte]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapShortIArray(arr: IArray[Short]): ArraySeq.ofShort = mapNull(arr, new ArraySeq.ofShort(arr.asInstanceOf[Array[Short]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapBooleanIArray(arr: IArray[Boolean]): ArraySeq.ofBoolean = mapNull(arr, new ArraySeq.ofBoolean(arr.asInstanceOf[Array[Boolean]])) - /** Conversion from IArray to immutable.ArraySeq. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. - */ + /** Conversion from IArray to immutable.ArraySeq */ implicit def wrapUnitIArray(arr: IArray[Unit]): ArraySeq.ofUnit = mapNull(arr, new ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]])) diff --git a/library/src/scala/StringContext.scala b/library/src/scala/StringContext.scala index 6f891fb2ffd2..ab07a50d6e01 100644 --- a/library/src/scala/StringContext.scala +++ b/library/src/scala/StringContext.scala @@ -95,7 +95,7 @@ case class StringContext(parts: String*) { object s { /** The simple string matcher. * - * Attempts to match the input string to the given interpolated patterns via + * Attempts to match the input string to the given interpolated patterns via * a naive globbing, that is the reverse of the simple interpolator. * * Here is an example usage: @@ -206,7 +206,7 @@ object StringContext { * separated by wildcards * @param input The input you wish to match against * @return None if there is no match, Some containing the sequence of matched - * wildcard strings if there is a match + * wildcard strings if there is a match */ def glob(patternChunks: Seq[String], input: String): Option[Seq[String]] = { var patternIndex = 0 @@ -317,7 +317,7 @@ object StringContext { val len = src.length() def loop(uindex: Int): (Char, Int) = { def loopCP(dindex: Int, codepoint: Int): (Char, Int) = { - //supports BMP + surrogate escapes + //supports BMP + surrogate escapes //but only in four hex-digit code units (uxxxx) if(dindex >= 4) { val usRead = uindex - startindex @@ -475,4 +475,3 @@ object StringContext { +") for interpolated string with "+ parts.length +" parts") } - diff --git a/library/src/scala/collection/JavaConverters.scala b/library/src/scala/collection/JavaConverters.scala index 15efa3e12f54..8d1503200188 100644 --- a/library/src/scala/collection/JavaConverters.scala +++ b/library/src/scala/collection/JavaConverters.scala @@ -110,6 +110,7 @@ object JavaConverters extends AsJavaConverters with AsScalaConverters { @deprecated("Use `asJava` instead", "2.13.0") def mapAsJavaConcurrentMap[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = asJava(m) + @deprecated("Use `asScala` instead", "2.13.0") def asScalaIterator[A](i: ju.Iterator[A]): Iterator[A] = asScala(i) diff --git a/library/src/scala/collection/convert/AsJavaConverters.scala b/library/src/scala/collection/convert/AsJavaConverters.scala index b84d746ac89c..9eb5c691dd8f 100644 --- a/library/src/scala/collection/convert/AsJavaConverters.scala +++ b/library/src/scala/collection/convert/AsJavaConverters.scala @@ -24,6 +24,11 @@ import scala.{unchecked => uc} /** Defines converter methods from Scala to Java collections. * These methods are available through the [[scala.jdk.javaapi.CollectionConverters]] object. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. */ trait AsJavaConverters { import JavaCollectionWrappers._ diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index ec55a242f303..63cf70379f60 100644 --- a/library/src/scala/collection/convert/AsScalaConverters.scala +++ b/library/src/scala/collection/convert/AsScalaConverters.scala @@ -25,6 +25,11 @@ import scala.{unchecked => uc} /** Defines converter methods from Java to Scala collections. * These methods are available through the [[scala.jdk.javaapi.CollectionConverters]] object. + * + * Note: Both the parameter and the return type are non-nullable. However, if a null + * reference is passed explicitly, this method will still return null. We intentionally + * keep this signature to discourage passing nulls implicitly while preserving the + * previous behavior for backward compatibility. */ trait AsScalaConverters { import JavaCollectionWrappers._ From aff2542462c7d26ac8eba30fba55187249df5bf4 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Wed, 1 Oct 2025 02:14:09 +0200 Subject: [PATCH 33/46] Address review comments; avoid inferred flexible types --- library/src/scala/MatchError.scala | 4 +-- library/src/scala/collection/SeqView.scala | 10 +++--- library/src/scala/collection/StringOps.scala | 4 +-- .../scala/collection/concurrent/TrieMap.scala | 28 +++++++-------- .../collection/convert/AsJavaConverters.scala | 26 +++++++------- .../convert/AsScalaConverters.scala | 20 +++++------ .../convert/JavaCollectionWrappers.scala | 35 +++++++++---------- .../scala/collection/immutable/Stream.scala | 4 +-- .../scala/collection/mutable/HashMap.scala | 7 ++-- .../impl/ExecutionContextImpl.scala | 1 + library/src/scala/io/Codec.scala | 4 +-- library/src/scala/jdk/FunctionWrappers.scala | 18 +++++----- library/src/scala/math/BigDecimal.scala | 2 +- library/src/scala/sys/process/BasicIO.scala | 2 +- library/src/scala/sys/process/package.scala | 6 ++-- library/src/scala/util/Properties.scala | 26 +++++++------- library/src/scala/util/matching/Regex.scala | 2 +- 17 files changed, 101 insertions(+), 98 deletions(-) diff --git a/library/src/scala/MatchError.scala b/library/src/scala/MatchError.scala index 7e6bcc480d8c..2053d2cc6f9c 100644 --- a/library/src/scala/MatchError.scala +++ b/library/src/scala/MatchError.scala @@ -22,7 +22,7 @@ final class MatchError(@transient obj: Any) extends RuntimeException { /** There's no reason we need to call toString eagerly, * so defer it until getMessage is called or object is serialized */ - private[this] lazy val objString = { + private[this] lazy val objString: String = { def ofClass = "of class " + obj.getClass.getName if (obj == null) "null" else @@ -38,5 +38,5 @@ final class MatchError(@transient obj: Any) extends RuntimeException { this } - override def getMessage() = objString + override def getMessage(): String = objString } diff --git a/library/src/scala/collection/SeqView.scala b/library/src/scala/collection/SeqView.scala index 7269982227f0..cd2cc1637eaf 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: SomeSeqOps[A]^{underlying_} | Null = underlying_ + private var underlying = 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.nn.head) + else if (len == 1) List(underlying.head) else { val arr = new Array[Any](len) // Array[Any] =:= Array[AnyRef] - @annotation.unused val copied = underlying.nn.copyToArray(arr) + @annotation.unused val copied = underlying.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 @@ -187,12 +187,12 @@ object SeqView { } } evaluated = true - underlying = null + underlying = nullForGC[SomeSeqOps[A]] // allow GC of unneeded reference res } private[this] def elems: SomeSeqOps[A]^{this} = { - if (evaluated) _sorted else underlying.nn + if (evaluated) _sorted else underlying } def apply(i: Int): A = _sorted.apply(i) diff --git a/library/src/scala/collection/StringOps.scala b/library/src/scala/collection/StringOps.scala index 17800cb1d98b..ffc69210d1c0 100644 --- a/library/src/scala/collection/StringOps.scala +++ b/library/src/scala/collection/StringOps.scala @@ -731,14 +731,14 @@ final class StringOps(private val s: String) extends AnyVal { self => /** Returns this string with the given `prefix` stripped. If this string does not * start with `prefix`, it is returned unchanged. */ - def stripPrefix(prefix: String) = + def stripPrefix(prefix: String): String = if (s startsWith prefix) s.substring(prefix.length) else s /** Returns this string with the given `suffix` stripped. If this string does not * end with `suffix`, it is returned unchanged. */ - def stripSuffix(suffix: String) = + def stripSuffix(suffix: String): String = if (s endsWith suffix) s.substring(0, s.length - suffix.length) else s diff --git a/library/src/scala/collection/concurrent/TrieMap.scala b/library/src/scala/collection/concurrent/TrieMap.scala index f44e7c869cd7..875ba45c9f49 100644 --- a/library/src/scala/collection/concurrent/TrieMap.scala +++ b/library/src/scala/collection/concurrent/TrieMap.scala @@ -410,7 +410,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e GCAS_READ(ct).nn.knownSize() /* this is a quiescent method! */ - def string(lev: Int) = "%sINode -> %s".format(" " * lev, mainnode match { + def string(lev: Int): String = "%sINode -> %s".format(" " * lev, mainnode match { case null => "" case tn: TNode[_, _] => "TNode(%s, %s, %d, !)".format(tn.k, tn.v, tn.hc) case cn: CNode[_, _] => cn.string(lev) @@ -446,7 +446,7 @@ private[concurrent] final class FailedNode[K, V](p: MainNode[K, V]) extends Main def knownSize: Int = throw new UnsupportedOperationException - override def toString = "FailedNode(%s)".format(p) + override def toString: String = "FailedNode(%s)".format(p) } @@ -461,7 +461,7 @@ private[collection] final class SNode[K, V](final val k: K, final val v: V, fina def copyTombed = new TNode(k, v, hc) def copyUntombed = new SNode(k, v, hc) def kvPair = (k, v) - def string(lev: Int) = (" " * lev) + "SNode(%s, %s, %x)".format(k, v, hc) + def string(lev: Int): String = (" " * lev) + "SNode(%s, %s, %x)".format(k, v, hc) } // Tomb Node, used to ensure proper ordering during removals @@ -473,7 +473,7 @@ private[collection] final class TNode[K, V](final val k: K, final val v: V, fina def kvPair = (k, v) def cachedSize(ct: AnyRef): Int = 1 def knownSize: Int = 1 - def string(lev: Int) = (" " * lev) + "TNode(%s, %s, %x, !)".format(k, v, hc) + def string(lev: Int): String = (" " * lev) + "TNode(%s, %s, %x, !)".format(k, v, hc) } // List Node, leaf node that handles hash collisions @@ -514,7 +514,7 @@ private[collection] final class LNode[K, V](val entries: List[(K, V)], equiv: Eq def knownSize: Int = -1 // shouldn't ever be empty, and the size of a list is not known - def string(lev: Int) = (" " * lev) + "LNode(%s)".format(entries.mkString(", ")) + def string(lev: Int): String = (" " * lev) + "LNode(%s)".format(entries.mkString(", ")) } @@ -839,7 +839,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater } - def string = RDCSS_READ_ROOT().string(0) + def string: String = RDCSS_READ_ROOT().string(0) /* public methods */ @@ -1082,17 +1082,17 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: def hasNext = (current ne null) || (subiter ne null) - def next() = if (hasNext) { - var r: (K, V) | Null = null + def next(): (K, V) = { if (subiter ne null) { - r = subiter.next() + val r = subiter.next() checkSubiter() - } else { - r = current.nn.kvPair + r + } else if (current ne null) { + val r = current.kvPair advance() - } - r - } else Iterator.empty.next() + r + } else Iterator.empty.next() + } private def readin(in: INode[K, V]) = in.gcasRead(ct) match { case cn: CNode[K, V] => diff --git a/library/src/scala/collection/convert/AsJavaConverters.scala b/library/src/scala/collection/convert/AsJavaConverters.scala index 9eb5c691dd8f..cabb1fbdf61a 100644 --- a/library/src/scala/collection/convert/AsJavaConverters.scala +++ b/library/src/scala/collection/convert/AsJavaConverters.scala @@ -45,7 +45,7 @@ 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]): ju.Iterator[A] = (i: Iterator[A] | Null) match { case null => null.asInstanceOf[ju.Iterator[A]] case wrapper: JIteratorWrapper[A @uc] => wrapper.underlying case _ => new IteratorWrapper(i) @@ -63,7 +63,7 @@ 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]): ju.Enumeration[A] = (i: Iterator[A] | Null) match { case null => null.asInstanceOf[ju.Enumeration[A]] case wrapper: JEnumerationWrapper[A @uc] => wrapper.underlying case _ => new IteratorWrapper(i) @@ -81,7 +81,7 @@ 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]): jl.Iterable[A] = (i: Iterable[A] | Null) match { case null => null.asInstanceOf[jl.Iterable[A]] case wrapper: JIterableWrapper[A @uc] => wrapper.underlying case _ => new IterableWrapper(i) @@ -96,7 +96,7 @@ 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]): ju.Collection[A] = (i: Iterable[A] | Null) match { case null => null.asInstanceOf[ju.Collection[A]] case wrapper: JCollectionWrapper[A @uc] => wrapper.underlying case _ => new IterableWrapper(i) @@ -114,7 +114,7 @@ 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]): ju.List[A] = (b: mutable.Buffer[A] | Null) match { case null => null.asInstanceOf[ju.List[A]] case wrapper: JListWrapper[A @uc] => wrapper.underlying case _ => new MutableBufferWrapper(b) @@ -132,7 +132,7 @@ 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]): ju.List[A] = (s: mutable.Seq[A] | Null) match { case null => null.asInstanceOf[ju.List[A]] case wrapper: JListWrapper[A @uc] => wrapper.underlying case _ => new MutableSeqWrapper(s) @@ -150,7 +150,7 @@ 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]): ju.List[A] = (s: Seq[A] | Null) match { case null => null.asInstanceOf[ju.List[A]] case wrapper: JListWrapper[A @uc] => wrapper.underlying case _ => new SeqWrapper(s) @@ -168,7 +168,7 @@ 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]): ju.Set[A] = (s: mutable.Set[A] | Null) match { case null => null.asInstanceOf[ju.Set[A]] case wrapper: JSetWrapper[A @uc] => wrapper.underlying case _ => new MutableSetWrapper(s) @@ -186,7 +186,7 @@ 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]): ju.Set[A] = (s: Set[A] | Null) match { case null => null.asInstanceOf[ju.Set[A]] case wrapper: JSetWrapper[A @uc] => wrapper.underlying case _ => new SetWrapper(s) @@ -204,7 +204,7 @@ 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]): ju.Map[K, V] = (m: mutable.Map[K, V] | Null) match { case null => null.asInstanceOf[ju.Map[K, V]] case wrapper: JMapWrapper[K @uc, V @uc] => wrapper.underlying case _ => new MutableMapWrapper(m) @@ -223,7 +223,7 @@ 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]): ju.Dictionary[K, V] = (m: mutable.Map[K, V] | Null) match { case null => null.asInstanceOf[ju.Dictionary[K, V]] case wrapper: JDictionaryWrapper[K @uc, V @uc] => wrapper.underlying case _ => new DictionaryWrapper(m) @@ -241,7 +241,7 @@ 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]): ju.Map[K, V] = (m: Map[K, V] | Null) match { case null => null.asInstanceOf[ju.Map[K, V]] case wrapper: JMapWrapper[K @uc, V @uc] => wrapper.underlying case _ => new MapWrapper(m) @@ -260,7 +260,7 @@ 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]): juc.ConcurrentMap[K, V] = (m: concurrent.Map[K, V] | Null) match { case null => null.asInstanceOf[juc.ConcurrentMap[K, V]] case wrapper: JConcurrentMapWrapper[K @uc, V @uc] => wrapper.underlying case _ => new ConcurrentMapWrapper(m) diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index 63cf70379f60..1925af791b6b 100644 --- a/library/src/scala/collection/convert/AsScalaConverters.scala +++ b/library/src/scala/collection/convert/AsScalaConverters.scala @@ -46,7 +46,7 @@ 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]): Iterator[A] = (i: ju.Iterator[A] | Null) match { case null => null.asInstanceOf[Iterator[A]] case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JIteratorWrapper(i) @@ -64,7 +64,7 @@ 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]): Iterator[A] = (e: ju.Enumeration[A] | Null) match { case null => null.asInstanceOf[Iterator[A]] case wrapper: IteratorWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JEnumerationWrapper(e) @@ -82,7 +82,7 @@ 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]): Iterable[A] = (i: jl.Iterable[A] | Null) match { case null => null.asInstanceOf[Iterable[A]] case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JIterableWrapper(i) @@ -97,7 +97,7 @@ 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]): Iterable[A] = (c: ju.Collection[A] | Null) match { case null => null.asInstanceOf[Iterable[A]] case wrapper: IterableWrapper[A @uc] => wrapper.underlying.unsafeAssumePure // TODO: Remove when pattern matching recognizes this is safe case _ => new JCollectionWrapper(c) @@ -115,7 +115,7 @@ 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]): mutable.Buffer[A] = (l: ju.List[A] | Null) match { case null => null.asInstanceOf[mutable.Buffer[A]] case wrapper: MutableBufferWrapper[A @uc] => wrapper.underlying case _ => new JListWrapper(l) @@ -133,7 +133,7 @@ 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]): mutable.Set[A] = (s: ju.Set[A] | Null) match { case null => null.asInstanceOf[mutable.Set[A]] case wrapper: MutableSetWrapper[A @uc] => wrapper.underlying case _ => new JSetWrapper(s) @@ -156,7 +156,7 @@ 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]): mutable.Map[K, V] = (m: ju.Map[K, V] | Null) match { case null => null.asInstanceOf[mutable.Map[K, V]] case wrapper: MutableMapWrapper[K @uc, V @uc] => wrapper.underlying case _ => new JMapWrapper(m) @@ -175,7 +175,7 @@ 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]): concurrent.Map[K, V] = (m: juc.ConcurrentMap[K, V] | Null) match { case null => null.asInstanceOf[concurrent.Map[K, V]] case wrapper: ConcurrentMapWrapper[K @uc, V @uc] => wrapper.underlyingConcurrentMap case _ => new JConcurrentMapWrapper(m) @@ -193,7 +193,7 @@ 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]): mutable.Map[K, V] = (d: ju.Dictionary[K, V] | Null) match { case null => null.asInstanceOf[mutable.Map[K, V]] case wrapper: DictionaryWrapper[K @uc, V @uc] => wrapper.underlying case _ => new JDictionaryWrapper(d) @@ -209,7 +209,7 @@ 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): mutable.Map[String, String] = (p: ju.Properties | Null) match { case null => null.asInstanceOf[mutable.Map[String, String]] case _ => new JPropertiesWrapper(p) } diff --git a/library/src/scala/collection/convert/JavaCollectionWrappers.scala b/library/src/scala/collection/convert/JavaCollectionWrappers.scala index 54dadc6bf772..d131a185c736 100644 --- a/library/src/scala/collection/convert/JavaCollectionWrappers.scala +++ b/library/src/scala/collection/convert/JavaCollectionWrappers.scala @@ -33,9 +33,9 @@ private[collection] object JavaCollectionWrappers extends Serializable { @SerialVersionUID(3L) class IteratorWrapper[A](val underlying: Iterator[A]^) extends ju.Iterator[A] with ju.Enumeration[A] with Serializable { def hasNext = underlying.hasNext - def next() = underlying.next() + def next(): A = underlying.next() def hasMoreElements = underlying.hasNext - def nextElement() = underlying.next() + def nextElement(): A = underlying.next() override def remove(): Nothing = throw new UnsupportedOperationException override def equals(other: Any): Boolean = other match { case that: IteratorWrapper[_] => this.underlying == that.underlying @@ -47,7 +47,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { @SerialVersionUID(3L) class JIteratorWrapper[A](val underlying: ju.Iterator[A]) extends AbstractIterator[A] with Serializable { def hasNext = underlying.hasNext - def next() = underlying.next + def next(): A = underlying.next override def equals(other: Any): Boolean = other match { case that: JIteratorWrapper[_] => this.underlying == that.underlying case _ => false @@ -58,7 +58,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { @SerialVersionUID(3L) class JEnumerationWrapper[A](val underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Serializable { def hasNext = underlying.hasMoreElements - def next() = underlying.nextElement + def next(): A = underlying.nextElement override def equals(other: Any): Boolean = other match { case that: JEnumerationWrapper[_] => this.underlying == that.underlying case _ => false @@ -116,13 +116,13 @@ private[collection] object JavaCollectionWrappers extends Serializable { @SerialVersionUID(3L) class SeqWrapper[A](val underlying: Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] with Serializable { - def get(i: Int) = underlying(i) + def get(i: Int): A = underlying(i) } @SerialVersionUID(3L) class MutableSeqWrapper[A](val underlying: mutable.Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] with Serializable { - def get(i: Int) = underlying(i) - override def set(i: Int, elem: A) = { + def get(i: Int): A = underlying(i) + override def set(i: Int, elem: A): A = { val p = underlying(i) underlying(i) = elem p @@ -131,10 +131,10 @@ private[collection] object JavaCollectionWrappers extends Serializable { @SerialVersionUID(3L) class MutableBufferWrapper[A](val underlying: mutable.Buffer[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] with Serializable { - def get(i: Int) = underlying(i) - override def set(i: Int, elem: A) = { val p = underlying(i); underlying(i) = elem; p } + def get(i: Int): A = underlying(i) + override def set(i: Int, elem: A): A = { val p = underlying(i); underlying(i) = elem; p } override def add(elem: A) = { underlying += elem; true } - override def remove(i: Int) = underlying remove i + override def remove(i: Int): A = underlying remove i } @SerialVersionUID(3L) @@ -148,7 +148,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { override def knownSize: Int = if (underlying.isEmpty) 0 else super.knownSize override def isEmpty = underlying.isEmpty override def iterator: Iterator[A] = underlying.iterator.asScala - def apply(i: Int) = underlying.get(i) + def apply(i: Int): A = underlying.get(i) def update(i: Int, elem: A) = underlying.set(i, elem) def prepend(elem: A) = { underlying.subList(0, 0) add elem; this } def addOne(elem: A): this.type = { underlying add elem; this } @@ -185,7 +185,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { val ui = underlying.iterator var prev: Option[A] = None def hasNext = ui.hasNext - def next = { val e = ui.next(); prev = Some(e); e } + def next: A = { val e = ui.next(); prev = Some(e); e } override def remove() = prev match { case Some(e) => underlying match { @@ -326,7 +326,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { @SerialVersionUID(3L) class MutableMapWrapper[K, V](val underlying: mutable.Map[K, V]) extends MapWrapper[K, V](underlying) { - override def put(k: K, v: V) = underlying.put(k, v) match { + override def put(k: K, v: V): V = underlying.put(k, v) match { case Some(v1) => v1 case None => null.asInstanceOf[V] } @@ -459,7 +459,7 @@ private[collection] object JavaCollectionWrappers extends Serializable { def underlyingConcurrentMap: concurrent.Map[K, V] = underlying - override def putIfAbsent(k: K, v: V) = underlying.putIfAbsent(k, v).getOrElse(null.asInstanceOf[V]) + override def putIfAbsent(k: K, v: V): V = underlying.putIfAbsent(k, v).getOrElse(null.asInstanceOf[V]) override def remove(k: AnyRef, v: AnyRef) = try underlying.remove(k.asInstanceOf[K], v.asInstanceOf[V]) @@ -622,12 +622,11 @@ private[collection] object JavaCollectionWrappers extends Serializable { override def empty: JPropertiesWrapper = new JPropertiesWrapper(new ju.Properties) - def getProperty(key: String) = underlying.getProperty(key) + def getProperty(key: String): String | Null = underlying.getProperty(key) - def getProperty(key: String, defaultValue: String) = - underlying.getProperty(key, defaultValue) + def getProperty(key: String, defaultValue: String): String = underlying.getProperty(key, defaultValue) - def setProperty(key: String, value: String) = + def setProperty(key: String, value: String): AnyRef | Null = underlying.setProperty(key, value) override def mapFactory: mutable.HashMap.type = mutable.HashMap diff --git a/library/src/scala/collection/immutable/Stream.scala b/library/src/scala/collection/immutable/Stream.scala index 352d4d5224c5..859cd29d1697 100644 --- a/library/src/scala/collection/immutable/Stream.scala +++ b/library/src/scala/collection/immutable/Stream.scala @@ -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: 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 + private[this] var s: Stream[A] = l // set to null to allow GC after filtered + private[this] lazy val filtered: Stream[A] = { val f = s.filter(p); s = nullForGC[Stream[A]]; 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/mutable/HashMap.scala b/library/src/scala/collection/mutable/HashMap.scala index cd38ac065c8a..0e3c8e7ce2a5 100644 --- a/library/src/scala/collection/mutable/HashMap.scala +++ b/library/src/scala/collection/mutable/HashMap.scala @@ -149,8 +149,11 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) previousNode = prev foundNode = nd } - else if ((nd.next eq null) || (nd.hash > h)) () - else findNode(nd, nd.next.nn, k, h) + else { + val ndNext = nd.next + if ((ndNext eq null) || (nd.hash > h)) () + else findNode(nd, ndNext, k, h) + } } findNode(null, nd, key, hash) diff --git a/library/src/scala/concurrent/impl/ExecutionContextImpl.scala b/library/src/scala/concurrent/impl/ExecutionContextImpl.scala index 55fc5354940b..54fd2dc4795b 100644 --- a/library/src/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/library/src/scala/concurrent/impl/ExecutionContextImpl.scala @@ -119,6 +119,7 @@ private[concurrent] object ExecutionContextImpl { ExecutionContextExecutorService = es match { case null => createDefaultExecutorService(reporter) case some => + // This is a anonymous class extending a Java class, so we left inferred flexible types in the signatures. new ExecutionContextImpl(some, reporter) with ExecutionContextExecutorService { private[this] final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService] final override def shutdown() = asExecutorService.shutdown() diff --git a/library/src/scala/io/Codec.scala b/library/src/scala/io/Codec.scala index 63fd2735589e..62c875cf2b27 100644 --- a/library/src/scala/io/Codec.scala +++ b/library/src/scala/io/Codec.scala @@ -46,7 +46,7 @@ class Codec(val charSet: Charset) { private[this] var _onCodingException: Handler = e => throw e /** The name of the Codec. */ - override def toString = name + override def toString: String = name // these methods can be chained to configure the variables above def onMalformedInput(newAction: Action): this.type = { _onMalformedInput = newAction ; this } @@ -55,7 +55,7 @@ class Codec(val charSet: Charset) { def encodingReplaceWith(newReplacement: Array[Byte]): this.type = { _encodingReplacement = newReplacement ; this } def onCodingException(handler: Handler): this.type = { _onCodingException = handler ; this } - def name = charSet.name + def name: String = charSet.name def encoder: CharsetEncoder = { val enc = charSet.newEncoder() if (_onMalformedInput ne null) enc onMalformedInput _onMalformedInput diff --git a/library/src/scala/jdk/FunctionWrappers.scala b/library/src/scala/jdk/FunctionWrappers.scala index e146d4b79325..f4137de041cf 100644 --- a/library/src/scala/jdk/FunctionWrappers.scala +++ b/library/src/scala/jdk/FunctionWrappers.scala @@ -57,7 +57,7 @@ object FunctionWrappers { } 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) + def apply(x1: T, x2: U): R = sf.apply(x1, x2) } class RichFunction2AsBiFunction[T, U, R](private val underlying: scala.Function2[T, U, R]) extends AnyVal { @@ -111,7 +111,7 @@ object FunctionWrappers { } 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) + def apply(x1: T, x2: T): T = sf.apply(x1, x2) } class RichFunction2AsBinaryOperator[T](private val underlying: scala.Function2[T, T, T]) extends AnyVal { @@ -234,7 +234,7 @@ object FunctionWrappers { } case class AsJavaDoubleFunction[R](sf: scala.Function1[Double, R]) extends java.util.function.DoubleFunction[R] { - def apply(x1: scala.Double) = sf.apply(x1) + def apply(x1: scala.Double): R = sf.apply(x1) } class RichFunction1AsDoubleFunction[R](private val underlying: scala.Function1[Double, R]) extends AnyVal { @@ -376,7 +376,7 @@ object FunctionWrappers { } case class AsJavaFunction[T, R](sf: scala.Function1[T, R]) extends java.util.function.Function[T, R] { - def apply(x1: T) = sf.apply(x1) + def apply(x1: T): R = sf.apply(x1) } class RichFunction1AsFunction[T, R](private val underlying: scala.Function1[T, R]) extends AnyVal { @@ -449,7 +449,7 @@ object FunctionWrappers { } case class AsJavaIntFunction[R](sf: scala.Function1[Int, R]) extends java.util.function.IntFunction[R] { - def apply(x1: scala.Int) = sf.apply(x1) + def apply(x1: scala.Int): R = sf.apply(x1) } class RichFunction1AsIntFunction[R](private val underlying: scala.Function1[Int, R]) extends AnyVal { @@ -637,7 +637,7 @@ object FunctionWrappers { } case class AsJavaLongFunction[R](sf: scala.Function1[Long, R]) extends java.util.function.LongFunction[R] { - def apply(x1: scala.Long) = sf.apply(x1) + def apply(x1: scala.Long): R = sf.apply(x1) } class RichFunction1AsLongFunction[R](private val underlying: scala.Function1[Long, R]) extends AnyVal { @@ -887,7 +887,7 @@ object FunctionWrappers { } case class AsJavaSupplier[T](sf: scala.Function0[T]) extends java.util.function.Supplier[T] { - def get() = sf.apply() + def get(): T = sf.apply() } class RichFunction0AsSupplier[T](private val underlying: scala.Function0[T]) extends AnyVal { @@ -1065,7 +1065,7 @@ object FunctionWrappers { case class FromJavaUnaryOperator[T](jf: java.util.function.UnaryOperator[T]) extends scala.Function1[T, T] { - def apply(x1: T) = jf.apply(x1) + def apply(x1: T): T = jf.apply(x1) } class RichUnaryOperatorAsFunction1[T](private val underlying: java.util.function.UnaryOperator[T]) extends AnyVal { @@ -1076,7 +1076,7 @@ object FunctionWrappers { } case class AsJavaUnaryOperator[T](sf: scala.Function1[T, T]) extends java.util.function.UnaryOperator[T] { - def apply(x1: T) = sf.apply(x1) + def apply(x1: T): T = sf.apply(x1) } class RichFunction1AsUnaryOperator[T](private val underlying: scala.Function1[T, T]) extends AnyVal { diff --git a/library/src/scala/math/BigDecimal.scala b/library/src/scala/math/BigDecimal.scala index 283d7865f00b..25d5f55a55d9 100644 --- a/library/src/scala/math/BigDecimal.scala +++ b/library/src/scala/math/BigDecimal.scala @@ -29,7 +29,7 @@ object BigDecimal { private final val deci2binary = 3.3219280948873626 // Ratio of log(10) to log(2) private[this] val minCached = -512 private[this] val maxCached = 512 - val defaultMathContext = MathContext.DECIMAL128 + val defaultMathContext: MathContext = MathContext.DECIMAL128 /** Cache only for defaultMathContext using BigDecimals in a small range. */ private[this] lazy val cache = new Array[BigDecimal](maxCached - minCached + 1) diff --git a/library/src/scala/sys/process/BasicIO.scala b/library/src/scala/sys/process/BasicIO.scala index 57710609451d..3a2b99b58c5c 100644 --- a/library/src/scala/sys/process/BasicIO.scala +++ b/library/src/scala/sys/process/BasicIO.scala @@ -37,7 +37,7 @@ object BasicIO { final val BufferSize = 8192 /** Used to separate lines in the `processFully` function that takes `Appendable`. */ - final val Newline = System.lineSeparator + final val Newline: String = System.lineSeparator private[process] final class LazilyListed[T]( val process: T => Unit, diff --git a/library/src/scala/sys/process/package.scala b/library/src/scala/sys/process/package.scala index bf0e534e2284..9314bc176813 100644 --- a/library/src/scala/sys/process/package.scala +++ b/library/src/scala/sys/process/package.scala @@ -211,11 +211,11 @@ import scala.language.`2.13` @annotation.nowarn("msg=package object inheritance") object `package` extends ProcessImplicits { /** The input stream of this process */ - def stdin = java.lang.System.in + def stdin: java.io.InputStream = java.lang.System.in /** The output stream of this process */ - def stdout = java.lang.System.out + def stdout: java.io.PrintStream = java.lang.System.out /** The error stream of this process */ - def stderr = java.lang.System.err + def stderr: java.io.PrintStream = java.lang.System.err } // private val shell: String => Array[String] = // if (isWin) Array("cmd.exe", "/C", _) diff --git a/library/src/scala/util/Properties.scala b/library/src/scala/util/Properties.scala index 50cde5fcff6a..2bc065d5cddf 100644 --- a/library/src/scala/util/Properties.scala +++ b/library/src/scala/util/Properties.scala @@ -52,18 +52,18 @@ private[scala] trait PropertiesTrait { catch { case _: IOException => } } - def propIsSet(name: String) = System.getProperty(name) != null - def propIsSetTo(name: String, value: String) = propOrNull(name) == value - def propOrNone(name: String): Option[String] = Option[String](System.getProperty(name)) - def propOrElse(name: String, alt: => String) = propOrNone(name).getOrElse(alt) - def propOrEmpty(name: String) = propOrElse(name, "") - def propOrNull(name: String): String | Null = propOrNone(name).orNull - def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.toLowerCase) - def setProp(name: String, value: String) = System.setProperty(name, value) - def clearProp(name: String) = System.clearProperty(name) - - def envOrElse(name: String, alt: => String) = Option(System getenv name) getOrElse alt - def envOrNone(name: String) = Option(System getenv name) + def propIsSet(name: String): Boolean = System.getProperty(name) != null + def propIsSetTo(name: String, value: String) = propOrNull(name) == value + def propOrNone(name: String): Option[String] = Option[String](System.getProperty(name)) + def propOrElse(name: String, alt: => String): String = propOrNone(name).getOrElse(alt) + def propOrEmpty(name: String): String = propOrElse(name, "") + def propOrNull(name: String): String | Null = propOrNone(name).orNull + def propOrFalse(name: String): Boolean = propOrNone(name) exists (x => List("yes", "on", "true") contains x.toLowerCase) + def setProp(name: String, value: String): String = System.setProperty(name, value) + def clearProp(name: String): String = System.clearProperty(name) + + def envOrElse(name: String, alt: => String): String = Option(System getenv name) getOrElse alt + def envOrNone(name: String): Option[String] = Option(System getenv name) def envOrSome(name: String, alt: => Option[String]) = envOrNone(name) orElse alt @@ -108,7 +108,7 @@ private[scala] trait PropertiesTrait { /** The default end of line character. */ - def lineSeparator = System.lineSeparator() + def lineSeparator: String = System.lineSeparator() /* Various well-known properties. */ def javaClassPath = propOrEmpty("java.class.path") diff --git a/library/src/scala/util/matching/Regex.scala b/library/src/scala/util/matching/Regex.scala index 17dafbe148b0..826d2ad9b604 100644 --- a/library/src/scala/util/matching/Regex.scala +++ b/library/src/scala/util/matching/Regex.scala @@ -895,7 +895,7 @@ object Regex { } // Appends the input prefix and the replacement text. - def replace(replacement: String) = matcher.appendReplacement(sb, replacement) + def replace(replacement: String): Matcher = matcher.appendReplacement(sb, replacement) } /** Quotes strings to be used literally in regex patterns. From 5452c87f9f1d84e52cdcb52ca38b43ea9dbb8031 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Wed, 1 Oct 2025 15:41:50 +0200 Subject: [PATCH 34/46] Address review comments --- library/src/scala/collection/convert/StreamExtensions.scala | 2 +- library/src/scala/collection/immutable/RedBlackTree.scala | 4 ++-- library/src/scala/collection/mutable/RedBlackTree.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/src/scala/collection/convert/StreamExtensions.scala b/library/src/scala/collection/convert/StreamExtensions.scala index 0865ab6ea0df..ca161d45d83a 100644 --- a/library/src/scala/collection/convert/StreamExtensions.scala +++ b/library/src/scala/collection/convert/StreamExtensions.scala @@ -462,7 +462,7 @@ object StreamExtensions { 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 | Null = null + val companion: AnyRef | Null = AnyAccumulator } implicit val intAccumulatorFactoryInfo: AccumulatorFactoryInfo[Int, IntAccumulator] = new AccumulatorFactoryInfo[Int, IntAccumulator] { diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index d7524b39b0a4..eb55757accb2 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -839,7 +839,7 @@ private[collection] object RedBlackTree { stackOfNexts.nn(index) } - protected[this] val stackOfNexts: Array[Tree[A, B]] | Null = if (root eq null) null else { + protected[this] val stackOfNexts: Array[Tree[A, B] | Null] | Null = if (root eq null) null else { /* * According to "Ralf Hinze. Constructing red-black trees" [https://www.cs.ox.ac.uk/ralf.hinze/publications/#P5] * the maximum height of a red-black tree is 2*log_2(n + 2) - 2. @@ -850,7 +850,7 @@ private[collection] object RedBlackTree { * we potentially do so in `startFrom`. */ val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 - new Array[Tree[A, B]](maximumHeight) + new Array[Tree[A, B] | Null](maximumHeight) } private[this] var index = 0 protected var lookahead: Tree[A, B] | Null = if (start.isDefined) startFrom(start.get) else findLeftMostOrPopOnEmpty(root) diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index a9645431ea5b..a21455eee0ec 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -271,7 +271,7 @@ private[collection] object RedBlackTree { else if (z.right eq null) { x = z.left transplant(tree, z, z.left) - xParent = z.left.parent + xParent = z.parent } else { y = minNodeNonNull(z.right) From c106546c5c44a957adf8f2d811fee6e0f3b61388 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Wed, 1 Oct 2025 17:46:54 +0200 Subject: [PATCH 35/46] Update Option.apply --- .../dotty/tools/dotc/transform/localopt/FormatChecker.scala | 4 +--- library/src/scala/Option.scala | 2 +- library/src/scala/quoted/FromExpr.scala | 2 +- scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala | 4 ++-- scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala | 4 ++-- scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala | 2 +- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala index 4184407d07a8..83ec7fb8399e 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala @@ -126,9 +126,7 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List def at(g: SpecGroup): Int = descriptor.start(g.ordinal) def end(g: SpecGroup): Int = descriptor.end(g.ordinal) def offset(g: SpecGroup, i: Int = 0): Int = at(g) + i - def group(g: SpecGroup): Option[String] = - // Unable to use @experimental fromNullable now - Option(descriptor.group(g.ordinal)).asInstanceOf[Option[String]] + def group(g: SpecGroup): Option[String] = Option(descriptor.group(g.ordinal)) def stringOf(g: SpecGroup): String = group(g).getOrElse("") def intOf(g: SpecGroup): Option[Int] = group(g).map(_.toInt) diff --git a/library/src/scala/Option.scala b/library/src/scala/Option.scala index 894eade2445a..b2eadf2c1be3 100644 --- a/library/src/scala/Option.scala +++ b/library/src/scala/Option.scala @@ -28,7 +28,7 @@ object Option { * @param x the value * @return Some(value) if value != null, None if value == null */ - def apply[A](x: A): Option[A] = if (x == null) None else Some(x) + def apply[A](x: A | Null): Option[A] = if (x == null) None else Some(x) /** An Option factory which returns `None` in a manner consistent with * the collections hierarchy. diff --git a/library/src/scala/quoted/FromExpr.scala b/library/src/scala/quoted/FromExpr.scala index 2d9e3ebc5ab6..fb230c6d22b9 100644 --- a/library/src/scala/quoted/FromExpr.scala +++ b/library/src/scala/quoted/FromExpr.scala @@ -104,7 +104,7 @@ object FromExpr { */ given OptionFromExpr[T](using Type[T], FromExpr[T]): FromExpr[Option[T]] with { def unapply(x: Expr[Option[T]])(using Quotes) = x match { - case '{ Option[T](${Expr(y)}) } => Some(Option(y)) + case '{ Option[T](${Expr(y)}: T) } => Some(Option(y)) case '{ None } => Some(None) case '{ ${Expr(opt)} : Some[T] } => Some(opt) case _ => None diff --git a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala index 9a79c5a84fe1..00344aa5ad75 100644 --- a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala +++ b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala @@ -74,8 +74,8 @@ class SourceLinkParser(revision: Option[String]) extends ArgParser[SourceLink]: else Right(TemplateSourceLink(supported.foldLeft(string)((template, pattern) => template.replace(pattern, SupportedScalaDocPatternReplacements(pattern))))) case KnownProvider(name: String, organization: String, repo: String, rawRevision, rawSubPath) => - val subPath = Option.fromNullable(rawSubPath).fold("")("/" + _.drop(1)) - val pathRev = Option.fromNullable(rawRevision).map(_.drop(1)).orElse(revision) + val subPath = Option(rawSubPath).fold("")("/" + _.drop(1)) + val pathRev = Option(rawRevision).map(_.drop(1)).orElse(revision) def withRevision(template: String => SourceLink) = pathRev.fold(Left(s"No revision provided"))(r => Right(template(r))) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index e0834ee78ecf..af0d1208c5cb 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -116,8 +116,8 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite def loadBlog(): Option[LoadedTemplate] = { val blogConfig = BlogParser.readYml(root) - val rootPath = Option.fromNullable(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) - val defaultDirectory = Option.fromNullable(blogConfig.output).getOrElse("blog") + val rootPath = Option(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) + val defaultDirectory = Option(blogConfig.output).getOrElse("blog") type Date = (String, String, String) if (!Files.exists(rootPath) || blogConfig.hidden) None diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala index a84137caa5a7..0b38af38a3b3 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala @@ -277,7 +277,7 @@ class SymOpsWithLinkCache: then externalLinkCache(csym.associatedFile) else { def calculatePath(file: AbstractFile): String = file.underlyingSource.filter(_ != file).fold("")(f => calculatePath(f) + "/") + file.path - val calculatedLink = Option.fromNullable(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => + val calculatedLink = Option(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => dctx.externalDocumentationLinks.find(_.originRegexes.exists(r => r.matches(path))) } externalLinkCache += (csym.associatedFile -> calculatedLink) From db7bce0d56b5c29b16c76ac3e776d22152093e6c Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 2 Oct 2025 10:47:26 +0200 Subject: [PATCH 36/46] Revert "Update Option.apply" This reverts commit e478f651c80ad7bdaf61c3a7c2cf7830fa3691fc. --- .../dotty/tools/dotc/transform/localopt/FormatChecker.scala | 4 +++- library/src/scala/Option.scala | 2 +- library/src/scala/quoted/FromExpr.scala | 2 +- scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala | 4 ++-- scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala | 4 ++-- scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala index 83ec7fb8399e..4184407d07a8 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala @@ -126,7 +126,9 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List def at(g: SpecGroup): Int = descriptor.start(g.ordinal) def end(g: SpecGroup): Int = descriptor.end(g.ordinal) def offset(g: SpecGroup, i: Int = 0): Int = at(g) + i - def group(g: SpecGroup): Option[String] = Option(descriptor.group(g.ordinal)) + def group(g: SpecGroup): Option[String] = + // Unable to use @experimental fromNullable now + Option(descriptor.group(g.ordinal)).asInstanceOf[Option[String]] def stringOf(g: SpecGroup): String = group(g).getOrElse("") def intOf(g: SpecGroup): Option[Int] = group(g).map(_.toInt) diff --git a/library/src/scala/Option.scala b/library/src/scala/Option.scala index b2eadf2c1be3..894eade2445a 100644 --- a/library/src/scala/Option.scala +++ b/library/src/scala/Option.scala @@ -28,7 +28,7 @@ object Option { * @param x the value * @return Some(value) if value != null, None if value == null */ - def apply[A](x: A | Null): Option[A] = if (x == null) None else Some(x) + def apply[A](x: A): Option[A] = if (x == null) None else Some(x) /** An Option factory which returns `None` in a manner consistent with * the collections hierarchy. diff --git a/library/src/scala/quoted/FromExpr.scala b/library/src/scala/quoted/FromExpr.scala index fb230c6d22b9..2d9e3ebc5ab6 100644 --- a/library/src/scala/quoted/FromExpr.scala +++ b/library/src/scala/quoted/FromExpr.scala @@ -104,7 +104,7 @@ object FromExpr { */ given OptionFromExpr[T](using Type[T], FromExpr[T]): FromExpr[Option[T]] with { def unapply(x: Expr[Option[T]])(using Quotes) = x match { - case '{ Option[T](${Expr(y)}: T) } => Some(Option(y)) + case '{ Option[T](${Expr(y)}) } => Some(Option(y)) case '{ None } => Some(None) case '{ ${Expr(opt)} : Some[T] } => Some(opt) case _ => None diff --git a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala index 00344aa5ad75..9a79c5a84fe1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala +++ b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala @@ -74,8 +74,8 @@ class SourceLinkParser(revision: Option[String]) extends ArgParser[SourceLink]: else Right(TemplateSourceLink(supported.foldLeft(string)((template, pattern) => template.replace(pattern, SupportedScalaDocPatternReplacements(pattern))))) case KnownProvider(name: String, organization: String, repo: String, rawRevision, rawSubPath) => - val subPath = Option(rawSubPath).fold("")("/" + _.drop(1)) - val pathRev = Option(rawRevision).map(_.drop(1)).orElse(revision) + val subPath = Option.fromNullable(rawSubPath).fold("")("/" + _.drop(1)) + val pathRev = Option.fromNullable(rawRevision).map(_.drop(1)).orElse(revision) def withRevision(template: String => SourceLink) = pathRev.fold(Left(s"No revision provided"))(r => Right(template(r))) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index af0d1208c5cb..e0834ee78ecf 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -116,8 +116,8 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite def loadBlog(): Option[LoadedTemplate] = { val blogConfig = BlogParser.readYml(root) - val rootPath = Option(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) - val defaultDirectory = Option(blogConfig.output).getOrElse("blog") + val rootPath = Option.fromNullable(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) + val defaultDirectory = Option.fromNullable(blogConfig.output).getOrElse("blog") type Date = (String, String, String) if (!Files.exists(rootPath) || blogConfig.hidden) None diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala index 0b38af38a3b3..a84137caa5a7 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala @@ -277,7 +277,7 @@ class SymOpsWithLinkCache: then externalLinkCache(csym.associatedFile) else { def calculatePath(file: AbstractFile): String = file.underlyingSource.filter(_ != file).fold("")(f => calculatePath(f) + "/") + file.path - val calculatedLink = Option(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => + val calculatedLink = Option.fromNullable(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => dctx.externalDocumentationLinks.find(_.originRegexes.exists(r => r.matches(path))) } externalLinkCache += (csym.associatedFile -> calculatedLink) From e98f6e4dd4b65d3de8e5947993018ab75b26c519 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 2 Oct 2025 10:51:25 +0200 Subject: [PATCH 37/46] Remove experimental annotation from Option.fromNullable --- library/src/scala/Predef.scala | 1 - library/src/scala/runtime/stdLibPatches/Predef.scala | 1 - tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala | 3 --- 3 files changed, 5 deletions(-) diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index d256f850a90b..2743bcffa56d 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -594,7 +594,6 @@ object Predef extends LowPriorityImplicits { !(x eq y) extension (opt: Option.type) - @experimental inline def fromNullable[T](t: T | Null): Option[T] = Option(t).asInstanceOf[Option[T]] // For backward compatibility with code compiled without -Yexplicit-nulls. diff --git a/library/src/scala/runtime/stdLibPatches/Predef.scala b/library/src/scala/runtime/stdLibPatches/Predef.scala index ed4cf207c925..1b4d3291ed9f 100644 --- a/library/src/scala/runtime/stdLibPatches/Predef.scala +++ b/library/src/scala/runtime/stdLibPatches/Predef.scala @@ -67,7 +67,6 @@ object Predef: !(x eq y) extension (opt: Option.type) - @experimental inline def fromNullable[T](t: T | Null): Option[T] = Option(t).asInstanceOf[Option[T]] /** A type supporting Self-based type classes. diff --git a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala index d57f19112659..c249721f6a6d 100644 --- a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala @@ -79,9 +79,6 @@ val experimentalDefinitionInLibrary = Set( "scala.quoted.Quotes.reflectModule.RenameSelectorModule.apply", "scala.quoted.Quotes.reflectModule.SimpleSelectorModule.apply", - // New feature: fromNullable for explicit nulls - "scala.Predef$.fromNullable", - // New feature: modularity "scala.Precise", "scala.annotation.internal.WitnessNames", From ebbd740a187bcee9a8c202c2da0c33b5aa48de34 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 3 Oct 2025 15:37:48 +0200 Subject: [PATCH 38/46] Address comments --- library/src/scala/IArray.scala | 3 +-- library/src/scala/Predef.scala | 1 + .../src/scala/collection/mutable/AnyRefMap.scala | 2 +- .../scala/collection/mutable/ListBuffer.scala | 2 +- .../src/scala/collection/mutable/LongMap.scala | 1 + .../scala/collection/mutable/RedBlackTree.scala | 16 ++++++++-------- .../src/scala/runtime/stdLibPatches/Predef.scala | 1 + 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index bb89926c55ac..4d7882a59a98 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -346,12 +346,11 @@ object IArray: mapNull(arr, ArraySeq.unsafeWrapArray(arr)) /** Conversion from IArray to immutable.ArraySeq */ - import scala.language.unsafeNulls // TODO!!! only for stdliib migration! + import scala.language.unsafeNulls // TODO!!! only for stdlib migration! 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. - // import scala.language.unsafeNulls mapNull(arr, if (arr.length == 0) ArraySeq.empty[AnyRef | Null].asInstanceOf[ArraySeq.ofRef[T]] else ArraySeq.ofRef[AnyRef](arr.asInstanceOf[Array[AnyRef]]).asInstanceOf[ArraySeq.ofRef[T]] diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index 2743bcffa56d..d256f850a90b 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -594,6 +594,7 @@ object Predef extends LowPriorityImplicits { !(x eq y) extension (opt: Option.type) + @experimental inline def fromNullable[T](t: T | Null): Option[T] = Option(t).asInstanceOf[Option[T]] // For backward compatibility with code compiled without -Yexplicit-nulls. diff --git a/library/src/scala/collection/mutable/AnyRefMap.scala b/library/src/scala/collection/mutable/AnyRefMap.scala index 09786cdcb517..8228254ddfe2 100644 --- a/library/src/scala/collection/mutable/AnyRefMap.scala +++ b/library/src/scala/collection/mutable/AnyRefMap.scala @@ -202,7 +202,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initi */ def getOrNull(key: K): V | Null = { val i = seekEntry(hashOf(key), key) - if (i < 0) null else _values(i).asInstanceOf[V | Null] + if (i < 0) null else _values(i).asInstanceOf[V] } /** Retrieves the value associated with a key. diff --git a/library/src/scala/collection/mutable/ListBuffer.scala b/library/src/scala/collection/mutable/ListBuffer.scala index e818de4d546d..cf0730ef0cd4 100644 --- a/library/src/scala/collection/mutable/ListBuffer.scala +++ b/library/src/scala/collection/mutable/ListBuffer.scala @@ -321,7 +321,7 @@ 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 = null diff --git a/library/src/scala/collection/mutable/LongMap.scala b/library/src/scala/collection/mutable/LongMap.scala index 959544f53bea..171c9d44351a 100644 --- a/library/src/scala/collection/mutable/LongMap.scala +++ b/library/src/scala/collection/mutable/LongMap.scala @@ -470,6 +470,7 @@ 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. val m = this + elem1 + elem2 if(elems.isEmpty) m else m.concat(elems) } diff --git a/library/src/scala/collection/mutable/RedBlackTree.scala b/library/src/scala/collection/mutable/RedBlackTree.scala index a21455eee0ec..b8347b5984c7 100644 --- a/library/src/scala/collection/mutable/RedBlackTree.scala +++ b/library/src/scala/collection/mutable/RedBlackTree.scala @@ -146,7 +146,8 @@ private[collection] object RedBlackTree { private[this] def minNodeAfter[A, B](node: Node[A, B] | Null, key: A)(implicit ord: Ordering[A]): Node[A, B] | Null = { if (node eq null) null else { - var y: Node[A, B] | Null = null + // We know x is not null initially, so y will only be null before the first iteration of the loop. + var y: Node[A, B] = null.asInstanceOf[Node[A, B]] var x: Node[A, B] | Null = node var cmp = 1 while ((x ne null) && cmp != 0) { @@ -176,7 +177,8 @@ private[collection] object RedBlackTree { private[this] def maxNodeBefore[A, B](node: Node[A, B] | Null, key: A)(implicit ord: Ordering[A]): Node[A, B] | Null = { if (node eq null) null else { - var y: Node[A, B] | Null = null + // We know x is not null initially, so y will only be null before the first iteration of the loop. + var y: Node[A, B] = null.asInstanceOf[Node[A, B]] var x: Node[A, B] | Null = node var cmp = 1 while ((x ne null) && cmp != 0) { @@ -364,9 +366,8 @@ private[collection] object RedBlackTree { * Returns the node that follows `node` in an in-order tree traversal. If `node` has the maximum key (and is, * therefore, the last node), this method returns `null`. */ - private[this] def successor[A, B](node: Node[A, B] | Null): Node[A, B] | Null = { - if (node eq null) null - else if (node.right ne null) minNodeNonNull(node.right) + private[this] def successor[A, B](node: Node[A, B]): Node[A, B] | Null = { + if (node.right ne null) minNodeNonNull(node.right) else { var x = node var y = x.parent @@ -382,9 +383,8 @@ private[collection] object RedBlackTree { * Returns the node that precedes `node` in an in-order tree traversal. If `node` has the minimum key (and is, * therefore, the first node), this method returns `null`. */ - private[this] def predecessor[A, B](node: Node[A, B] | Null): Node[A, B] | Null = { - if (node eq null) null - else if (node.left ne null) maxNodeNonNull(node.left) + private[this] def predecessor[A, B](node: Node[A, B]): Node[A, B] | Null = { + if (node.left ne null) maxNodeNonNull(node.left) else { var x = node var y = x.parent diff --git a/library/src/scala/runtime/stdLibPatches/Predef.scala b/library/src/scala/runtime/stdLibPatches/Predef.scala index 1b4d3291ed9f..ed4cf207c925 100644 --- a/library/src/scala/runtime/stdLibPatches/Predef.scala +++ b/library/src/scala/runtime/stdLibPatches/Predef.scala @@ -67,6 +67,7 @@ object Predef: !(x eq y) extension (opt: Option.type) + @experimental inline def fromNullable[T](t: T | Null): Option[T] = Option(t).asInstanceOf[Option[T]] /** A type supporting Self-based type classes. From e0f96ba747c77c650ce470e231fb7da717325c44 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 3 Oct 2025 16:59:20 +0200 Subject: [PATCH 39/46] Add mapNull and nullForGC to ScalaRunTime --- .../src/scala/runtime/ScalaRunTime.scala | 16 ++++++++-------- library/src/scala/IArray.scala | 4 ++-- library/src/scala/Predef.scala | 9 +-------- library/src/scala/collection/Iterator.scala | 7 ++++--- library/src/scala/collection/SeqView.scala | 3 ++- library/src/scala/collection/View.scala | 3 ++- .../scala/collection/immutable/Stream.scala | 2 ++ .../scala/collection/immutable/Vector.scala | 12 ++++++------ library/src/scala/runtime/ScalaRunTime.scala | 18 +++++++++++++----- library/src/scala/util/Using.scala | 3 ++- 10 files changed, 42 insertions(+), 35 deletions(-) diff --git a/library-js/src/scala/runtime/ScalaRunTime.scala b/library-js/src/scala/runtime/ScalaRunTime.scala index d63a8e5b61ce..28aba9dea39e 100644 --- a/library-js/src/scala/runtime/ScalaRunTime.scala +++ b/library-js/src/scala/runtime/ScalaRunTime.scala @@ -254,11 +254,14 @@ object ScalaRunTime { case s => s + "\n" } + // For backward compatibility with code compiled without -Yexplicit-nulls. // If `a` is null, return null; otherwise, return `f`. - // Have to add a private mapNull here to avoid errors - private inline def mapNull[A, B](a: A, inline f: B): B = - if((a: A | Null) == null) null.asInstanceOf[B] else f + private[scala] inline def mapNull[A, B](a: A, inline f: B): B = + if ((a: A | Null) == null) null.asInstanceOf[B] else f + + // Use `null` in places where we want to make sure the reference is cleared. + private[scala] inline def nullForGC[T]: T = null.asInstanceOf[T] // For the following functions, both the parameter and the return type are non-nullable. // However, if a null reference is passed explicitly, this method will still return null. @@ -268,11 +271,8 @@ object ScalaRunTime { // Convert arrays to immutable.ArraySeq for use with Java varargs: def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = mapNull(xs, ArraySeq.unsafeWrapArray(xs)) - def wrapRefArray[T <: AnyRef | Null](xs: Array[T]): ArraySeq[T] = { - if (xs eq null) null.asInstanceOf[ArraySeq[T]] - else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] - else new ArraySeq.ofRef[T](xs) - } + def wrapRefArray[T <: AnyRef | Null](xs: Array[T]): ArraySeq[T] = + mapNull(xs, if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] else new ArraySeq.ofRef[T](xs)) def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = mapNull(xs, new ArraySeq.ofInt(xs)) def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = mapNull(xs, new ArraySeq.ofDouble(xs)) def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = mapNull(xs, new ArraySeq.ofLong(xs)) diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 4d7882a59a98..275eaccd7325 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -332,9 +332,9 @@ object IArray: // For backward compatibility with code compiled without -Yexplicit-nulls. // If `a` is null, return null; otherwise, return `f`. - // Have to add a private mapNull here to avoid errors + // Have to add a private mapNull here to avoid errors, use `ScalaRunTime.mapNull` in the future. 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 // For the following functions, both the parameter and the return type are non-nullable. // However, if a null reference is passed explicitly, this method will still return null. diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index d256f850a90b..48030f2f1232 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -20,6 +20,7 @@ import scala.annotation.{elidable, experimental, implicitNotFound, publicInBinar import scala.annotation.meta.{ companionClass, companionMethod } import scala.annotation.internal.{ RuntimeChecked } import scala.compiletime.summonFrom +import scala.runtime.ScalaRunTime.mapNull /** The `Predef` object provides definitions that are accessible in all Scala * compilation units without explicit qualification. @@ -597,14 +598,6 @@ object Predef extends LowPriorityImplicits { @experimental inline def fromNullable[T](t: T | Null): Option[T] = Option(t).asInstanceOf[Option[T]] - // For backward compatibility with code compiled without -Yexplicit-nulls. - // If `a` is null, return null; otherwise, return `f`. - private[scala] inline def mapNull[A, B](a: A, inline f: B): B = - if((a: A | Null) == null) null.asInstanceOf[B] else f - - // Use `null` in places where we want to make sure the reference is cleared. - private[scala] inline def nullForGC[T]: T = null.asInstanceOf[T] - /** A type supporting Self-based type classes. * * A is TC diff --git a/library/src/scala/collection/Iterator.scala b/library/src/scala/collection/Iterator.scala index 6df7c189cadb..66faf001cac0 100644 --- a/library/src/scala/collection/Iterator.scala +++ b/library/src/scala/collection/Iterator.scala @@ -17,6 +17,7 @@ import language.experimental.captureChecking import scala.collection.mutable.{ArrayBuffer, ArrayBuilder, Builder, ImmutableBuilder} import scala.annotation.tailrec import scala.annotation.unchecked.uncheckedVariance +import scala.runtime.ScalaRunTime.nullForGC import scala.runtime.Statics /** Iterators are data structures that allow to iterate over a sequence @@ -772,14 +773,14 @@ 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.asInstanceOf[Leading]; hasNext } + if (myLeading.finish()) { status = 0 ; true } else { status = 1 ; myLeading = nullForGC[Leading]; hasNext } } def next() = { if (hasNext) { if (status == 0) { status = 1 val res = myLeading.trailer - myLeading = null.asInstanceOf[Leading] + myLeading = nullForGC[Leading] res } else { status = 1 @@ -1301,7 +1302,7 @@ object Iterator extends IterableFactory[Iterator] { if (res eq null) throw new NullPointerException("null during unfold") res } - state = null.asInstanceOf[S] // allow GC + state = nullForGC[S] } nextResult.nn.isDefined } diff --git a/library/src/scala/collection/SeqView.scala b/library/src/scala/collection/SeqView.scala index cd2cc1637eaf..21b771d4e13c 100644 --- a/library/src/scala/collection/SeqView.scala +++ b/library/src/scala/collection/SeqView.scala @@ -18,6 +18,7 @@ import language.experimental.captureChecking import scala.annotation.nowarn import scala.collection.generic.CommonErrors +import scala.runtime.ScalaRunTime.nullForGC trait SeqView[+A] extends SeqOps[A, View, View[A]] with View[A] { @@ -187,7 +188,7 @@ object SeqView { } } evaluated = true - underlying = nullForGC[SomeSeqOps[A]] // allow GC of unneeded reference + underlying = nullForGC[SomeSeqOps[A]] res } diff --git a/library/src/scala/collection/View.scala b/library/src/scala/collection/View.scala index 81a18b2ef08e..0ea0459664bd 100644 --- a/library/src/scala/collection/View.scala +++ b/library/src/scala/collection/View.scala @@ -18,6 +18,7 @@ import language.experimental.captureChecking import scala.annotation.{nowarn, tailrec} import scala.collection.mutable.{ArrayBuffer, Builder} import scala.collection.immutable.LazyList +import scala.runtime.ScalaRunTime.nullForGC import caps.unsafe.unsafeAssumePure /** Views are collections whose transformation operations are non strict: the resulting elements @@ -465,7 +466,7 @@ object View extends IterableFactory[View] { if(pos == maxlen) pos = 0 len += 1 } - underlying = null.asInstanceOf[Iterator[A]] // allow GC of underlying iterator + underlying = nullForGC[Iterator[A]] if(len > maxlen) len = maxlen pos = pos - len if(pos < 0) pos += maxlen diff --git a/library/src/scala/collection/immutable/Stream.scala b/library/src/scala/collection/immutable/Stream.scala index 859cd29d1697..941e4ff5d158 100644 --- a/library/src/scala/collection/immutable/Stream.scala +++ b/library/src/scala/collection/immutable/Stream.scala @@ -23,6 +23,8 @@ import scala.annotation.unchecked.uncheckedVariance import scala.collection.generic.SerializeEnd import scala.collection.mutable.{ArrayBuffer, StringBuilder} import scala.language.implicitConversions +import scala.runtime.ScalaRunTime.nullForGC + import Stream.cons @deprecated("Use LazyListIterable (which is fully lazy) instead of Stream (which has a lazy tail only)", "2.13.0") diff --git a/library/src/scala/collection/immutable/Vector.scala b/library/src/scala/collection/immutable/Vector.scala index a5089a24b3e7..3af7c7d6a9be 100644 --- a/library/src/scala/collection/immutable/Vector.scala +++ b/library/src/scala/collection/immutable/Vector.scala @@ -27,7 +27,7 @@ import scala.collection.generic.{CommonErrors, DefaultSerializable} import scala.collection.immutable.VectorInline._ import scala.collection.immutable.VectorStatics._ import scala.collection.mutable.ReusableBuilder - +import scala.runtime.ScalaRunTime.nullForGC /** $factoryInfo * @define Coll `Vector` @@ -1421,11 +1421,11 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] { @inline def nonEmpty: Boolean = knownSize != 0 def clear(): Unit = { - a6 = null.asInstanceOf[Arr6] - a5 = null.asInstanceOf[Arr5] - a4 = null.asInstanceOf[Arr4] - a3 = null.asInstanceOf[Arr3] - a2 = null.asInstanceOf[Arr2] + a6 = nullForGC[Arr6] + a5 = nullForGC[Arr5] + a4 = nullForGC[Arr4] + a3 = nullForGC[Arr3] + a2 = nullForGC[Arr2] a1 = new Arr1(WIDTH) len1 = 0 lenRest = 0 diff --git a/library/src/scala/runtime/ScalaRunTime.scala b/library/src/scala/runtime/ScalaRunTime.scala index 7bd1022a95d2..e288fa7ffc5e 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 | Null, idx: Int): Any = { + def array_apply(xs: AnyRef, 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 | Null, idx: Int, value: Any): Unit = { + def array_update(xs: AnyRef, 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 | Null): Int = java.lang.reflect.Array.getLength(xs) + @inline def array_length(xs: AnyRef): 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 | Null): AnyRef = (xs: @unchecked) match { + def array_clone(xs: AnyRef): 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 | Null): Array[Object] = { + def toObjectArray(src: AnyRef): Array[Object] = { def copy[@specialized T <: AnyVal](src: Array[T]): Array[Object] = { val length = src.length if (length == 0) Array.emptyObjectArray @@ -281,6 +281,14 @@ object ScalaRunTime { case s => s + "\n" } + // For backward compatibility with code compiled without -Yexplicit-nulls. + // If `a` is null, return null; otherwise, return `f`. + private[scala] inline def mapNull[A, B](a: A, inline f: B): B = + if ((a: A | Null) == null) null.asInstanceOf[B] else f + + // Use `null` in places where we want to make sure the reference is cleared. + private[scala] inline def nullForGC[T]: T = null.asInstanceOf[T] + // Convert arrays to immutable.ArraySeq for use with Scala varargs. // By construction, calls to these methods always receive a fresh (and non-null), non-empty array. // In cases where an empty array would appear, the compiler uses a direct reference to Nil instead. diff --git a/library/src/scala/util/Using.scala b/library/src/scala/util/Using.scala index 0f022bacd896..d0c6bdbde4fa 100644 --- a/library/src/scala/util/Using.scala +++ b/library/src/scala/util/Using.scala @@ -14,6 +14,7 @@ package scala.util import scala.language.`2.13` import scala.util.control.{ControlThrowable, NonFatal} +import scala.runtime.ScalaRunTime.nullForGC /** A utility for performing automatic resource management. It can be used to perform an * operation using resources, after which it releases the resources in reverse order @@ -208,7 +209,7 @@ object Using { } finally { closed = true var rs = resources - resources = null.asInstanceOf[List[Resource[_]]] // allow GC, in case something is holding a reference to `this` + resources = nullForGC[List[Resource[_]]] // allow GC, in case something is holding a reference to `this` while (rs != null && rs.nonEmpty) { val resource = rs.head rs = rs.tail From 694dee6988c0ee8b80720160bdd2f46214cdd9df Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 3 Oct 2025 18:05:02 +0200 Subject: [PATCH 40/46] Address some comments --- .../dotty/tools/scripting/StringDriver.scala | 2 +- compiler/src/dotty/tools/scripting/Util.scala | 2 +- .../test/dotty/tools/io/ClasspathTest.scala | 2 +- .../scala/concurrent/BatchingExecutor.scala | 4 +- library/src/scala/io/BufferedSource.scala | 6 +- .../src/scala/jdk/FunctionExtensions.scala | 176 +++++++++--------- library/src/scala/sys/SystemProperties.scala | 2 +- library/src/scala/util/Sorting.scala | 6 +- 8 files changed, 100 insertions(+), 100 deletions(-) diff --git a/compiler/src/dotty/tools/scripting/StringDriver.scala b/compiler/src/dotty/tools/scripting/StringDriver.scala index 222c2c1dd357..6d4fac719be2 100755 --- a/compiler/src/dotty/tools/scripting/StringDriver.scala +++ b/compiler/src/dotty/tools/scripting/StringDriver.scala @@ -31,7 +31,7 @@ class StringDriver(compilerArgs: Array[String], scalaSource: String) extends Dri try val classpath = s"${ctx.settings.classpath.value}${pathsep}${sys.props("java.class.path")}" val classpathEntries: Seq[Path] = ClassPath.expandPath(classpath, expandStar=true).map { Paths.get(_) } - sys.props("java.class.path") = classpathEntries.map(_.toString).mkString(pathsep.nn) + sys.props("java.class.path") = classpathEntries.map(_.toString).mkString(pathsep) detectMainClassAndMethod(outDir, classpathEntries, scalaSource) match case Right((mainClass, mainMethod)) => mainMethod.invoke(null, Array.empty[String]) diff --git a/compiler/src/dotty/tools/scripting/Util.scala b/compiler/src/dotty/tools/scripting/Util.scala index 99af967143d3..5ce71aa7c130 100755 --- a/compiler/src/dotty/tools/scripting/Util.scala +++ b/compiler/src/dotty/tools/scripting/Util.scala @@ -56,7 +56,7 @@ object Util: end match end detectMainClassAndMethod - def pathsep = sys.props("path.separator") + def pathsep: String = sys.props("path.separator").nn end Util diff --git a/compiler/test/dotty/tools/io/ClasspathTest.scala b/compiler/test/dotty/tools/io/ClasspathTest.scala index 333f2b8062b0..7af68e47b3b8 100755 --- a/compiler/test/dotty/tools/io/ClasspathTest.scala +++ b/compiler/test/dotty/tools/io/ClasspathTest.scala @@ -13,7 +13,7 @@ import dotty.tools.io.{ PlainDirectory, Directory, ClassPath } class ClasspathTest { - def pathsep = sys.props("path.separator") + def pathsep: String = sys.props("path.separator").nn def isWindows: Boolean = scala.util.Properties.isWin diff --git a/library/src/scala/concurrent/BatchingExecutor.scala b/library/src/scala/concurrent/BatchingExecutor.scala index e76c807c8a96..b69dc86fd181 100644 --- a/library/src/scala/concurrent/BatchingExecutor.scala +++ b/library/src/scala/concurrent/BatchingExecutor.scala @@ -100,7 +100,7 @@ private[concurrent] trait BatchingExecutor extends Executor { */ 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 other: Array[Runnable | Null], protected final var size: Int ) { @@ -149,7 +149,7 @@ private[concurrent] trait BatchingExecutor extends Executor { } 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 + private[this] final var parentBlockContext: BlockContext = BatchingExecutorStatics.MissingParentBlockContext final def this(runnable: Runnable) = this(runnable, BatchingExecutorStatics.emptyBatchArray, 1) diff --git a/library/src/scala/io/BufferedSource.scala b/library/src/scala/io/BufferedSource.scala index f2aa614107ec..d4cfee2db477 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 = null + @annotation.stableNull 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.nn finally nextLine = null + else try nextLine finally nextLine = null } if (result == null) Iterator.empty.next() - else result.nn + else result } } diff --git a/library/src/scala/jdk/FunctionExtensions.scala b/library/src/scala/jdk/FunctionExtensions.scala index 88c4623ac8f8..9f97426bbe12 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/sys/SystemProperties.scala b/library/src/scala/sys/SystemProperties.scala index 24c935e85e5c..31d7ea3edc55 100644 --- a/library/src/scala/sys/SystemProperties.scala +++ b/library/src/scala/sys/SystemProperties.scala @@ -34,7 +34,7 @@ extends mutable.AbstractMap[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 | Null)] = wrapAccess { + def iterator: Iterator[(String, String)] = wrapAccess { val ps = System.getProperties() names map (k => (k, ps getProperty k)) filter (_._2 ne null) } getOrElse Iterator.empty diff --git a/library/src/scala/util/Sorting.scala b/library/src/scala/util/Sorting.scala index 2f44d73ca1cb..3c8da267ccad 100644 --- a/library/src/scala/util/Sorting.scala +++ b/library/src/scala/util/Sorting.scala @@ -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] | Null, from: Int, until: Int, ord: Ordering[T]): Unit = (a: @unchecked) match { - case _: Array[AnyRef] => + @inline private def sort[T](a: Array[T], from: Int, until: Int, ord: Ordering[T]): Unit = (a: @unchecked) match { + case a: 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.nn.length > 1 && (ord eq null)) throw new NullPointerException("Ordering") + if (a.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! From be5548ab21f11300c061eb357e7df5d4fe6d087d Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Sun, 5 Oct 2025 21:46:01 +0200 Subject: [PATCH 41/46] Re-apply nullable to Option.apply --- library/src/scala/Option.scala | 2 +- library/src/scala/quoted/FromExpr.scala | 2 +- sbt-bridge/src/xsbt/ConsoleInterface.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/src/scala/Option.scala b/library/src/scala/Option.scala index 894eade2445a..b2eadf2c1be3 100644 --- a/library/src/scala/Option.scala +++ b/library/src/scala/Option.scala @@ -28,7 +28,7 @@ object Option { * @param x the value * @return Some(value) if value != null, None if value == null */ - def apply[A](x: A): Option[A] = if (x == null) None else Some(x) + def apply[A](x: A | Null): Option[A] = if (x == null) None else Some(x) /** An Option factory which returns `None` in a manner consistent with * the collections hierarchy. diff --git a/library/src/scala/quoted/FromExpr.scala b/library/src/scala/quoted/FromExpr.scala index 2d9e3ebc5ab6..fb230c6d22b9 100644 --- a/library/src/scala/quoted/FromExpr.scala +++ b/library/src/scala/quoted/FromExpr.scala @@ -104,7 +104,7 @@ object FromExpr { */ given OptionFromExpr[T](using Type[T], FromExpr[T]): FromExpr[Option[T]] with { def unapply(x: Expr[Option[T]])(using Quotes) = x match { - case '{ Option[T](${Expr(y)}) } => Some(Option(y)) + case '{ Option[T](${Expr(y)}: T) } => Some(Option(y)) case '{ None } => Some(None) case '{ ${Expr(opt)} : Some[T] } => Some(opt) case _ => None diff --git a/sbt-bridge/src/xsbt/ConsoleInterface.java b/sbt-bridge/src/xsbt/ConsoleInterface.java index 49194fdf53d2..3ba4e011c8e3 100644 --- a/sbt-bridge/src/xsbt/ConsoleInterface.java +++ b/sbt-bridge/src/xsbt/ConsoleInterface.java @@ -5,7 +5,7 @@ import java.util.ArrayList; -import scala.Some; +import scala.Option; import xsbti.Logger; @@ -40,7 +40,7 @@ public void run( completeArgsList.add(classpathString); String[] completeArgs = completeArgsList.toArray(args); - ReplDriver driver = new ReplDriver(completeArgs, System.out, Some.apply(loader), ReplDriver.pprintImport()); + ReplDriver driver = new ReplDriver(completeArgs, System.out, Option.apply(loader), ReplDriver.pprintImport()); State state = driver.initialState(); assert bindNames.length == bindValues.length; From 4cebbb13d7a9c649474157fa9f80b827625464b1 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Sun, 5 Oct 2025 23:58:49 +0200 Subject: [PATCH 42/46] Fix tests --- tests/neg-macros/annot-crash.check | 2 +- tests/neg-macros/i23008.check | 2 +- tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala | 3 +++ tests/warn/i15503f.scala | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/neg-macros/annot-crash.check b/tests/neg-macros/annot-crash.check index 63fd77de0ec5..30a02c6f9286 100644 --- a/tests/neg-macros/annot-crash.check +++ b/tests/neg-macros/annot-crash.check @@ -3,5 +3,5 @@ |^^^^^^ |Failed to evaluate macro annotation '@crash'. | Caused by class scala.NotImplementedError: an implementation is missing - | scala.Predef$.$qmark$qmark$qmark(Predef.scala:400) + | scala.Predef$.$qmark$qmark$qmark(Predef.scala:401) | crash.transform(Macro_1.scala:7) diff --git a/tests/neg-macros/i23008.check b/tests/neg-macros/i23008.check index f69edff330a0..d661e59fb74b 100644 --- a/tests/neg-macros/i23008.check +++ b/tests/neg-macros/i23008.check @@ -3,7 +3,7 @@ | ^^^^^^^^^^^^^^^^^^ | Exception occurred while executing macro expansion. | java.lang.IllegalArgumentException: requirement failed: value of StringConstant cannot be `null` - | at scala.Predef$.require(Predef.scala:393) + | at scala.Predef$.require(Predef.scala:394) | at scala.quoted.runtime.impl.QuotesImpl$reflect$StringConstant$.apply(QuotesImpl.scala:2542) | at scala.quoted.runtime.impl.QuotesImpl$reflect$StringConstant$.apply(QuotesImpl.scala:2541) | at scala.quoted.ToExpr$StringToExpr.apply(ToExpr.scala:82) diff --git a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala index c249721f6a6d..d57f19112659 100644 --- a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala @@ -79,6 +79,9 @@ val experimentalDefinitionInLibrary = Set( "scala.quoted.Quotes.reflectModule.RenameSelectorModule.apply", "scala.quoted.Quotes.reflectModule.SimpleSelectorModule.apply", + // New feature: fromNullable for explicit nulls + "scala.Predef$.fromNullable", + // New feature: modularity "scala.Precise", "scala.annotation.internal.WitnessNames", diff --git a/tests/warn/i15503f.scala b/tests/warn/i15503f.scala index 70d0b9182eb2..d4ef9709ffe6 100644 --- a/tests/warn/i15503f.scala +++ b/tests/warn/i15503f.scala @@ -28,7 +28,7 @@ object Example: import scala.quoted.* given OptionFromExpr[T](using Type[T], FromExpr[T]): FromExpr[Option[T]] with def unapply(x: Expr[Option[T]])(using Quotes) = x match - case '{ Option[T](${Expr(y)}) } => Some(Option(y)) + case '{ Option[T](${Expr(y)}: T) } => Some(Option(y)) case '{ None } => Some(None) case '{ ${Expr(opt)} : Some[T] } => Some(opt) case _ => None @@ -37,7 +37,7 @@ object ExampleWithoutWith: import scala.quoted.* given [T] => (Type[T], FromExpr[T]) => FromExpr[Option[T]]: def unapply(x: Expr[Option[T]])(using Quotes) = x match - case '{ Option[T](${Expr(y)}) } => Some(Option(y)) + case '{ Option[T](${Expr(y)}: T) } => Some(Option(y)) case '{ None } => Some(None) case '{ ${Expr(opt)} : Some[T] } => Some(opt) case _ => None From 2afafc96e7ba1b74487642aa595b5fac4c824116 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 6 Oct 2025 00:45:23 +0200 Subject: [PATCH 43/46] Update Promise; update build --- library/src/scala/concurrent/impl/Promise.scala | 2 +- .../src/scala/reflect/ClassManifestDeprecatedApis.scala | 3 ++- project/Build.scala | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/library/src/scala/concurrent/impl/Promise.scala b/library/src/scala/concurrent/impl/Promise.scala index d9bf2879e155..2ca2228d159f 100644 --- a/library/src/scala/concurrent/impl/Promise.scala +++ b/library/src/scala/concurrent/impl/Promise.scala @@ -274,7 +274,7 @@ private[concurrent] object Promise { override final def isCompleted: Boolean = value0 ne null - override final def value: Option[Try[T]] = Option(value0).asInstanceOf[Option[Try[T]]] + override final def value: Option[Try[T]] = Option(value0) @tailrec // returns null if not completed private final def value0: Try[T] | Null = { diff --git a/library/src/scala/reflect/ClassManifestDeprecatedApis.scala b/library/src/scala/reflect/ClassManifestDeprecatedApis.scala index 2655dac38f54..f3b866f42858 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.nn.toSet ++ Option(next.getSuperclass) + val supers = next.getInterfaces.toSet ++ Option(next.getSuperclass) supers(sup) || { val xs = left ++ supers filterNot seen loop(xs - next, seen + next) @@ -137,6 +137,7 @@ trait ClassManifestDeprecatedApis[T] extends OptManifest[T] { protected def argString = if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]") + // TODO: remove .nn here after 3.8. See #24070 else if (runtimeClass.isArray) "["+ClassManifest.fromClass(runtimeClass.getComponentType.nn)+"]" else "" } diff --git a/project/Build.scala b/project/Build.scala index 4cf7bbb592df..5ebc7af0f5a9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -241,7 +241,7 @@ object Build { "-deprecation", "-unchecked", //"-Wconf:cat=deprecation&msg=Unsafe:s", // example usage - // "-Werror", + "-Werror", //"-Wunused:all", //"-rewrite", // requires -Werror:false since no rewrites are applied with errors "-encoding", "UTF8", @@ -962,6 +962,9 @@ object Build { } }.value, + // TODO: Enable fatal warnings after 3.8 because old stdlib has different nullability. + (Compile / scalacOptions) -= "-Werror", + (Test / testOptions) += Tests.Argument( TestFrameworks.JUnit, "--exclude-categories=dotty.BootstrappedOnlyTests", @@ -1797,7 +1800,7 @@ object Build { Compile / scalacOptions := Seq("-deprecation", "-feature", "-unchecked", "-encoding", "UTF8", "-language:implicitConversions"), Compile / scalacOptions += "-Yno-stdlib-patches", Compile / scalacOptions += "-Yexplicit-nulls", - (Compile / scalacOptions) ++= Seq( + 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), ), @@ -2342,6 +2345,8 @@ object Build { // Make sure that the produced artifacts have the minimum JVM version in the bytecode Compile / javacOptions ++= Seq("--release", Versions.minimumJVMVersion), Compile / scalacOptions ++= Seq("--java-output-version", Versions.minimumJVMVersion), + // TODO: Enable fatal warnings after 3.8 because old stdlib has different nullability. + Compile / scalacOptions -= "-Werror", // Specify the default entry point of the compiler Compile / mainClass := Some("dotty.tools.dotc.Main"), // Add entry's to the MANIFEST From 437660eda8132c00e8b6ac02f7be060ad53c2c49 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 6 Oct 2025 01:50:07 +0200 Subject: [PATCH 44/46] Fix build; remove fromNullable usage --- .../tools/dotc/transform/localopt/FormatChecker.scala | 4 +--- project/Build.scala | 8 +++----- scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala | 4 ++-- .../src/dotty/tools/scaladoc/site/StaticSiteLoader.scala | 4 ++-- scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala index 4184407d07a8..83ec7fb8399e 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala @@ -126,9 +126,7 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List def at(g: SpecGroup): Int = descriptor.start(g.ordinal) def end(g: SpecGroup): Int = descriptor.end(g.ordinal) def offset(g: SpecGroup, i: Int = 0): Int = at(g) + i - def group(g: SpecGroup): Option[String] = - // Unable to use @experimental fromNullable now - Option(descriptor.group(g.ordinal)).asInstanceOf[Option[String]] + def group(g: SpecGroup): Option[String] = Option(descriptor.group(g.ordinal)) def stringOf(g: SpecGroup): String = group(g).getOrElse("") def intOf(g: SpecGroup): Option[Int] = group(g).map(_.toInt) diff --git a/project/Build.scala b/project/Build.scala index 5ebc7af0f5a9..c81821cf80d0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -686,6 +686,9 @@ object Build { // Note: bench/profiles/projects.yml should be updated accordingly. Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Wsafe-init"), + // TODO: Enable fatal warnings after 3.8 because old stdlib has different nullability. + Compile / scalacOptions -= "-Werror", + // Use source 3.3 to avoid fatal migration warnings on scalajs-ir scalacOptions ++= Seq("-source", "3.3"), @@ -962,9 +965,6 @@ object Build { } }.value, - // TODO: Enable fatal warnings after 3.8 because old stdlib has different nullability. - (Compile / scalacOptions) -= "-Werror", - (Test / testOptions) += Tests.Argument( TestFrameworks.JUnit, "--exclude-categories=dotty.BootstrappedOnlyTests", @@ -2345,8 +2345,6 @@ object Build { // Make sure that the produced artifacts have the minimum JVM version in the bytecode Compile / javacOptions ++= Seq("--release", Versions.minimumJVMVersion), Compile / scalacOptions ++= Seq("--java-output-version", Versions.minimumJVMVersion), - // TODO: Enable fatal warnings after 3.8 because old stdlib has different nullability. - Compile / scalacOptions -= "-Werror", // Specify the default entry point of the compiler Compile / mainClass := Some("dotty.tools.dotc.Main"), // Add entry's to the MANIFEST diff --git a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala index 9a79c5a84fe1..00344aa5ad75 100644 --- a/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala +++ b/scaladoc/src/dotty/tools/scaladoc/SourceLinks.scala @@ -74,8 +74,8 @@ class SourceLinkParser(revision: Option[String]) extends ArgParser[SourceLink]: else Right(TemplateSourceLink(supported.foldLeft(string)((template, pattern) => template.replace(pattern, SupportedScalaDocPatternReplacements(pattern))))) case KnownProvider(name: String, organization: String, repo: String, rawRevision, rawSubPath) => - val subPath = Option.fromNullable(rawSubPath).fold("")("/" + _.drop(1)) - val pathRev = Option.fromNullable(rawRevision).map(_.drop(1)).orElse(revision) + val subPath = Option(rawSubPath).fold("")("/" + _.drop(1)) + val pathRev = Option(rawRevision).map(_.drop(1)).orElse(revision) def withRevision(template: String => SourceLink) = pathRev.fold(Left(s"No revision provided"))(r => Right(template(r))) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index e0834ee78ecf..af0d1208c5cb 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -116,8 +116,8 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite def loadBlog(): Option[LoadedTemplate] = { val blogConfig = BlogParser.readYml(root) - val rootPath = Option.fromNullable(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) - val defaultDirectory = Option.fromNullable(blogConfig.output).getOrElse("blog") + val rootPath = Option(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) + val defaultDirectory = Option(blogConfig.output).getOrElse("blog") type Date = (String, String, String) if (!Files.exists(rootPath) || blogConfig.hidden) None diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala index a84137caa5a7..0b38af38a3b3 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala @@ -277,7 +277,7 @@ class SymOpsWithLinkCache: then externalLinkCache(csym.associatedFile) else { def calculatePath(file: AbstractFile): String = file.underlyingSource.filter(_ != file).fold("")(f => calculatePath(f) + "/") + file.path - val calculatedLink = Option.fromNullable(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => + val calculatedLink = Option(csym.associatedFile).map(f => calculatePath(f)).flatMap { path => dctx.externalDocumentationLinks.find(_.originRegexes.exists(r => r.matches(path))) } externalLinkCache += (csym.associatedFile -> calculatedLink) From b50ee944ea42bc4f0e697106e1758081936df858 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 6 Oct 2025 15:43:53 +0200 Subject: [PATCH 45/46] Address comments; polish Prop to disallow setting null string value --- .../collection/convert/AsJavaConverters.scala | 10 +- .../convert/AsScalaConverters.scala | 10 +- library/src/scala/jdk/FunctionWrappers.scala | 426 +++++++++--------- library/src/scala/math/BigInt.scala | 8 +- library/src/scala/sys/BooleanProp.scala | 2 +- library/src/scala/sys/Prop.scala | 2 +- library/src/scala/sys/PropImpl.scala | 4 +- 7 files changed, 234 insertions(+), 228 deletions(-) diff --git a/library/src/scala/collection/convert/AsJavaConverters.scala b/library/src/scala/collection/convert/AsJavaConverters.scala index cabb1fbdf61a..07775f678fdd 100644 --- a/library/src/scala/collection/convert/AsJavaConverters.scala +++ b/library/src/scala/collection/convert/AsJavaConverters.scala @@ -24,15 +24,15 @@ import scala.{unchecked => uc} /** Defines converter methods from Scala to Java collections. * These methods are available through the [[scala.jdk.javaapi.CollectionConverters]] object. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. */ trait AsJavaConverters { import JavaCollectionWrappers._ + // Note: Both the parameter and the return type of the methods in this class are non-nullable. + // However, if a null reference is passed explicitly, the method will still return null. + // We intentionally keep this signature to discourage passing nulls implicitly while preserving the + // previous behavior for backward compatibility. + /** * Converts a Scala `Iterator` to a Java `Iterator`. * diff --git a/library/src/scala/collection/convert/AsScalaConverters.scala b/library/src/scala/collection/convert/AsScalaConverters.scala index 1925af791b6b..fa39ff1d8d37 100644 --- a/library/src/scala/collection/convert/AsScalaConverters.scala +++ b/library/src/scala/collection/convert/AsScalaConverters.scala @@ -25,15 +25,15 @@ import scala.{unchecked => uc} /** Defines converter methods from Java to Scala collections. * These methods are available through the [[scala.jdk.javaapi.CollectionConverters]] object. - * - * Note: Both the parameter and the return type are non-nullable. However, if a null - * reference is passed explicitly, this method will still return null. We intentionally - * keep this signature to discourage passing nulls implicitly while preserving the - * previous behavior for backward compatibility. */ trait AsScalaConverters { import JavaCollectionWrappers._ + // Note: Both the parameter and the return type of the methods in this class are non-nullable. + // However, if a null reference is passed explicitly, the method will still return null. + // We intentionally keep this signature to discourage passing nulls implicitly while preserving the + // previous behavior for backward compatibility. + /** * Converts a Java `Iterator` to a Scala `Iterator`. * diff --git a/library/src/scala/jdk/FunctionWrappers.scala b/library/src/scala/jdk/FunctionWrappers.scala index f4137de041cf..674922d5d60a 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): R = 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): 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): R = 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): R = 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): R = 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): R = 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(): T = 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): 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): 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/math/BigInt.scala b/library/src/scala/math/BigInt.scala index 498cbad8d864..76c4a7caf67f 100644 --- a/library/src/scala/math/BigInt.scala +++ b/library/src/scala/math/BigInt.scala @@ -19,6 +19,7 @@ import scala.language.`2.13` import scala.annotation.nowarn import scala.language.implicitConversions import scala.collection.immutable.NumericRange +import scala.runtime.ScalaRunTime.mapNull object BigInt { @@ -122,9 +123,14 @@ object BigInt { */ implicit def long2bigInt(l: Long): BigInt = apply(l) + // For the following function, both the parameter and the return type are non-nullable. + // However, if a null reference is passed explicitly, this method will still return null. + // We intentionally keep this signature to discourage passing nulls implicitly while + // preserving the previous behavior for backward compatibility. + /** Implicit conversion from `java.math.BigInteger` to `scala.BigInt`. */ - implicit def javaBigInteger2bigInt(x: BigInteger | Null): BigInt | Null = if (x eq null) null else apply(x) + implicit def javaBigInteger2bigInt(x: BigInteger): BigInt = mapNull(x, 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 diff --git a/library/src/scala/sys/BooleanProp.scala b/library/src/scala/sys/BooleanProp.scala index 6afe8658c9ce..723623d72769 100644 --- a/library/src/scala/sys/BooleanProp.scala +++ b/library/src/scala/sys/BooleanProp.scala @@ -50,7 +50,7 @@ object BooleanProp { private[sys] class ConstantImpl(val key: String, val value: Boolean) extends BooleanProp { val isSet = value - def set(newValue: String | Null) = "" + value + def set(newValue: String) = "" + value def setValue[T1 >: Boolean](newValue: T1): Boolean = value def get: String = "" + value def option = if (isSet) Some(value) else None diff --git a/library/src/scala/sys/Prop.scala b/library/src/scala/sys/Prop.scala index 1a6d8c584cdc..6ed7db6f84b8 100644 --- a/library/src/scala/sys/Prop.scala +++ b/library/src/scala/sys/Prop.scala @@ -44,7 +44,7 @@ trait Prop[+T] { * @param newValue the new string value * @return the old value, or null if it was unset. */ - def set(newValue: String | Null): String | Null + def set(newValue: String): String | Null /** Sets the property with a value of the represented type. */ diff --git a/library/src/scala/sys/PropImpl.scala b/library/src/scala/sys/PropImpl.scala index 7f2f1b96b153..455fb65f9a18 100644 --- a/library/src/scala/sys/PropImpl.scala +++ b/library/src/scala/sys/PropImpl.scala @@ -21,14 +21,14 @@ 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 | Null): String | Null = { + def set(newValue: String): String | Null = { val old: String | Null = if (isSet) get else null underlying(key) = newValue old } def setValue[T1 >: T](newValue: T1): T = { val old = value - if (newValue == null) set(null) + if (newValue == null) set(null.asInstanceOf[String]) // will cause NPE in java.lang.System.setProperty else set("" + newValue) old } From e6bd8f4de434b87d0078428851530ee2bcd4a7a4 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Tue, 7 Oct 2025 16:31:17 +0200 Subject: [PATCH 46/46] Update UniquenessCache in sjs --- library-js/src/scala/Symbol.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library-js/src/scala/Symbol.scala b/library-js/src/scala/Symbol.scala index 2d9ac33c8480..a5bbd615ef36 100644 --- a/library-js/src/scala/Symbol.scala +++ b/library-js/src/scala/Symbol.scala @@ -46,7 +46,7 @@ object Symbol extends UniquenessCache[String, Symbol] { } // Modified to use Scala.js specific cache -private[scala] abstract class UniquenessCache[K, V >: Null] { +private[scala] abstract class UniquenessCache[K, V] { private val cache = js.Dictionary.empty[V] protected def valueFromKey(k: String): V