I think this is a bug. The enum only has two options, but the compiler does not recognize this as being exhaustive.
enum S[T](t: T) {
case SA extends S("str")
case SB extends S(10)
}
case class Merged[T](a: S[T], b: T)
def f(m: Merged[?]): Unit =
m match {
case Merged(S.SA, s) => println(s)
case Merged(S.SB, x) => println(x)
}
I recall that there is something finicky in how pattern matching decides whether to warn? 20 minutes later ⌠I see I looked at Scala 2 patmat a few years ago, where it doesnât warn if a type is âswitchableâ. I donât know (to coin a phrase), but maybe not knowing the type of s or x leads to warning, even though the âvariable patternâ matches all values.
iâm just thinking loud and guessing as i have no knowledge of scala compiler internals.
is the compiler doing âmulti-pathâ exhaustiveness checks? here if the compiler starts doing exhaustiveness checking by picking b and checking if the cases exhaustively match all possible values then that will fail. the compiler then would need to backtrack and pick a and then do exhaustiveness check and this time it would succeed.
btw:
iâve found a (hopefully) non-intrusive hack to make it compile
enum S[T](t: T) {
case SA extends S("str")
case SB extends S(10)
}
type Id[T] = T
case class Merged[T](a: S[T], b: Id[T])
def f(m: Merged[?]): Unit =
m match {
case Merged(S.SA, s) => println(s)
case Merged(S.SB, x) => println(x)
}
just wrapping b: T in Id[T] i.e. a no-op. if this works then the original version should work too, i.e. the miscompilation seems like a bug then.