Skip to content

Commit d38ce6b

Browse files
committed
Fix #3144: more agressively check unreachability
1 parent 7799da6 commit d38ce6b

10 files changed

+33
-13
lines changed

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -903,24 +903,25 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
903903
def checkRedundancy(_match: Match): Unit = {
904904
val Match(sel, cases) = _match
905905
// ignore selector type for now
906-
// val selTyp = sel.tpe.widen.dealias
907-
908-
if (cases.length == 1) return
906+
val selTyp = sel.tpe.widen.dealias
909907

910-
// starts from the second, the first can't be redundant
911-
(1 until cases.length).foreach { i =>
908+
(0 until cases.length).foreach { i =>
912909
// in redundancy check, take guard as false in order to soundly approximate
913-
val prevs = cases.take(i).map { x =>
914-
if (x.guard.isEmpty) project(x.pat)
915-
else Empty
916-
}.reduce((a, b) => Or(List(a, b)))
910+
val prevs =
911+
if (i == 0)
912+
Empty
913+
else
914+
cases.take(i).map { x =>
915+
if (x.guard.isEmpty) project(x.pat)
916+
else Empty
917+
}.reduce((a, b) => Or(List(a, b)))
917918

918919
val curr = project(cases(i).pat)
919920

920921
debug.println(s"---------------reachable? ${show(curr)}")
921922
debug.println(s"prev: ${show(prevs)}")
922923

923-
if (isSubspace(curr, prevs)) {
924+
if (isSubspace(intersect(curr, Typ(selTyp, false)), prevs)) {
924925
ctx.warning(MatchCaseUnreachable(), cases(i).body.pos)
925926
}
926927
}

tests/patmat/3144.check

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

tests/patmat/3144c.check

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

tests/patmat/3144c.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
sealed trait Foo
2+
case class Bar(s: String)
3+
4+
object Test {
5+
def shouldError(foo: Foo): String =
6+
foo match {
7+
case bar: Bar => bar.s
8+
}
9+
}

tests/patmat/andtype-opentype-interaction.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
27: Pattern Match Exhaustivity: _: SealedClass & OpenTrait & OpenTrait2, _: AbstractClass & OpenTrait & OpenTrait2, _: Clazz & OpenTrait & OpenTrait2, _: Trait & OpenTrait & OpenTrait2
33
31: Pattern Match Exhaustivity: _: Trait & OpenClass
44
35: Pattern Match Exhaustivity: _: Trait & OpenTrait & OpenClass
5+
40: Match case Unreachable
56
43: Pattern Match Exhaustivity: _: Trait & OpenAbstractClass
67
47: Pattern Match Exhaustivity: _: Trait & OpenClass & OpenTrait & OpenClassSubclass

tests/patmat/andtype-refinedtype-interaction.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
32: Pattern Match Exhaustivity: _: Trait & C1{x: Int}
2+
37: Match case Unreachable
3+
43: Match case Unreachable
24
48: Pattern Match Exhaustivity: _: Clazz & (C1 | C2 | T1){x: Int} & (C3 | C4 | T2){x: Int}, _: Trait & (C1 | C2 | T1){x: Int} & (C3 | C4 | T2){x: Int}
35
54: Pattern Match Exhaustivity: _: Trait & (C1 | C2 | T1){x: Int} & C3{x: Int}
6+
60: Match case Unreachable
47
65: Pattern Match Exhaustivity: _: Trait & (C1 | C2){x: Int} & (C3 | SubC1){x: Int}
58
72: Pattern Match Exhaustivity: _: Trait & (T1 & (C1 | SubC2)){x: Int} & (T2 & (C2 | C3 | SubC1)){x: Int} &
69
SubSubC1{x: Int}

tests/patmat/i2253.check

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
27: Pattern Match Exhaustivity: HasIntXIntM, HasIntXStringM
2-
28: Pattern Match Exhaustivity: HasIntXIntM
1+
28: Pattern Match Exhaustivity: HasIntXIntM, HasIntXStringM
32
29: Pattern Match Exhaustivity: HasIntXIntM
3+
29: Match case Unreachable
4+
30: Pattern Match Exhaustivity: HasIntXIntM
5+
30: Match case Unreachable

tests/patmat/i2253.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ object HasIntXIntM extends S {
2222
}
2323

2424
trait T
25+
case class TA(val x: Int) extends T with S
2526

2627
class Test {
2728
def onlyIntX(s: S { val x: Int }) = s match { case _: T => ; }

tests/patmat/t6450.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
sealed abstract class FoundNode[T]
2-
// case class A[T](x: T) extends FoundNode[T]
2+
case class A[T](x: T) extends FoundNode[T]
33

44
object Foo {
55
val v: (Some[_], FoundNode[_]) = (???, ???)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
16: Pattern Match Exhaustivity: false
22
18: Match case Unreachable
33
19: Match case Unreachable
4+
20: Match case Unreachable

0 commit comments

Comments
 (0)