@@ -908,50 +908,36 @@ class SpaceEngine(using Context) extends SpaceLogic {
908908
909909 if (! redundancyCheckable(sel)) return
910910
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)
917915 debug.println(s " targetSpace: ${show(targetSpace)}" )
918916
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" )
924919
925- debug.println(s " ${x.pat.show} ====> ${show(res)}" )
926- res
927- }
920+ val curr = project(pat)
921+ debug.println(i " reachable? ${show(curr)}" )
928922
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)
954937 }
938+
939+ // in redundancy check, take guard as false in order to soundly approximate
940+ (if guard.isEmpty then covered else Empty ) :: prevs
955941 }
956942 }
957943}
0 commit comments