@@ -900,7 +900,9 @@ class SpaceEngine(using Context) extends SpaceLogic {
900
900
def checkRedundancy (_match : Match ): Unit = {
901
901
debug.println(s " ---------------checking redundant patterns ${_match.show}" )
902
902
903
- val Match (sel, cases) = _match
903
+ val Match (sel, _) = _match
904
+ val cases = _match.cases.toIndexedSeq
905
+
904
906
val selTyp = sel.tpe.widen.dealias
905
907
906
908
if (! redundancyCheckable(sel)) return
@@ -911,7 +913,14 @@ class SpaceEngine(using Context) extends SpaceLogic {
911
913
else project(selTyp)
912
914
debug.println(s " targetSpace: ${show(targetSpace)}" )
913
915
914
- cases.iterator.zipWithIndex.foldLeft(Nil : List [Space ]) { case (prevs, (CaseDef (pat, guard, _), i)) =>
916
+ var i = 0
917
+ val len = cases.length
918
+ var prevs = List .empty[Space ]
919
+ var deferred = List .empty[Tree ]
920
+
921
+ while (i < len) {
922
+ val CaseDef (pat, guard, _) = cases(i)
923
+
915
924
debug.println(i " case pattern: $pat" )
916
925
917
926
val curr = project(pat)
@@ -923,18 +932,24 @@ class SpaceEngine(using Context) extends SpaceLogic {
923
932
val covered = simplify(intersect(curr, targetSpace))
924
933
debug.println(s " covered: ${show(covered)}" )
925
934
926
- if pat != EmptyTree // rethrow case of catch uses EmptyTree
927
- && prev != Empty // avoid isSubspace(Empty, Empty) - one of the previous cases much be reachable
928
- && isSubspace(covered, prev)
929
- then {
930
- if isNullable && i == cases.length - 1 && isWildcardArg(pat) then
931
- report.warning(MatchCaseOnlyNullWarning (), pat.srcPos)
932
- else
935
+ if prev == Empty && covered == Empty then // defer until a case is reachable
936
+ deferred ::= pat
937
+ else {
938
+ for (pat <- deferred.reverseIterator)
933
939
report.warning(MatchCaseUnreachable (), pat.srcPos)
940
+ if pat != EmptyTree // rethrow case of catch uses EmptyTree
941
+ && isSubspace(covered, prev)
942
+ then {
943
+ val nullOnly = isNullable && i == len - 1 && isWildcardArg(pat)
944
+ val msg = if nullOnly then MatchCaseOnlyNullWarning () else MatchCaseUnreachable ()
945
+ report.warning(msg, pat.srcPos)
946
+ }
947
+ deferred = Nil
934
948
}
935
949
936
950
// in redundancy check, take guard as false in order to soundly approximate
937
- (if guard.isEmpty then covered else Empty ) :: prevs
951
+ prevs ::= (if guard.isEmpty then covered else Empty )
952
+ i += 1
938
953
}
939
954
}
940
955
}
0 commit comments