Should we disallow type Null in a type pattern or isInstanceOf test like scalac does to avoid surprising behaviors?
Dotty:
scala> null.isInstanceOf[Null]
val res0: Boolean = false
Scalac:
scala> null.isInstanceOf[Null]
<console>:12: error: type Null cannot be used in a type pattern or isInstanceOf test
null.isInstanceOf[Null]
^
I would say yes, same with Singleton.
Maybe we should translate null.isInstanceOf[Null] into null eq null. Like we currently do with singleton types, we translate val o = ""; "".isInstanceOf[o.type] becomes val o = ""; "" eq o.
But what's the usecase? :)
This can only be done if the callee is a subtype of AnyRef. Otherwise, it should be disallowed or 0.isInstanceOf[Null] might say true.
The main point is that we should at least not do it for singletons. The one with Null might be useful in cases where an isInstanceOf check is inserted by the compiler for some reason (not sure if it ever happens).
The one with Null might be useful in cases where an isInstanceOf check is inserted by the compiler for some reason (not sure if it ever happens).
So somebody could just forbid isInstanceOf[Null] and see if something breaks. Volunteers? @liufengyun maybe in your PR when you have time?
Pattern matching with singleton types (which is equivalent to isInstanceOf, IIUC) is useful (at least a bit) with GADTs:
def f[T, U](t: Foo[T], u: Foo[U]) =
t match {
case _: u.type => // Here T and U are equal
}
An actual use case is in ECOOP'07 Burak Emir's paper on case classes, and that code still works today in Scala (though IIRC not yet in Dotty).
Most helpful comment
I would say yes, same with Singleton.