Description
It looks like widening of enums gets into the way when trying to use match types on them. I guess this is expected behavior, but it is still really sad.
Compiler version
Scala 3.2.0
Minimized example
enum Target {
case Foo(n: Int)
case Bar(s: String)
}
enum Source {
case Foo(n: Int)
case Bar(s: String)
}
type resolved[T] = T match {
case Source.Foo => Target.Foo
case Source.Bar => Target.Bar
}
def resolve[S <: Source](src: S): resolved[S] = ???
Now, for
val foo: Target.Foo = resolve(Source.Foo(42))
the match type gets stuck since Foo
will be widened to Source
.
Manually annotating works
val foo: Target.Foo = resolve(Source.Foo(42) : Source.Foo)
but is infeasible in practice.
Discussion
Context: I want to use enums to model ADTs in a compiler. Different phases have different trees. Match types could really nicely tell which tree types in the source are translated to which in the next phase. Manually "downcasting" by ascribing the call does not work, since I literally would have to annotate over 1000 of such calls.
In general, I am not a big fan of the widening behavior. I do understand the design considerations, but overall would be happier without it.
(Please feel free to immediately close and mark as won't fix :) )