Skip to content
15 changes: 12 additions & 3 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 16 additions & 0 deletions tests/neg/i12049.check
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/warn/12974.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions tests/warn/i23822.scala
Original file line number Diff line number Diff line change
@@ -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)
Loading