Skip to content

Commit d4791ef

Browse files
committed
Refactor flatten to be lazy
- show at most 6 unmatched cases
1 parent 35801a1 commit d4791ef

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -822,14 +822,16 @@ import transform.SymUtils._
822822
|"""
823823
}
824824

825-
class PatternMatchExhaustivity(uncoveredFn: => String)(using Context)
825+
class PatternMatchExhaustivity(uncoveredFn: => String, hasMore: Boolean)(using Context)
826826
extends Message(PatternMatchExhaustivityID) {
827827
def kind = "Pattern Match Exhaustivity"
828828
lazy val uncovered = uncoveredFn
829829
def msg =
830+
val addendum = if hasMore then "(More unmatched cases are elided)" else ""
830831
em"""|${hl("match")} may not be exhaustive.
831832
|
832-
|It would fail on pattern case: $uncovered"""
833+
|It would fail on pattern case: $uncovered
834+
|$addendum"""
833835

834836

835837
def explain =

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

+18-12
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,23 @@ trait SpaceLogic {
150150
})
151151

152152
/** Flatten space to get rid of `Or` for pretty print */
153-
def flatten(space: Space)(using Context): List[Space] = space match {
153+
def flatten(space: Space)(using Context): Seq[Space] = space match {
154154
case Prod(tp, fun, spaces, full) =>
155-
spaces.map(flatten) match {
156-
case Nil => Prod(tp, fun, Nil, full) :: Nil
157-
case ss =>
158-
ss.foldLeft(List[Prod]()) { (acc, flat) =>
159-
if (acc.isEmpty) flat.map(s => Prod(tp, fun, s :: Nil, full))
160-
else for (Prod(tp, fun, ss, full) <- acc; s <- flat) yield Prod(tp, fun, ss :+ s, full)
161-
}
155+
val ss = LazyList(spaces: _*).map(flatten)
156+
val template = Prod(tp, fun, Nil, full)
157+
ss.foldLeft(LazyList(template)) { (acc, flat) =>
158+
for
159+
Prod(tp, fun, ss, full) <- acc;
160+
s <- flat
161+
yield
162+
Prod(tp, fun, ss :+ s, full)
162163
}
164+
163165
case Or(spaces) =>
164-
spaces.flatMap(flatten _)
165-
case _ => List(space)
166+
LazyList(spaces: _*).flatMap(flatten)
167+
168+
case _ =>
169+
List(space)
166170
}
167171

168172
/** Is `a` a subspace of `b`? Equivalent to `a - b == Empty`, but faster */
@@ -838,8 +842,10 @@ class SpaceEngine(using Context) extends SpaceLogic {
838842
s != Empty && (!checkGADTSAT || satisfiable(s))
839843
}
840844

841-
if (uncovered.nonEmpty)
842-
report.warning(PatternMatchExhaustivity(show(uncovered)), sel.srcPos)
845+
846+
if uncovered.nonEmpty then
847+
val hasMore = uncovered.lengthCompare(6) > 0
848+
report.warning(PatternMatchExhaustivity(show(uncovered.take(6)), hasMore), sel.srcPos)
843849
}
844850

845851
private def redundancyCheckable(sel: Tree): Boolean =

tests/patmat/i8922c.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
26: Pattern Match Exhaustivity: (_, _, _)
1+
26: Pattern Match Exhaustivity: (true, _: String, _), (true, _: Double, _), (true, true, _), (true, false, _), (true, (), _), (false, _: String, _)

0 commit comments

Comments
 (0)