Skip to content

Commit e184e75

Browse files
Fix regression in provablyDisjoint
1 parent fe2fcc4 commit e184e75

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,7 +2494,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
24942494

24952495
def isEnumValueOrModule(ref: TermRef): Boolean =
24962496
val sym = ref.termSymbol
2497-
sym.isAllOf(EnumCase, butNot=JavaDefined) || sym.is(Module)
2497+
val isEnumValue = sym.isAllOf(EnumCase, butNot=JavaDefined)
2498+
val isModule = sym.is(Module)
2499+
isEnumValue || isModule || (ref.info match {
2500+
case tp: TermRef => isEnumValueOrModule(tp)
2501+
case _ => false
2502+
})
24982503

24992504
/** Can we enumerate all instantiations of this type? */
25002505
def isClosedSum(tp: Symbol): Boolean =
@@ -2603,11 +2608,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
26032608
provablyDisjoint(tp1, gadtBounds(tp2.symbol).hi) || provablyDisjoint(tp1, tp2.superType)
26042609
case (tp1: TermRef, tp2: TermRef) if isEnumValueOrModule(tp1) && isEnumValueOrModule(tp2) =>
26052610
tp1.termSymbol != tp2.termSymbol
2606-
case (tp1: TermRef, tp2: TypeRef) if isEnumValueOrModule(tp1) && !tp1.classSymbols.exists(_.derivesFrom(tp2.classSymbol)) =>
2607-
// Note: enum values may have multiple parents
2608-
true
2609-
case (tp1: TypeRef, tp2: TermRef) if isEnumValueOrModule(tp2) && !tp2.classSymbols.exists(_.derivesFrom(tp1.classSymbol)) =>
2610-
true
2611+
case (tp1: TermRef, tp2: TypeRef) if isEnumValueOrModule(tp1) && tp2.symbol.isClass =>
2612+
!isSubType(tp1, tp2)
2613+
case (tp1: TypeRef, tp2: TermRef) if isEnumValueOrModule(tp2) && tp1.symbol.isClass =>
2614+
!isSubType(tp2, tp1)
26112615
case (tp1: Type, tp2: Type) if defn.isTupleType(tp1) =>
26122616
provablyDisjoint(tp1.toNestedPairs, tp2)
26132617
case (tp1: Type, tp2: Type) if defn.isTupleType(tp2) =>

tests/neg/12549.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
enum Bool {
2+
case True
3+
case False
4+
}
5+
6+
import Bool.*
7+
8+
type Not[B <: Bool] = B match {
9+
case True.type => False.type
10+
case False.type => True.type
11+
case _ => "unreachable"
12+
}
13+
14+
def foo[B <: Bool & Singleton]: Unit = {
15+
implicitly[Not[B] =:= "unreachable"] // error
16+
17+
()
18+
}

0 commit comments

Comments
 (0)