@@ -908,50 +908,36 @@ class SpaceEngine(using Context) extends SpaceLogic {
908
908
909
909
if (! redundancyCheckable(sel)) return
910
910
911
- val targetSpace =
912
- if ! selTyp.classSymbol.isNullableClass then
913
- project(selTyp)
914
- else
915
- project(OrType (selTyp, constantNullType, soft = false ))
916
-
911
+ val isNullable = selTyp.classSymbol.isNullableClass
912
+ val targetSpace = if isNullable
913
+ then project(OrType (selTyp, constantNullType, soft = false ))
914
+ else project(selTyp)
917
915
debug.println(s " targetSpace: ${show(targetSpace)}" )
918
916
919
- // in redundancy check, take guard as false in order to soundly approximate
920
- val spaces = cases.map { x =>
921
- val res =
922
- if (x.guard.isEmpty) project(x.pat)
923
- else Empty
917
+ cases.iterator.zipWithIndex.foldLeft(Nil : List [Space ]) { case (prevs, (CaseDef (pat, guard, _), i)) =>
918
+ debug.println(i " case pattern: $pat" )
924
919
925
- debug.println(s " ${x.pat.show} ====> ${show(res)}" )
926
- res
927
- }
920
+ val curr = project(pat)
921
+ debug.println(i " reachable? ${show(curr)}" )
928
922
929
- (1 until cases.length).foreach { i =>
930
- val pat = cases(i).pat
931
- val prevs = Or (spaces.take(i))
932
- if (pat != EmptyTree // rethrow case of catch uses EmptyTree
933
- && simplify(intersect(prevs, targetSpace)) != Empty
934
- // it's required that at one of the previous cases is reachable (its intersected Space isn't Empty)
935
- // because if all the previous cases are unreachable then case i can't be unreachable
936
- ) {
937
- val curr = project(pat) // TODO(dnw) reuse `spaces(i)` & avoid re-computing? Or is mutability present?
938
-
939
- debug.println(s " ---------------reachable? ${show(curr)}" )
940
- debug.println(s " prev: ${show(prevs)}" )
941
-
942
- val covered = simplify(intersect(curr, targetSpace))
943
- debug.println(s " covered: ${show(covered)}" )
944
-
945
- if (isSubspace(covered, prevs)) {
946
- if i == cases.length - 1
947
- && isWildcardArg(pat)
948
- && pat.tpe.classSymbol.isNullableClass
949
- then
950
- report.warning(MatchCaseOnlyNullWarning (), pat.srcPos)
951
- else
952
- report.warning(MatchCaseUnreachable (), pat.srcPos)
953
- }
923
+ val prev = simplify(Or (prevs))
924
+ debug.println(s " prev: ${show(prev)}" )
925
+
926
+ val covered = simplify(intersect(curr, targetSpace))
927
+ debug.println(s " covered: ${show(covered)}" )
928
+
929
+ if pat != EmptyTree // rethrow case of catch uses EmptyTree
930
+ && prev != Empty // avoid isSubspace(Empty, Empty) - one of the previous cases much be reachable
931
+ && isSubspace(covered, prev)
932
+ then {
933
+ if isNullable && i == cases.length - 1 && isWildcardArg(pat) then
934
+ report.warning(MatchCaseOnlyNullWarning (), pat.srcPos)
935
+ else
936
+ report.warning(MatchCaseUnreachable (), pat.srcPos)
954
937
}
938
+
939
+ // in redundancy check, take guard as false in order to soundly approximate
940
+ (if guard.isEmpty then covered else Empty ) :: prevs
955
941
}
956
942
}
957
943
}
0 commit comments