diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 746be4ae5766..70051a713bb3 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -3974,10 +3974,19 @@ class MatchReducer(initctx: Context) extends TypeComparer(initctx) { MatchTypeTrace.emptyScrutinee(scrut) NoType case Nil => - /* TODO warn ? then re-enable warn/12974.scala:26 val noCasesText = MatchTypeTrace.noMatchesText(scrut, cases) - report.warning(reporting.MatchTypeNoCases(noCasesText), pos = ???) - */ + val pos = ctx.source.atSpan(ctx.owner.span) + val isStableScrut = !scrut.isInstanceOf[TypeVar] + + // Emit warn for user-facing term-level typing, and avoid intermediate / redundant reports + val doEmit = + pos.exists + && ctx.owner.isTerm + && isStableScrut + && ctx.phase.isTyper + if doEmit then + report.warning(reporting.MatchTypeNoCases(noCasesText), pos) + MatchTypeTrace.noMatches(scrut, cases) NoType diff --git a/tests/neg/i12049.check b/tests/neg/i12049.check index e0c2d498f119..8ec1e2da932b 100644 --- a/tests/neg/i12049.check +++ b/tests/neg/i12049.check @@ -103,3 +103,19 @@ | Therefore, reduction cannot advance to the remaining case | | case B => String +-- [E184] Type Warning: tests/neg/i12049.scala:14:4 -------------------------------------------------------------------- +14 |val y3: String = ??? : Last[Int *: Int *: Boolean *: String *: EmptyTuple] // error + | ^ + | Match type reduction failed since selector EmptyTuple + | matches none of the cases + | + | case _ *: _ *: t => Last[t] + | case t *: EmptyTuple => t +-- [E184] Type Warning: tests/neg/i12049.scala:22:4 -------------------------------------------------------------------- +22 |val z3: (A, B, A) = ??? : Reverse[(A, B, A)] // error + | ^ + | Match type reduction failed since selector A *: EmptyTuple.type + | matches none of the cases + | + | case t1 *: t2 *: ts => Tuple.Concat[Reverse[ts], (t2, t1)] + | case EmptyTuple => EmptyTuple diff --git a/tests/warn/12974.scala b/tests/warn/12974.scala index 45029602296f..5d7daa2b3ae7 100644 --- a/tests/warn/12974.scala +++ b/tests/warn/12974.scala @@ -23,7 +23,7 @@ object RecMap { def main(args: Array[String]) = import Record._ - val foo: Any = Rec.empty.fetch("foo") // TODO + val foo: Any = Rec.empty.fetch("foo") // warn // ^ // Match type reduction failed since selector EmptyTuple.type // matches none of the cases diff --git a/tests/warn/i23822.scala b/tests/warn/i23822.scala new file mode 100644 index 000000000000..3c7aecb1fbcc --- /dev/null +++ b/tests/warn/i23822.scala @@ -0,0 +1,16 @@ +object MatchTypes: + + type ConstituentPartOf[A] = A match + case BigInt => Int + case String => Char + + def lastPartOf[A](thing: A): ConstituentPartOf[A] = thing match + case number: BigInt => (number % 10).toInt + case string: String => string.charAt(string.length - 1) + + def main(args: Array[String]): Unit = + val lastPartOfSomethingElse = lastPartOf(BigDecimal("10")) // warn + // ^ + // Match type reduction failed since selector BigDecimal + // matches none of the cases + println(lastPartOfSomethingElse)