Skip to content

Enum widening sabotages match types #16299

Open
@b-studios

Description

@b-studios

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 :) )

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions