I was looking at ways of making non-exhaustive matches a compile error in Scala when I saw the flag -Xlint:unsound-match
. I couldn't find much information on it, however, and the one example I found works the same with and without the flag, so I really don't know when it would be helpful. Can someone explain it and/or provide an example of a match that compiles without warnings in the absence of this flag, but generates a warning with it?
The following program compiles just fine, but then crashes with a ClassCastException at runtime:
case class A()
object B extends A() {
def bar() = println("only B has this method")
}
A() match {
case x @ B => x.bar()
case _ => ()
}
This happens because ==
is used to check whether x
is B
, but in this case, ==
behaves very strangely:
case class A()
object B extends A()
B == A() // returns true, because extending from case classes is evil.
This seems to happen because B
inherits the equals
from the case class, so that
B == a
for all a: A
, but at the same timea: B.type
is false for almost all a: A
(all except B
itself).When compiled with -Xlint:unsound-match
on an older scalac version (e.g. 2.15), the code produces the following warning:
warning: The value matched by $anon.this.B is bound to x, which may be used under the
unsound assumption that it has type this.B.type, whereas we can only safely
count on it having type this.A, as the pattern is matched using `==` (see scala/bug#1503).
case x @ B => x.bar()
^
one warning found
whereas without -Xlint
, nothing happens.
Note that the -Xlint:unsound-match
seems to have been removed in more recent versions of the compiler (at least I couldn't find it in the most recent commit), so, apparently, it doesn't do anything at all now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With