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.