Enum widening sabotages match types
See original GitHub issueIt 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 😃 )
Issue Analytics
- State:
- Created 10 months ago
- Comments:15 (12 by maintainers)
Top GitHub Comments
Currently, only match expressions with patterns of the form
t: T
can be typed as match types.You could rewrite your example as:
Yet, considering that match types are a new thing, this really could be considered a bug and fixed without the need for any
precise
modifier on the type. Intuitively, the match type is supposed to work here, and a code that currently assumes otherwise (if such code exists) should be considered invalid.