Skip to content

False pattern match not exhaustive for union types + opaque types #23620

@road21

Description

@road21

Compiler version

3.3.6, 3.7.1

Minimized code

//> using scala 3.7.1

trait Foo
trait Bar

type FooOrBar = FooOrBar.Type
object FooOrBar:
  opaque type Type <: (Foo | Bar) = Foo | Bar

  def bar: FooOrBar = new Bar {}

trait Buz

@main def main =
  val p: FooOrBar | Buz = FooOrBar.bar

  p match
    case _: Foo => println("foo")
    case _: Buz => println("buz")
    case _: Bar => println("bar")

Output

[warn] match may not be exhaustive.
[warn] 
[warn] It would fail on pattern case: _: FooOrBar
[warn]   p match
[warn]   ^

Expectation

no compiler warning

The problem is that it's unsafe to @nowarn annotation here, because it's easy to forget one of the cases (Bar for example) and get real non-exhaustiveness.

Workaround can be to reimplement pattern matching like:
https://scastie.scala-lang.org/road21/3itBzkqmRLeTtXckc0pFWQ/10

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