Skip to content

Commit c756919

Browse files
authored
Merge pull request #4236 from dotty-staging/fix-4226
Fix #4226: allow infallible boolean extractors to return `true`
2 parents 2762567 + f1b8cda commit c756919

File tree

7 files changed

+35
-2
lines changed

7 files changed

+35
-2
lines changed

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ object PatternMatcher {
289289

290290
if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length)
291291
matchArgsPlan(caseAccessors.map(ref(scrutinee).select(_)), args, onSuccess)
292-
else if (unapp.tpe.isRef(defn.BooleanClass))
292+
else if (unapp.tpe.widenSingleton.isRef(defn.BooleanClass))
293293
TestPlan(GuardTest, unapp, unapp.pos, onSuccess, onFailure)
294294
else {
295295
letAbstract(unapp) { unappResult =>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
309309
def irrefutable(unapp: Tree): Boolean = {
310310
// TODO: optionless patmat
311311
unapp.tpe.widen.finalResultType.isRef(scalaSomeClass) ||
312+
unapp.tpe.widen.finalResultType =:= ConstantType(Constant(true)) ||
312313
(unapp.symbol.is(Synthetic) && unapp.symbol.owner.linkedClass.is(Case)) ||
313314
productArity(unapp.tpe.widen.finalResultType) > 0
314315
}

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ object Applications {
114114
productSelectorTypes(unapplyResult)
115115
else if (isGetMatch(unapplyResult, pos))
116116
getUnapplySelectors(getTp, args, pos)
117-
else if (unapplyResult isRef defn.BooleanClass)
117+
else if (unapplyResult.widenSingleton isRef defn.BooleanClass)
118118
Nil
119119
else if (defn.isProductSubType(unapplyResult))
120120
productSelectorTypes(unapplyResult)

tests/patmat/i4226.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
11: Pattern Match Exhaustivity: Just(_)

tests/patmat/i4226.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
sealed abstract class Maybe[A]
2+
final case class Just[A](a: A) extends Maybe[A]
3+
class Empty[A] extends Maybe[A]
4+
object Empty {
5+
def apply[A](): Maybe[A] = new Empty[A]
6+
def unapply[A](e: Empty[A]): true = true
7+
}
8+
9+
object Test {
10+
val a: Maybe[Int] = Just(2)
11+
def main(args: Array[String]): Unit = a match {
12+
case Just(2) => true
13+
case Empty() =>
14+
}
15+
}

tests/patmat/i4226b.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
11: Pattern Match Exhaustivity: _: Empty, Just(_)

tests/patmat/i4226b.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
sealed abstract class Maybe[A]
2+
final case class Just[A](a: A) extends Maybe[A]
3+
class Empty[A] extends Maybe[A]
4+
object Empty {
5+
def apply[A](): Maybe[A] = new Empty[A]
6+
def unapply[A](e: Empty[A]): false = false
7+
}
8+
9+
object Test {
10+
val a: Maybe[Int] = Just(2)
11+
def main(args: Array[String]): Unit = a match {
12+
case Just(2) => true
13+
case Empty() =>
14+
}
15+
}

0 commit comments

Comments
 (0)