diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 5d2ad1e1274c..9b10f88e4a17 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -289,7 +289,7 @@ object PatternMatcher { if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length) matchArgsPlan(caseAccessors.map(ref(scrutinee).select(_)), args, onSuccess) - else if (unapp.tpe.isRef(defn.BooleanClass)) + else if (unapp.tpe.widenSingleton.isRef(defn.BooleanClass)) TestPlan(GuardTest, unapp, unapp.pos, onSuccess, onFailure) else { letAbstract(unapp) { unappResult => diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index e3f064031758..20057a560016 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -309,6 +309,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic { def irrefutable(unapp: Tree): Boolean = { // TODO: optionless patmat unapp.tpe.widen.finalResultType.isRef(scalaSomeClass) || + unapp.tpe.widen.finalResultType =:= ConstantType(Constant(true)) || (unapp.symbol.is(Synthetic) && unapp.symbol.owner.linkedClass.is(Case)) || productArity(unapp.tpe.widen.finalResultType) > 0 } diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 83f8b88d86df..7d77920e8741 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -114,7 +114,7 @@ object Applications { productSelectorTypes(unapplyResult) else if (isGetMatch(unapplyResult, pos)) getUnapplySelectors(getTp, args, pos) - else if (unapplyResult isRef defn.BooleanClass) + else if (unapplyResult.widenSingleton isRef defn.BooleanClass) Nil else if (defn.isProductSubType(unapplyResult)) productSelectorTypes(unapplyResult) diff --git a/tests/patmat/i4226.check b/tests/patmat/i4226.check new file mode 100644 index 000000000000..9d5e9110945e --- /dev/null +++ b/tests/patmat/i4226.check @@ -0,0 +1 @@ +11: Pattern Match Exhaustivity: Just(_) diff --git a/tests/patmat/i4226.scala b/tests/patmat/i4226.scala new file mode 100644 index 000000000000..ad75c4d1236c --- /dev/null +++ b/tests/patmat/i4226.scala @@ -0,0 +1,15 @@ +sealed abstract class Maybe[A] +final case class Just[A](a: A) extends Maybe[A] +class Empty[A] extends Maybe[A] +object Empty { + def apply[A](): Maybe[A] = new Empty[A] + def unapply[A](e: Empty[A]): true = true +} + +object Test { + val a: Maybe[Int] = Just(2) + def main(args: Array[String]): Unit = a match { + case Just(2) => true + case Empty() => + } +} diff --git a/tests/patmat/i4226b.check b/tests/patmat/i4226b.check new file mode 100644 index 000000000000..1528dd515904 --- /dev/null +++ b/tests/patmat/i4226b.check @@ -0,0 +1 @@ +11: Pattern Match Exhaustivity: _: Empty, Just(_) diff --git a/tests/patmat/i4226b.scala b/tests/patmat/i4226b.scala new file mode 100644 index 000000000000..d489b1d5b8f0 --- /dev/null +++ b/tests/patmat/i4226b.scala @@ -0,0 +1,15 @@ +sealed abstract class Maybe[A] +final case class Just[A](a: A) extends Maybe[A] +class Empty[A] extends Maybe[A] +object Empty { + def apply[A](): Maybe[A] = new Empty[A] + def unapply[A](e: Empty[A]): false = false +} + +object Test { + val a: Maybe[Int] = Just(2) + def main(args: Array[String]): Unit = a match { + case Just(2) => true + case Empty() => + } +}