It would be best to open issue on Scala 3 GH issues so that you can reach directly to the compiler team working on explicit null
As a side note if you’re having a performance requirements you most likely should not use Int | Null - it would require to box primitive scala.Int into java.lang.Integer at all times.
The problem however also applies to cases where we’re dealing with reference types (so there won’t be any additional performance penalty)
//> using options -Yexplicit-nulls
def example = {
var buf: List[Int] | Null = null
buf = List(0)
buf ::= List(1, 2, 3) // error: value ::= is not a member of List[Int] | Null
}
See what compiler would actually need to emit below:
// //> using options -Yexplicit-nulls
def exmaple = {
var x: Int | Null = null
println(x)
x = x.nn + 1
println(x)
}
> scala compile a1.scala -Vprint:genBCode
Compiling project (Scala 3.7.4, JVM (21))
[[syntax trees at end of genBCode]] // /Users/wmazur/projects/scala/scala3/a1.scala
package <empty> {
@SourceFile("a1.scala") final module class a1$package extends Object {
def <init>(): Unit =
{
super()
()
}
private def writeReplace(): Object =
new scala.runtime.ModuleSerializationProxy(classOf[a1$package])
def exmaple(): Unit =
{
var x: Object = null
println(x)
x =
Int.box(
{
val x$proxy1: Object = x
{
(if x$proxy1:Object == null then
scala.runtime.Scala3RunTime.nnFail() else ())
Int.unbox(x$proxy1:Object)
}:Int + 1
}
)
println(Int.box(Int.unbox(x:Object)))
}
}
final lazy module val a1$package: a1$package = new a1$package()
}
For comparsion variant using only primitive Int
> scala compile a1.scala -Vprint:genBCode
Compiling project (Scala 3.7.4, JVM (21))
[[syntax trees at end of genBCode]] // /Users/wmazur/projects/scala/scala3/a1.scala
package <empty> {
@SourceFile("a1.scala") final module class a1$package extends Object {
def <init>(): Unit =
{
super()
()
}
private def writeReplace(): Object =
new scala.runtime.ModuleSerializationProxy(classOf[a1$package])
def exmaple(): Unit =
{
var x: Int = 0
println(Int.box(x))
x = x + 1
println(Int.box(x))
}
}
final lazy module val a1$package: a1$package = new a1$package()
}