I would really like to have a new warning type for pattern matches in which the matched case looks for traits that are not an immediate type of the unwrapped type.
For example:
class Foo
object Foo1 extends Foo
object Foo2 extends Foo
case class Bar(foo: Foo)
Bar(Foo1) match {
case Bar(Seq(1)) => "compiles no warning"
case Bar(s: Seq[_]) => "compiles no warning"
case Bar(List(1)) => "compiles with warning"
case Bar(Foo2) => "oh no :("
case Bar(Foo1) => "hooray!"
}
The pattern match on Bar(List(1))
yields a “fruitless type test” warning as List
is a class and Foo
does not extend from it.
Seq
on the other hand is a trait, which means that even though Foo
does not extend it by definition, it can always be anonymously mixed in via new Foo with Seq[Any]
. This results in no warning whatsoever on the pattern match.
It would be useful to have such a warning, especially in cases where one wishes to refactor a case class that previously held a Seq
(or any other trait) and now holds a different type:
// from
case class Foo(items: Seq[String])
// to
case class Items(...)
case class Foo(items: Items)
Without such a warning, one has to manually find all instances of pattern matching on the case class with Seq
:
foo match {
case Foo(Seq("1")) => ...
...
}
Which is prone to error that is only discoverable at runtime!
I’m really unsure whether this warning should be enabled by default, but in any case it would be extremely helpful to back-port it to earlier versions (i.e not just 2.13
).