When using explicit nulls, following the SIP I’m trying to rely solely on subtype relationship, and so I tried the following match type
type AdmitsNull[T] = Null match {
case T => true
case _ => false
}
summon[AdmitsNull[String | Null] =:= true] // works
summon[AdmitsNull[String] =:= false]
//Cannot prove that AdmitsNull[String] =:= (false : Boolean).
//Note: a match type could not be fully reduced:
// trying to reduce AdmitsNull[String]
// failed since selector Null
// is uninhabited (there are no values of that type)
I don’t quite understand the thing about null being uninhabited (although it seems to me that it is, after all null is a value of that set, unlike the Nothing type), since the match is not asking that question, but rather if T is a super type of Null.
If I change Null to Unit, it works in every case too and Unit should be the same (as I understand it) as Null in terms of inhabitants.
Oh, sorry, I thought I was using 3.4.0 in my testing but I was actually using 3.3.3.
It works with Scala 3.3.3 but not 3.4.0 :-/
To be clear, this compiles:
//> using scala 3.3.3
//> using options -Yexplicit-nulls
type AdmitsNull[T] = Null match {
case T => true
case _ => false
}
def testAdmitsNull(): Unit =
summon[AdmitsNull[String | Null] =:= true]
summon[AdmitsNull[String] =:= false]
but changing to using scala 3.4.0 makes the same code fail with:
Compiling project (Scala 3.4.0, JVM (21))
[error] ./AdmitsNull.scala:11:39
[error] Cannot prove that AdmitsNull[String] =:= (false : Boolean).
[error]
[error] Note: a match type could not be fully reduced:
[error]
[error] trying to reduce AdmitsNull[String]
[error] failed since selector Null
[error] is uninhabited (there are no values of that type).
[error] summon[AdmitsNull[String] =:= false]
[error] ^
Error compiling project (Scala 3.4.0, JVM (21))
… as you had initially reported. Sorry for the noise.
However, for match types, we consider Null to be a bottom type like Nothing. This is a compromise. If we did not do this, nothing would ever be disjoint from anything because they would always have null in common.
With -Xexplicit-nulls we might change that, but it has to be part of what the explicit nulls proposal brings to the table.