Skip to content

"Unreachable case" is, in fact, reachable #23113

@durban

Description

@durban

Compiler version

3.3.5

Minimized code

package com.example

object Repro {

  sealed abstract class Listener[A]

  final case class Empty[A]()
    extends Listener[A]

  final case class Waiting[A](next: Promise[A])
    extends Listener[A]

  def foo[A](l: Listener[A]): Unit = {
    l match {
      case Empty() => println("empty")
      case w @ Waiting(_) => println(s"waiting: ${w.next}") // <-- HERE
    }
  }

  def main(args: Array[String]): Unit = {
    foo(Waiting(Promise()))
  }
}

sealed trait Promise[A]

object Promise {

  def apply[A](): Promise[A] = new PromiseImpl[A](null)

  private[this] abstract class PromiseBase[A] extends Promise[A]

  private[this] final class PromiseImpl[A](val st: Waiting[A]) extends PromiseBase[A]

  private[this] final class Waiting[A]
}

Output

[warn] -- [E030] Match case Unreachable Warning: /home/.../Repro.scala:... 
[warn] 33 |      case w @ Waiting(_) => println(s"waiting: ${w.next}")
[warn]    |           ^^^^^^^^^^^^^^
[warn]    |           Unreachable case
[warn] Matching filters for @nowarn or -Wconf:
[warn]   - id=E30
[warn]   - name=MatchCaseUnreachable
[warn] one warning found
[info] running com.example.Repro 
waiting: com.example.Promise$PromiseImpl@d3995d

Expectation

I'd expect no "Unreachable case" warning for a case which is reachable.

Activity

som-snytt

som-snytt commented on May 7, 2025

@som-snytt
Contributor

It's quiet for case w: Waiting[?] =>.

Maybe there's something special about Scala 3 pattern matching, but this looks like it should be easy. Speaking as a peanut gallery member.

added
area:reportingError reporting including formatting, implicit suggestions, etc
better-errorsIssues concerned with improving confusing/unhelpful diagnostic messages
and removed
stat:needs triageEvery issue needs to have an "area" and "itype" label
on May 7, 2025
added a commit that references this issue on May 30, 2025
b396ee5
linked a pull request that will close this issue on May 30, 2025
marq

marq commented on Jul 16, 2025

@marq

I've encountered something similar. Looking at the linked PR it may be the same, if it's not I can create a new issue.
Compiler version: 3.3.4+

sealed trait A

case object A0 extends A

class B {
  final case class C(i: Int) extends A

  def c(i: Int): A = C(i)
}

def a: A = new B().c(1)

Option(a).collect {
  case c: B#C => c.i // 'Unreachable case' warning
}.foreach(println)

a match {
  case c: B#C => println(c.i) // no warning
  case _ =>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pattern-matchingarea:reportingError reporting including formatting, implicit suggestions, etcbetter-errorsIssues concerned with improving confusing/unhelpful diagnostic messagesitype:bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @som-snytt@marq@durban@Gedochao

      Issue actions

        "Unreachable case" is, in fact, reachable · Issue #23113 · scala/scala3