Skip to content

Commit e750a8a

Browse files
authored
Merge pull request #6260 from dotty-staging/fix-6255
Fix #6255: Don't check unreachability for Expr[T]
2 parents 7a70cb2 + d50b984 commit e750a8a

File tree

7 files changed

+34
-16
lines changed

7 files changed

+34
-16
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
545545
* C --> C if current owner is C !!!
546546
*
547547
*/
548-
def showType(tp: Type): String = {
548+
def showType(tp: Type, showTypeArgs: Boolean = false): String = {
549549
val enclosingCls = ctx.owner.enclosingClass
550550

551551
def isOmittable(sym: Symbol) =
@@ -564,25 +564,25 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
564564
case _ => tp.show
565565
}
566566

567-
def refine(tp: Type): String = tp match {
567+
def refine(tp: Type): String = tp.stripAnnots match {
568568
case tp: RefinedType => refine(tp.parent)
569-
case tp: AppliedType => refine(tp.typeConstructor)
569+
case tp: AppliedType =>
570+
refine(tp.typeConstructor) + (
571+
if (showTypeArgs) tp.argInfos.map(refine).mkString("[", ",", "]")
572+
else ""
573+
)
570574
case tp: ThisType => refine(tp.tref)
571575
case tp: NamedType =>
572576
val pre = refinePrefix(tp.prefix)
573577
if (tp.name == tpnme.higherKinds) pre
574578
else if (pre.isEmpty) tp.name.show.stripSuffix("$")
575579
else pre + "." + tp.name.show.stripSuffix("$")
580+
case tp: OrType => refine(tp.tp1) + " | " + refine(tp.tp2)
581+
case _: TypeBounds => "_"
576582
case _ => tp.show.stripSuffix("$")
577583
}
578584

579-
val text = tp.stripAnnots match {
580-
case tp: OrType => showType(tp.tp1) + " | " + showType(tp.tp2)
581-
case tp => refine(tp)
582-
}
583-
584-
if (text.isEmpty) enclosingCls.show.stripSuffix("$")
585-
else text
585+
refine(tp)
586586
}
587587

588588
/** Whether the counterexample is satisfiable. The space is flattened and non-empty. */
@@ -646,7 +646,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
646646
else if (tp.classSymbol.is(CaseClass) && !hasCustomUnapply(tp.classSymbol))
647647
// use constructor syntax for case class
648648
showType(tp) + params(tp).map(_ => "_").mkString("(", ", ", ")")
649-
else if (decomposed) "_: " + showType(tp)
649+
else if (decomposed) "_: " + showType(tp, showTypeArgs = true)
650650
else "_"
651651
case Prod(tp, fun, sym, params, _) =>
652652
if (ctx.definitions.isTupleType(tp))
@@ -677,7 +677,6 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
677677
}) ||
678678
tpw.isRef(defn.BooleanClass) ||
679679
tpw.typeSymbol.is(JavaEnum) ||
680-
canDecompose(tpw) ||
681680
(defn.isTupleType(tpw) && tpw.argInfos.exists(isCheckable(_)))
682681
}
683682

@@ -719,7 +718,12 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
719718
}
720719

721720
private def redundancyCheckable(sel: Tree): Boolean =
722-
!sel.tpe.hasAnnotation(defn.UncheckedAnnot)
721+
// Ignore Expr for unreachability as a special case.
722+
// Quote patterns produce repeated calls to the same unapply method, but with different implicit parameters.
723+
// Since we assume that repeated calls to the same unapply method overlap
724+
// and implicit parameters cannot normally differ between two patterns in one `match`,
725+
// the easiest solution is just to ignore Expr.
726+
!sel.tpe.hasAnnotation(defn.UncheckedAnnot) && !sel.tpe.widen.isRef(defn.QuotedExprClass)
723727

724728
def checkRedundancy(_match: Match): Unit = {
725729
val Match(sel, cases) = _match

tests/patmat/3144.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6: Pattern Match Exhaustivity: _: Foo
1+
6: Pattern Match Exhaustivity: _: Foo[T]

tests/patmat/i4226b.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
11: Pattern Match Exhaustivity: Just(_), _: Empty
1+
11: Pattern Match Exhaustivity: Just(_), _: Empty[Int]

tests/patmat/i6255.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Foo {
2+
def foo(x: quoted.Expr[Int]) given scala.tasty.Reflection: Unit = x match {
3+
case '{ 1 } =>
4+
case '{ 2 } =>
5+
case _ =>
6+
}
7+
}

tests/patmat/i6255b.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2: Pattern Match Exhaustivity: _: Expr[Int]

tests/patmat/i6255b.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Foo {
2+
def foo(x: quoted.Expr[Int]) given scala.tasty.Reflection: Unit = x match {
3+
case '{ 1 } =>
4+
case '{ 2 } =>
5+
}
6+
}

tests/patmat/t9779.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
10: Pattern Match Exhaustivity: _: a.Elem
1+
10: Pattern Match Exhaustivity: _: a.Elem[_]

0 commit comments

Comments
 (0)