@@ -937,36 +937,36 @@ object SpaceEngine {
937
937
then project(OrType (selTyp, ConstantType (Constant (null )), soft = false ))
938
938
else project(selTyp)
939
939
940
- @ tailrec def recur (cases : List [CaseDef ], prevs : List [Space ], deferred : List [Tree ]): Unit =
940
+ @ tailrec def recur (cases : List [CaseDef ], prevs : List [Space ], deferred : List [Tree ], nullCovered : Boolean ): Unit =
941
941
cases match
942
942
case Nil =>
943
- case CaseDef (pat, guard, _) :: rest =>
944
- val curr = trace(i " project( $pat) " )(project(pat))
943
+ case (c @ CaseDef (pat, guard, _)) :: rest =>
944
+ val patNullable = Nullables .matchesNull(c)
945
+ val curr = trace(i " project( $pat) " )(
946
+ if patNullable
947
+ then Or (List (project(pat), Typ (ConstantType (Constant (null )))))
948
+ else project(pat))
945
949
val covered = trace(" covered" )(simplify(intersect(curr, targetSpace)))
946
950
val prev = trace(" prev" )(simplify(Or (prevs)))
947
951
if prev == Empty && covered == Empty then // defer until a case is reachable
948
- recur(rest, prevs, pat :: deferred)
952
+ recur(rest, prevs, pat :: deferred, nullCovered )
949
953
else
950
954
for pat <- deferred.reverseIterator
951
955
do report.warning(MatchCaseUnreachable (), pat.srcPos)
952
956
953
957
if pat != EmptyTree // rethrow case of catch uses EmptyTree
954
958
&& ! pat.symbol.isAllOf(SyntheticCase , butNot= Method ) // ExpandSAMs default cases use SyntheticCase
955
- && isSubspace(covered, prev)
959
+ && isSubspace(covered, Or ( List ( prev, Typ ( ConstantType ( Constant ( null ))))) )
956
960
then
957
- val nullOnly = isNullable && isWildcardArg(pat) && ! mayCoverNull( prev)
958
- val msg = if nullOnly then MatchCaseOnlyNullWarning () else MatchCaseUnreachable ( )
959
- report.warning(msg , pat.srcPos)
961
+ val nullOnly = isNullable && isWildcardArg(pat) && ! nullCovered && ! isSubspace(covered, prev) && ( ! ctx.explicitNulls || selTyp. isInstanceOf [ FlexibleType ] )
962
+ if nullOnly then report.warning( MatchCaseOnlyNullWarning () , pat.srcPos )
963
+ else if (isSubspace(covered, prev)) then report.warning(MatchCaseUnreachable () , pat.srcPos)
960
964
961
965
// in redundancy check, take guard as false in order to soundly approximate
962
- val newPrev = if (guard.isEmpty)
963
- then if (isWildcardArg(pat))
964
- then Typ (ConstantType (Constant (null ))) :: covered :: prevs
965
- else covered :: prevs
966
- else prevs
967
- recur(rest, newPrev, Nil )
968
-
969
- recur(m.cases, Nil , Nil )
966
+ val newPrev = if (guard.isEmpty) then covered :: prevs else prevs
967
+ recur(rest, newPrev, Nil , nullCovered || (guard.isEmpty && patNullable))
968
+
969
+ recur(m.cases, Nil , Nil , false )
970
970
end checkReachability
971
971
972
972
def checkMatch (m : Match )(using Context ): Unit =
0 commit comments