Skip to content

Commit bfa5aea

Browse files
committed
Merge isOpen/commonOpenTypeSpace into intersectUnrelatedAtomicTypes
Check if at least one of the types is a trait before deciding that their intersection is non-empty.
1 parent 2252d78 commit bfa5aea

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,12 @@ trait SpaceLogic {
7474
/** Is `tp1` the same type as `tp2`? */
7575
def isEqualType(tp1: Type, tp2: Type): Boolean
7676

77-
/** Can `tp` be arbitrarily subtyped by any other open type? */
78-
def isOpen(tp: Type): Boolean
79-
80-
/** Construct a space which contains values from both `tp1` and `tp2`.
77+
/** Return a space containing the values of both types.
8178
*
82-
* Both types are expected to be open in the [[isOpen]] sense.
79+
* The types should be atomic (non-decomposable) and unrelated (neither
80+
* should be a subtype of the other).
8381
*/
84-
def commonOpenTypeSpace(tp1: Type, tp2: Type): Space
82+
def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type): Space
8583

8684
/** Is the type `tp` decomposable? i.e. all values of the type can be covered
8785
* by its decomposed types.
@@ -180,8 +178,7 @@ trait SpaceLogic {
180178
else if (isSubType(tp2, tp1)) b
181179
else if (canDecompose(tp1)) tryDecompose1(tp1)
182180
else if (canDecompose(tp2)) tryDecompose2(tp2)
183-
else if (isOpen(tp1) && isOpen(tp2)) commonOpenTypeSpace(tp1, tp2)
184-
else Empty
181+
else intersectUnrelatedAtomicTypes(tp1, tp2)
185182
case (Typ(tp1, _), Kon(tp2, ss)) =>
186183
if (isSubType(tp2, tp1)) b
187184
else if (isSubType(tp1, tp2)) a // problematic corner case: inheriting a case class
@@ -253,10 +250,15 @@ trait SpaceLogic {
253250
class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
254251
import tpd._
255252

256-
override def isOpen(tp: Type) =
257-
!tp.classSymbol.is(Sealed | Final) && !tp.termSymbol.is(Module)
253+
override def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type) = {
254+
def isOpen(tp: Type) =
255+
!tp.classSymbol.is(Sealed | Final) && !tp.termSymbol.is(Module)
258256

259-
override def commonOpenTypeSpace(tp1: Type, tp2: Type) = Typ(AndType(tp1, tp2), true)
257+
if ((tp1.classSymbol.is(Trait) || tp2.classSymbol.is(Trait))
258+
&& isOpen(tp1) && isOpen(tp2))
259+
Typ(AndType(tp1, tp2), true)
260+
else Empty
261+
}
260262

261263
/** Return the space that represents the pattern `pat`
262264
*
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
19: Pattern Match Exhaustivity: _: AbstractClass & OpenTrait, _: Clazz & OpenTrait, _: Trait & OpenTrait
2-
23: Pattern Match Exhaustivity: _: AbstractClass & OpenClass, _: Clazz & OpenClass, _: Trait & OpenClass
3-
27: Pattern Match Exhaustivity: _: AbstractClass & OpenAbstractClass, _: Clazz & OpenAbstractClass, _: Trait & OpenAbstractClass
2+
23: Pattern Match Exhaustivity: _: Trait & OpenClass
3+
27: Pattern Match Exhaustivity: _: Trait & OpenAbstractClass

0 commit comments

Comments
 (0)