Skip to content

Commit 6b75f5b

Browse files
committed
Fix #4225: always check redundant cases except for @uncheck
1 parent 14187e2 commit 6b75f5b

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,8 @@ class PatternMatcher extends MiniPhase {
3333

3434
// check exhaustivity and unreachability
3535
val engine = new patmat.SpaceEngine
36-
37-
if (engine.checkable(tree)) {
38-
engine.checkExhaustivity(tree)
39-
engine.checkRedundancy(tree)
40-
}
36+
engine.checkExhaustivity(tree)
37+
engine.checkRedundancy(tree)
4138

4239
translated.ensureConforms(tree.tpe)
4340
}

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
839839
flatten(s).map(doShow(_, false)).distinct.mkString(", ")
840840
}
841841

842-
def checkable(tree: Match): Boolean = {
842+
private def exhaustivityCheckable(sel: Tree): Boolean = {
843843
// Possible to check everything, but be compatible with scalac by default
844844
def isCheckable(tp: Type): Boolean =
845845
!tp.hasAnnotation(defn.UncheckedAnnot) && {
@@ -857,9 +857,8 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
857857
(defn.isTupleType(tpw) && tpw.argInfos.exists(isCheckable(_)))
858858
}
859859

860-
val Match(sel, cases) = tree
861860
val res = isCheckable(sel.tpe)
862-
debug.println(s"checkable: ${sel.show} = $res")
861+
debug.println(s"exhaustivity checkable: ${sel.show} = $res")
863862
res
864863
}
865864

@@ -877,6 +876,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
877876
val Match(sel, cases) = _match
878877
val selTyp = sel.tpe.widen.dealias
879878

879+
if (!exhaustivityCheckable(sel)) return
880880

881881
val patternSpace = cases.map({ x =>
882882
val space = project(x.pat)
@@ -894,11 +894,15 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
894894
ctx.warning(PatternMatchExhaustivity(show(Or(uncovered))), sel.pos)
895895
}
896896

897+
private def redundancyCheckable(sel: Tree): Boolean =
898+
!sel.tpe.hasAnnotation(defn.UncheckedAnnot)
899+
897900
def checkRedundancy(_match: Match): Unit = {
898901
val Match(sel, cases) = _match
899-
// ignore selector type for now
900902
val selTyp = sel.tpe.widen.dealias
901903

904+
if (!redundancyCheckable(sel)) return
905+
902906
(0 until cases.length).foreach { i =>
903907
// in redundancy check, take guard as false in order to soundly approximate
904908
val prevs =

tests/patmat/i4225.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
10: Match case Unreachable

tests/patmat/i4225.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
object Bar {
2+
def unapply(x: Int): Some[Int] =
3+
Some(0)
4+
}
5+
6+
object Test {
7+
def test(x: Int) =
8+
x match {
9+
case Bar(a) => a
10+
case _ => x // should be unreachable
11+
}
12+
}

0 commit comments

Comments
 (0)