Skip to content

Unreachable case false-positive for type-parametered boolean extractors #21829

Open
@ivan-klass

Description

@ivan-klass

Compiler version

3.5.1, 3.6.4, 3.7.0-RC1

Minimized code

import scala.reflect.ClassTag

opaque type EntryName = String

object EntryName:
  def apply[T](using cls: ClassTag[T]): EntryName =
    cls.runtimeClass.getSimpleName.replaceAll("([a-z])([A-Z]+)", "$1 $2")

  def unapply[T](s: EntryName)(using ct: ClassTag[T]): Boolean = s == apply[T]


sealed abstract class Shape

case class Square(side: Int) extends Shape
case class Circle(radius: Int) extends Shape
case class Rectangle(xSide: Int, ySide: Int) extends Shape

// make groups by EntryName while ordering
given Ordering[(EntryName, Int)] = Ordering.by { case (n, size) => n match 
  case EntryName[Circle]() => (0, size)
  case EntryName[Square]() => (1, size) // reachable!
  case EntryName[Rectangle]() => (2, size)  // reachable!
}

println(
  Vector(
  EntryName[Circle] -> 4,
  EntryName[Rectangle] -> 8,
  EntryName[Square] -> 12,
  EntryName[Circle] -> 1
).sorted == Vector(
    EntryName[Circle] -> 1,
    EntryName[Circle] -> 4,
    EntryName[Square] -> 12,
    EntryName[Rectangle] -> 8,
  )
)

Output

[E030]  Match case Unreachable Warning:
  case EntryName[Square]() => (1, size)

[E030]  Match case Unreachable Warning:
  case EntryName[Rectangle]() => (2, size)

Expectation

No warnings issued

Note: also reproducible without opaque type

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