Skip to content

Commit 8776906

Browse files
committed
Reuse computation in checkRedundancy
1 parent be658f6 commit 8776906

File tree

1 file changed

+25
-39
lines changed
  • compiler/src/dotty/tools/dotc/transform/patmat

1 file changed

+25
-39
lines changed

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

+25-39
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)