Skip to content

Commit 7cd54aa

Browse files
noti0na1hamzaremmal
authored andcommitted
Port stdlib to explicit nulls
1 parent a434d11 commit 7cd54aa

File tree

90 files changed

+1353
-1331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1353
-1331
lines changed

library/src/scala/Enumeration.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
107107
private val vmap: mutable.Map[Int, Value] = new mutable.HashMap
108108

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

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

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

133-
private def nextNameOrNull =
133+
private def nextNameOrNull: String | Null =
134134
if (nextName != null && nextName.hasNext) nextName.next() else null
135135

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

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

192192
private def populateNameMap(): Unit = {
193193
@tailrec def getFields(clazz: Class[_], acc: Array[JField]): Array[JField] = {
@@ -248,7 +248,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
248248
* identification behaviour.
249249
*/
250250
@SerialVersionUID(0 - 3501153230598116017L)
251-
protected class Val(i: Int, name: String) extends Value with Serializable {
251+
protected class Val(i: Int, name: String | Null) extends Value with Serializable {
252252
def this(i: Int) = this(i, nextNameOrNull)
253253
def this(name: String) = this(nextId, name)
254254
def this() = this(nextId)

library/src/scala/Predef.scala

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ object Predef extends LowPriorityImplicits {
122122
* @return The runtime [[Class]] representation of type `T`.
123123
* @group utilities
124124
*/
125-
def classOf[T]: Class[T] = null // This is a stub method. The actual implementation is filled in by the compiler.
125+
def classOf[T]: Class[T] = null.asInstanceOf[Class[T]] // This is a stub method. The actual implementation is filled in by the compiler.
126126

127127
/**
128128
* Retrieve the single value of a type with a unique inhabitant.
@@ -657,46 +657,46 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2
657657
@inline implicit def booleanWrapper(x: Boolean): runtime.RichBoolean = new runtime.RichBoolean(x)
658658

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

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

674674
/** @group conversions-array-to-wrapped-array */
675-
implicit def wrapIntArray(xs: Array[Int]): ArraySeq.ofInt = if (xs ne null) new ArraySeq.ofInt(xs) else null
675+
implicit def wrapIntArray(xs: Array[Int] | Null): ArraySeq.ofInt | Null = if (xs ne null) new ArraySeq.ofInt(xs) else null
676676
/** @group conversions-array-to-wrapped-array */
677-
implicit def wrapDoubleArray(xs: Array[Double]): ArraySeq.ofDouble = if (xs ne null) new ArraySeq.ofDouble(xs) else null
677+
implicit def wrapDoubleArray(xs: Array[Double] | Null): ArraySeq.ofDouble | Null = if (xs ne null) new ArraySeq.ofDouble(xs) else null
678678
/** @group conversions-array-to-wrapped-array */
679-
implicit def wrapLongArray(xs: Array[Long]): ArraySeq.ofLong = if (xs ne null) new ArraySeq.ofLong(xs) else null
679+
implicit def wrapLongArray(xs: Array[Long] | Null): ArraySeq.ofLong | Null = if (xs ne null) new ArraySeq.ofLong(xs) else null
680680
/** @group conversions-array-to-wrapped-array */
681-
implicit def wrapFloatArray(xs: Array[Float]): ArraySeq.ofFloat = if (xs ne null) new ArraySeq.ofFloat(xs) else null
681+
implicit def wrapFloatArray(xs: Array[Float] | Null): ArraySeq.ofFloat | Null = if (xs ne null) new ArraySeq.ofFloat(xs) else null
682682
/** @group conversions-array-to-wrapped-array */
683-
implicit def wrapCharArray(xs: Array[Char]): ArraySeq.ofChar = if (xs ne null) new ArraySeq.ofChar(xs) else null
683+
implicit def wrapCharArray(xs: Array[Char] | Null): ArraySeq.ofChar | Null = if (xs ne null) new ArraySeq.ofChar(xs) else null
684684
/** @group conversions-array-to-wrapped-array */
685-
implicit def wrapByteArray(xs: Array[Byte]): ArraySeq.ofByte = if (xs ne null) new ArraySeq.ofByte(xs) else null
685+
implicit def wrapByteArray(xs: Array[Byte] | Null): ArraySeq.ofByte | Null = if (xs ne null) new ArraySeq.ofByte(xs) else null
686686
/** @group conversions-array-to-wrapped-array */
687-
implicit def wrapShortArray(xs: Array[Short]): ArraySeq.ofShort = if (xs ne null) new ArraySeq.ofShort(xs) else null
687+
implicit def wrapShortArray(xs: Array[Short] | Null): ArraySeq.ofShort | Null = if (xs ne null) new ArraySeq.ofShort(xs) else null
688688
/** @group conversions-array-to-wrapped-array */
689-
implicit def wrapBooleanArray(xs: Array[Boolean]): ArraySeq.ofBoolean = if (xs ne null) new ArraySeq.ofBoolean(xs) else null
689+
implicit def wrapBooleanArray(xs: Array[Boolean] | Null): ArraySeq.ofBoolean | Null = if (xs ne null) new ArraySeq.ofBoolean(xs) else null
690690
/** @group conversions-array-to-wrapped-array */
691-
implicit def wrapUnitArray(xs: Array[Unit]): ArraySeq.ofUnit = if (xs ne null) new ArraySeq.ofUnit(xs) else null
691+
implicit def wrapUnitArray(xs: Array[Unit] | Null): ArraySeq.ofUnit | Null = if (xs ne null) new ArraySeq.ofUnit(xs) else null
692692

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

697697
private[scala] abstract class LowPriorityImplicits2 {
698698
@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")
699-
implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T]): IndexedSeq[T] =
699+
implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T] | Null): IndexedSeq[T] | Null =
700700
if (xs eq null) null
701701
else new ArrayOps(xs).toIndexedSeq
702702
}

library/src/scala/Specializable.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ object Specializable {
2424
trait SpecializedGroup
2525

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

29-
final val Primitives: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit)] = null
30-
final val Everything: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef)] = null
31-
final val Bits32AndUp: Group[(Int, Long, Float, Double)] = null
32-
final val Integral: Group[(Byte, Short, Int, Long, Char)] = null
33-
final val AllNumeric: Group[(Byte, Short, Int, Long, Char, Float, Double)] = null
34-
final val BestOfBreed: Group[(Int, Double, Boolean, Unit, AnyRef)] = null
35-
final val Unit: Group[Tuple1[Unit]] = null
29+
final val Primitives: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit)] = null.asInstanceOf
30+
final val Everything: Group[(Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef)] = null.asInstanceOf
31+
final val Bits32AndUp: Group[(Int, Long, Float, Double)] = null.asInstanceOf
32+
final val Integral: Group[(Byte, Short, Int, Long, Char)] = null.asInstanceOf
33+
final val AllNumeric: Group[(Byte, Short, Int, Long, Char, Float, Double)] = null.asInstanceOf
34+
final val BestOfBreed: Group[(Int, Double, Boolean, Unit, AnyRef)] = null.asInstanceOf
35+
final val Unit: Group[Tuple1[Unit]] = null.asInstanceOf
3636

37-
final val Arg: Group[(Int, Long, Float, Double)] = null
38-
final val Args: Group[(Int, Long, Double)] = null
39-
final val Return: Group[(Int, Long, Float, Double, Boolean, Unit)] = null
37+
final val Arg: Group[(Int, Long, Float, Double)] = null.asInstanceOf
38+
final val Args: Group[(Int, Long, Double)] = null.asInstanceOf
39+
final val Return: Group[(Int, Long, Float, Double, Boolean, Unit)] = null.asInstanceOf
4040
}

library/src/scala/collection/Iterator.scala

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
124124
private[this] var hd: A = _
125125
private[this] var hdDefined: Boolean = false
126126

127-
128127
def head: A = {
129128
if (!hdDefined) {
130129
hd = next()
@@ -161,12 +160,12 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
161160

162161
require(size >= 1 && step >= 1, f"size=$size%d and step=$step%d, but both must be positive")
163162

164-
private[this] var buffer: Array[B] = null // current result
165-
private[this] var prev: Array[B] = null // if sliding, overlap from previous result
163+
private[this] var buffer: Array[B] | Null = null // current result
164+
private[this] var prev: Array[B] | Null = null // if sliding, overlap from previous result
166165
private[this] var first = true // if !first, advancing may skip ahead
167166
private[this] var filled = false // whether the buffer is "hot"
168167
private[this] var partial = true // whether to emit partial sequence
169-
private[this] var padding: () -> B = null // what to pad short sequences with
168+
private[this] var padding: (() -> B) | Null = null // what to pad short sequences with
170169
private[this] def pad = padding != null // irrespective of partial flag
171170
private[this] def newBuilder = {
172171
val b = ArrayBuilder.make[Any]
@@ -189,7 +188,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
189188
* @note This method is mutually exclusive with `withPartial`.
190189
* @group Configuration
191190
*/
192-
def withPadding(x: -> B): this.type = {
191+
def withPadding(x: => B): this.type = {
193192
padding = () => x
194193
partial = true // redundant, as padding always results in complete segment
195194
this
@@ -230,7 +229,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
230229
val builder = newBuilder
231230
var done = false
232231
// keep prefix of previous buffer if stepping
233-
if (prev != null) builder.addAll(prev)
232+
if (prev != null) builder.addAll(prev.nn)
234233
// skip ahead
235234
if (!first && step > size) {
236235
var dropping = step - size
@@ -251,7 +250,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
251250
if (index < size && pad) {
252251
builder.sizeHint(size)
253252
while (index < size) {
254-
builder.addOne(padding())
253+
builder.addOne(padding.nn())
255254
index += 1
256255
}
257256
}
@@ -275,11 +274,11 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
275274
filled = false
276275
// if stepping, retain overlap in prev
277276
if (step < size) {
278-
if (first) prev = buffer.drop(step)
279-
else if (buffer.length == size) Array.copy(src = buffer, srcPos = step, dest = prev, destPos = 0, length = size - step)
277+
if (first) prev = buffer.nn.drop(step)
278+
else if (buffer.nn.length == size) Array.copy(src = buffer.nn, srcPos = step, dest = prev.nn, destPos = 0, length = size - step)
280279
else prev = null
281280
}
282-
val res = immutable.ArraySeq.unsafeWrapArray(buffer).asInstanceOf[immutable.ArraySeq[B]]
281+
val res = immutable.ArraySeq.unsafeWrapArray(buffer.nn).asInstanceOf[immutable.ArraySeq[B]]
283282
buffer = null
284283
first = false
285284
res
@@ -702,7 +701,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
702701
* handling of structural calls. It's not what's intended here.
703702
*/
704703
final class Leading extends AbstractIterator[A] {
705-
private[this] var lookahead: mutable.Queue[A] = null
704+
private[this] var lookahead: mutable.Queue[A] | Null = null
706705
private[this] var hd: A = _
707706
/* Status is kept with magic numbers
708707
* 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
713712
private[this] var status = 0
714713
private def store(a: A): Unit = {
715714
if (lookahead == null) lookahead = new mutable.Queue[A]
716-
lookahead += a
715+
lookahead.nn += a
717716
}
718717
def hasNext = {
719-
if (status < 0) (lookahead ne null) && lookahead.nonEmpty
718+
if (status < 0) (lookahead ne null) && lookahead.nn.nonEmpty
720719
else if (status > 0) true
721720
else {
722721
if (self.hasNext) {
@@ -730,7 +729,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
730729
def next() = {
731730
if (hasNext) {
732731
if (status == 1) { status = 0; hd }
733-
else lookahead.dequeue()
732+
else lookahead.nn.dequeue()
734733
}
735734
else Iterator.empty.next()
736735
}
@@ -757,7 +756,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
757756
val leading = new Leading
758757

759758
val trailing = new AbstractIterator[A] {
760-
private[this] var myLeading = leading
759+
private[this] var myLeading: Leading | Null = leading
761760
/* Status flag meanings:
762761
* -1 not yet accessed
763762
* 0 single element waiting in leading
@@ -772,13 +771,13 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
772771
case 1 => if (self.hasNext) { status = 2 ; true } else { status = 3 ; false }
773772
case 0 => true
774773
case _ =>
775-
if (myLeading.finish()) { status = 0 ; true } else { status = 1 ; myLeading = null ; hasNext }
774+
if (myLeading.nn.finish()) { status = 0 ; true } else { status = 1 ; myLeading = null ; hasNext }
776775
}
777776
def next() = {
778777
if (hasNext) {
779778
if (status == 0) {
780779
status = 1
781-
val res = myLeading.trailer
780+
val res = myLeading.nn.trailer
782781
myLeading = null
783782
res
784783
} else {
@@ -873,7 +872,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
873872
*/
874873
def duplicate: (Iterator[A]^{this}, Iterator[A]^{this}) = {
875874
val gap = new scala.collection.mutable.Queue[A]
876-
var ahead: Iterator[A]^ = null
875+
var ahead: (Iterator[A]^) | Null = null
877876
class Partner extends AbstractIterator[A] {
878877
override def knownSize: Int = self.synchronized {
879878
val thisSize = self.knownSize
@@ -1149,10 +1148,13 @@ object Iterator extends IterableFactory[Iterator] {
11491148
/** Creates an iterator to which other iterators can be appended efficiently.
11501149
* Nested ConcatIterators are merged to avoid blowing the stack.
11511150
*/
1152-
private final class ConcatIterator[+A](val from: Iterator[A @uncheckedVariance]^) extends AbstractIterator[A] {
1153-
private var current: Iterator[A]^{from} = from
1154-
private var tail: ConcatIteratorCell[A @uncheckedVariance] = null
1155-
private var last: ConcatIteratorCell[A @uncheckedVariance] = null
1151+
private final class ConcatIterator[+A](val from: (Iterator[A @uncheckedVariance]^) | Null) extends AbstractIterator[A] {
1152+
@annotation.stableNull
1153+
private var current: Iterator[A]^{from} | Null = from
1154+
@annotation.stableNull
1155+
private var tail: ConcatIteratorCell[A @uncheckedVariance] | Null = null
1156+
@annotation.stableNull
1157+
private var last: ConcatIteratorCell[A @uncheckedVariance] | Null = null
11561158
private var currentHasNextChecked = false
11571159

11581160
def hasNext =
@@ -1171,7 +1173,7 @@ object Iterator extends IterableFactory[Iterator] {
11711173
currentHasNextChecked = c.currentHasNextChecked
11721174
if (c.tail != null) {
11731175
if (last == null) last = c.last
1174-
c.last.tail = tail
1176+
c.last.nn.tail = tail
11751177
tail = c.tail
11761178
}
11771179
merge()
@@ -1186,9 +1188,9 @@ object Iterator extends IterableFactory[Iterator] {
11861188
false
11871189
}
11881190
else {
1189-
current = tail.headIterator
1190-
if (last eq tail) last = last.tail
1191-
tail = tail.tail
1191+
current = tail.nn.headIterator
1192+
if (last eq tail) last = last.nn.tail
1193+
tail = tail.nn.tail
11921194
merge()
11931195
if (currentHasNextChecked) true
11941196
else if (current != null && current.hasNext) {
@@ -1203,7 +1205,7 @@ object Iterator extends IterableFactory[Iterator] {
12031205
def next() =
12041206
if (hasNext) {
12051207
currentHasNextChecked = false
1206-
current.next()
1208+
current.nn.next()
12071209
} else Iterator.empty.next()
12081210

12091211
override def concat[B >: A](that: => IterableOnce[B]^): Iterator[B]^{this, that} = {
@@ -1213,15 +1215,15 @@ object Iterator extends IterableFactory[Iterator] {
12131215
last = c
12141216
}
12151217
else {
1216-
last.tail = c
1218+
last.nn.tail = c
12171219
last = c
12181220
}
12191221
if (current == null) current = Iterator.empty
12201222
this
12211223
}
12221224
}
12231225

1224-
private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^, var tail: ConcatIteratorCell[A]^) {
1226+
private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^, var tail: (ConcatIteratorCell[A]^) | Null) {
12251227
def headIterator: Iterator[A]^{this} = head.iterator
12261228
}
12271229

@@ -1289,7 +1291,7 @@ object Iterator extends IterableFactory[Iterator] {
12891291
*/
12901292
private final class UnfoldIterator[A, S](init: S)(f: S => Option[(A, S)]) extends AbstractIterator[A] {
12911293
private[this] var state: S = init
1292-
private[this] var nextResult: Option[(A, S)] = null
1294+
private[this] var nextResult: Option[(A, S)] | Null = null
12931295

12941296
override def hasNext: Boolean = {
12951297
if (nextResult eq null) {
@@ -1300,12 +1302,12 @@ object Iterator extends IterableFactory[Iterator] {
13001302
}
13011303
state = null.asInstanceOf[S] // allow GC
13021304
}
1303-
nextResult.isDefined
1305+
nextResult.nn.isDefined
13041306
}
13051307

13061308
override def next(): A = {
13071309
if (hasNext) {
1308-
val (value, newState) = nextResult.get
1310+
val (value, newState) = nextResult.nn.get
13091311
state = newState
13101312
nextResult = null
13111313
value

0 commit comments

Comments
 (0)