Skip to content

Commit 9cd9318

Browse files
Refactor check to an inhabited function
1 parent e55c931 commit 9cd9318

File tree

1 file changed

+23
-22
lines changed
  • compiler/src/dotty/tools/dotc/transform/patmat

1 file changed

+23
-22
lines changed

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

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ trait SpaceLogic {
267267
else
268268
// `(_, _, _) - (Some, None, _)` becomes `(None, _, _) | (_, Some, _) | (_, _, Empty)`
269269
Or(ss1.zip(ss2).map((minus _).tupled).zip(0 to ss2.length - 1).map {
270-
case (ri, i) => Prod(tp1, fun1, sym1, ss1.updated(i, ri), full)
271-
})
270+
case (ri, i) => Prod(tp1, fun1, sym1, ss1.updated(i, ri), full)
271+
})
272272

273273
}
274274

@@ -561,7 +561,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
561561

562562
val resTp = instantiate(childTp, parent)(ctx.fresh.setNewTyperState())
563563

564-
if (!resTp.exists) {
564+
if (!resTp.exists || !inhabited(resTp)) {
565565
debug.println(s"[refine] unqualified child ousted: ${childTp.show} !< ${parent.show}")
566566
NoType
567567
}
@@ -571,6 +571,25 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
571571
}
572572
}
573573

574+
/** Can this type be inhabited by a value?
575+
*
576+
* Intersection between singleton types and other types is always empty
577+
* the singleton type is not a subtype of the other type.
578+
* See patmat/i3573.scala for an example.
579+
*/
580+
def inhabited(tpe: Type)(implicit ctx: Context): Boolean = {
581+
val emptySingletonIntersection = new ExistsAccumulator({
582+
case AndType(s: SingletonType, t) =>
583+
!(s <:< t)
584+
case AndType(t, s: SingletonType) =>
585+
!(s <:< t)
586+
case x =>
587+
false
588+
})
589+
590+
!emptySingletonIntersection(false, tpe)
591+
}
592+
574593
/** Instantiate type `tp1` to be a subtype of `tp2`
575594
*
576595
* Return the instantiated type if type parameters and this type
@@ -625,7 +644,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
625644
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
626645
val protoTp1 = thisTypeMap(tp1.appliedTo(tvars))
627646

628-
val result = if (protoTp1 <:< tp2) {
647+
if (protoTp1 <:< tp2) {
629648
if (isFullyDefined(protoTp1, force)) protoTp1
630649
else instUndetMap(protoTp1)
631650
}
@@ -640,24 +659,6 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
640659
NoType
641660
}
642661
}
643-
644-
// The intersection between a singleton type s and another type t is
645-
// always empty when s is not a subtype of t. See patmat/i3573.scala
646-
val hasEmptyIntersections = new ExistsAccumulator({
647-
case AndType(s: SingletonType, t) =>
648-
!(s <:< t)
649-
case AndType(t, s: SingletonType) =>
650-
!(s <:< t)
651-
case x =>
652-
false
653-
})
654-
655-
if (hasEmptyIntersections(false, result)) {
656-
debug.println(s"hasEmptyIntersections($protoTp1) = true")
657-
NoType
658-
} else {
659-
result
660-
}
661662
}
662663

663664
/** Abstract sealed types, or-types, Boolean and Java enums can be decomposed */

0 commit comments

Comments
 (0)