Skip to content

Commit ae0f828

Browse files
authored
Merge pull request #13729 from dotty-staging/wip-expnull-library
enable -Yexplicit-nulls for scala3-library
2 parents 7da659b + 4a1c9f2 commit ae0f828

File tree

6 files changed

+30
-23
lines changed

6 files changed

+30
-23
lines changed

library/src/scala/IArray.scala

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -328,54 +328,59 @@ object IArray:
328328
extension [T, U >: T: ClassTag](x: T)
329329
def +:(arr: IArray[U]): IArray[U] = genericArrayOps(arr).prepended(x)
330330

331+
// For backwards compatibility with code compiled without -Yexplicit-nulls
332+
private inline def mapNull[A, B](a: A, inline f: B): B =
333+
if((a: A|Null) == null) null.asInstanceOf[B] else f
334+
331335
/** Conversion from IArray to immutable.ArraySeq */
332336
implicit def genericWrapArray[T](arr: IArray[T]): ArraySeq[T] =
333-
if arr eq null then null else ArraySeq.unsafeWrapArray(arr)
337+
mapNull(arr, ArraySeq.unsafeWrapArray(arr))
334338

335339
/** Conversion from IArray to immutable.ArraySeq */
336340
implicit def wrapRefArray[T <: AnyRef](arr: IArray[T]): ArraySeq.ofRef[T] =
337341
// Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef]
338342
// is as good as another for all T <: AnyRef. Instead of creating 100,000,000
339343
// unique ones by way of this implicit, let's share one.
340-
if (arr eq null) null
341-
else if (arr.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]]
342-
else ArraySeq.ofRef(arr.asInstanceOf[Array[T]])
344+
mapNull(arr,
345+
if (arr.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]]
346+
else ArraySeq.ofRef(arr.asInstanceOf[Array[T]])
347+
)
343348

344349
/** Conversion from IArray to immutable.ArraySeq */
345350
implicit def wrapIntArray(arr: IArray[Int]): ArraySeq.ofInt =
346-
if (arr ne null) new ArraySeq.ofInt(arr.asInstanceOf[Array[Int]]) else null
351+
mapNull(arr, new ArraySeq.ofInt(arr.asInstanceOf[Array[Int]]))
347352

348353
/** Conversion from IArray to immutable.ArraySeq */
349354
implicit def wrapDoubleIArray(arr: IArray[Double]): ArraySeq.ofDouble =
350-
if (arr ne null) new ArraySeq.ofDouble(arr.asInstanceOf[Array[Double]]) else null
355+
mapNull(arr, new ArraySeq.ofDouble(arr.asInstanceOf[Array[Double]]))
351356

352357
/** Conversion from IArray to immutable.ArraySeq */
353358
implicit def wrapLongIArray(arr: IArray[Long]): ArraySeq.ofLong =
354-
if (arr ne null) new ArraySeq.ofLong(arr.asInstanceOf[Array[Long]]) else null
359+
mapNull(arr, new ArraySeq.ofLong(arr.asInstanceOf[Array[Long]]))
355360

356361
/** Conversion from IArray to immutable.ArraySeq */
357362
implicit def wrapFloatIArray(arr: IArray[Float]): ArraySeq.ofFloat =
358-
if (arr ne null) new ArraySeq.ofFloat(arr.asInstanceOf[Array[Float]]) else null
363+
mapNull(arr, new ArraySeq.ofFloat(arr.asInstanceOf[Array[Float]]))
359364

360365
/** Conversion from IArray to immutable.ArraySeq */
361366
implicit def wrapCharIArray(arr: IArray[Char]): ArraySeq.ofChar =
362-
if (arr ne null) new ArraySeq.ofChar(arr.asInstanceOf[Array[Char]]) else null
367+
mapNull(arr, new ArraySeq.ofChar(arr.asInstanceOf[Array[Char]]))
363368

364369
/** Conversion from IArray to immutable.ArraySeq */
365370
implicit def wrapByteIArray(arr: IArray[Byte]): ArraySeq.ofByte =
366-
if (arr ne null) new ArraySeq.ofByte(arr.asInstanceOf[Array[Byte]]) else null
371+
mapNull(arr, new ArraySeq.ofByte(arr.asInstanceOf[Array[Byte]]))
367372

368373
/** Conversion from IArray to immutable.ArraySeq */
369374
implicit def wrapShortIArray(arr: IArray[Short]): ArraySeq.ofShort =
370-
if (arr ne null) new ArraySeq.ofShort(arr.asInstanceOf[Array[Short]]) else null
375+
mapNull(arr, new ArraySeq.ofShort(arr.asInstanceOf[Array[Short]]))
371376

372377
/** Conversion from IArray to immutable.ArraySeq */
373378
implicit def wrapBooleanIArray(arr: IArray[Boolean]): ArraySeq.ofBoolean =
374-
if (arr ne null) new ArraySeq.ofBoolean(arr.asInstanceOf[Array[Boolean]]) else null
379+
mapNull(arr, new ArraySeq.ofBoolean(arr.asInstanceOf[Array[Boolean]]))
375380

376381
/** Conversion from IArray to immutable.ArraySeq */
377382
implicit def wrapUnitIArray(arr: IArray[Unit]): ArraySeq.ofUnit =
378-
if (arr ne null) new ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]]) else null
383+
mapNull(arr, new ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]]))
379384

380385
/** Convert an array into an immutable array without copying, the original array
381386
* must _not_ be mutated after this or the guaranteed immutablity of IArray will

library/src/scala/reflect/Selectable.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ trait Selectable extends scala.Selectable:
2121
final def selectDynamic(name: String): Any =
2222
val rcls = selectedValue.getClass
2323
try
24-
val fld = rcls.getField(name)
24+
val fld = rcls.getField(name).nn
2525
ensureAccessible(fld)
2626
fld.get(selectedValue)
2727
catch case ex: NoSuchFieldException =>
@@ -35,7 +35,7 @@ trait Selectable extends scala.Selectable:
3535
*/
3636
final def applyDynamic(name: String, paramTypes: Class[_]*)(args: Any*): Any =
3737
val rcls = selectedValue.getClass
38-
val mth = rcls.getMethod(name, paramTypes: _*)
38+
val mth = rcls.getMethod(name, paramTypes: _*).nn
3939
ensureAccessible(mth)
4040
mth.invoke(selectedValue, args.asInstanceOf[Seq[AnyRef]]: _*)
4141

library/src/scala/runtime/LazyVals.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ package scala.runtime
55
*/
66
object LazyVals {
77
private[this] val unsafe: sun.misc.Unsafe =
8-
classOf[sun.misc.Unsafe].getDeclaredFields.find { field =>
9-
field.getType == classOf[sun.misc.Unsafe] && {
10-
field.setAccessible(true)
8+
classOf[sun.misc.Unsafe].getDeclaredFields.nn.find { field =>
9+
field.nn.getType == classOf[sun.misc.Unsafe] && {
10+
field.nn.setAccessible(true)
1111
true
1212
}
1313
}
14-
.map(_.get(null).asInstanceOf[sun.misc.Unsafe])
14+
.map(_.nn.get(null).asInstanceOf[sun.misc.Unsafe])
1515
.getOrElse {
1616
throw new ExceptionInInitializerError {
1717
new IllegalStateException("Can't find instance of sun.misc.Unsafe")
1818
}
1919
}
2020

2121
private[this] val base: Int = {
22-
val processors = java.lang.Runtime.getRuntime.availableProcessors()
22+
val processors = java.lang.Runtime.getRuntime.nn.availableProcessors()
2323
8 * processors * processors
2424
}
2525
private[this] val monitors: Array[Object] =

library/src/scala/runtime/Scala3RunTime.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ object Scala3RunTime:
1515
* Extracted to minimize the bytecode size at call site.
1616
*/
1717
def nn[T](x: T | Null): x.type & T =
18-
if (x == null) throw new NullPointerException("tried to cast away nullability, but value is null")
18+
val isNull = x == null
19+
if (isNull) throw new NullPointerException("tried to cast away nullability, but value is null")
1920
else x.asInstanceOf[x.type & T]
2021

2122
end Scala3RunTime

library/src/scala/util/FromDigits.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ object FromDigits {
135135
case ex: NumberFormatException => throw MalformedNumber()
136136
}
137137
if (x.isInfinite) throw NumberTooLarge()
138-
if (x == 0.0f && !zeroFloat.pattern.matcher(digits).matches) throw NumberTooSmall()
138+
if (x == 0.0f && !zeroFloat.pattern.matcher(digits).nn.matches) throw NumberTooSmall()
139139
x
140140
}
141141

@@ -153,7 +153,7 @@ object FromDigits {
153153
case ex: NumberFormatException => throw MalformedNumber()
154154
}
155155
if (x.isInfinite) throw NumberTooLarge()
156-
if (x == 0.0d && !zeroFloat.pattern.matcher(digits).matches) throw NumberTooSmall()
156+
if (x == 0.0d && !zeroFloat.pattern.matcher(digits).nn.matches) throw NumberTooSmall()
157157
x
158158
}
159159

project/Build.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ object Build {
790790
(Compile / scalacOptions) ++= Seq(
791791
// Needed so that the library sources are visible when `dotty.tools.dotc.core.Definitions#init` is called
792792
"-sourcepath", (Compile / sourceDirectories).value.map(_.getAbsolutePath).distinct.mkString(File.pathSeparator),
793+
"-Yexplicit-nulls",
793794
),
794795
)
795796

0 commit comments

Comments
 (0)