//> using scala 3.8.1
case object Err
type Err = Err.type
enum Plan[+E <: Err] {
case A()
case B()
case C()
final inline def narrow[Sub <: Plan[Err]](inline fn: Sub => String): Option[String] =
this match {
case a: Sub => Some(fn(a))
case other => None
}
}
@main def main = {
val plan = Plan.A()
println(plan.narrow[Plan.A[Err]](_.toString)) // Some(A())
println(plan.narrow[Plan.B[Err]](_.toString)) // None, therefore the 'other' case is actually reachable!
}
$ scala run .
Compiling project (Scala 3.8.1, JVM (17))
[warn] ./Plan.scala:14:12
[warn] Unreachable case except for null (if this is intentional, consider writing case null => instead).
[warn] case other => None
[warn] ^^^^^
Compiled project (Scala 3.8.1, JVM (17))
Some(A())
None