diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 2bfff0baad6e..38341ed3a573 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -380,7 +380,12 @@ class SpaceEngine(using Context) extends SpaceLogic { Prod(erase(pat.tpe.stripAnnots, isValue = false), funRef, pats.take(arity - 1).map(project) :+ projectSeq(pats.drop(arity - 1))) } else - Prod(erase(pat.tpe.stripAnnots, isValue = false), funRef, pats.map(project)) + val tp = fun.tpe.widen.finalResultType + val isProdMatch = isProductMatch(tp, pats.length) || defn.isProductSubType(tp) && tp.classSymbol.is(Scala2x) + if isProdMatch then + Prod(erase(pat.tpe.stripAnnots, isValue = false), funRef, pats.map(project)) + else + Typ(erase(pat.tpe.stripAnnots, isValue = false), decomposed = false) case Typed(pat @ UnApply(_, _, _), _) => project(pat) diff --git a/tests/patmat/irrefutable.mini.check b/tests/patmat/irrefutable.mini.check new file mode 100644 index 000000000000..91c755c01131 --- /dev/null +++ b/tests/patmat/irrefutable.mini.check @@ -0,0 +1 @@ +15: Pattern Match Exhaustivity: ExM(_, _) diff --git a/tests/patmat/irrefutable.mini.scala b/tests/patmat/irrefutable.mini.scala new file mode 100644 index 000000000000..463188b92642 --- /dev/null +++ b/tests/patmat/irrefutable.mini.scala @@ -0,0 +1,18 @@ +sealed class M(n: Int, s: String) extends Product { + def _1: Int = n + def _2: String = s + def isEmpty: Boolean = s.size > n + def get: M = this + + def canEqual(that: Any): Boolean = true + def productArity: Int = 2 + def productElement(n: Int): Any = ??? +} + +object ExM { + def unapply(m: M): M = m + + def test(m: M) = m match { // warning + case ExM(s) => + } +} \ No newline at end of file diff --git a/tests/pos/i13737.scala b/tests/pos/i13737.scala new file mode 100644 index 000000000000..b18dd32e6fcd --- /dev/null +++ b/tests/pos/i13737.scala @@ -0,0 +1,18 @@ +sealed trait Result + +case class Success(result: String, next: Int) extends Result { + def isEmpty: Boolean = 10 % 2 == 1 + def get: String = result +} + +object Success { + def unapply(x: Success): Success = x +} + +def main = + val res: Result = ??? + res match + case Success(v) => v + + +// todo: check why only sealed trait interference