Skip to content

Commit 45da347

Browse files
Fix regression in provablyDisjoint (cherry-picked from #12786)
1 parent 73af047 commit 45da347

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
@@ -2499,7 +2499,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
24992499

25002500
def isEnumValueOrModule(ref: TermRef): Boolean =
25012501
val sym = ref.termSymbol
2502-
sym.isAllOf(EnumCase, butNot=JavaDefined) || sym.is(Module)
2502+
val isEnumValue = sym.isAllOf(EnumCase, butNot=JavaDefined)
2503+
val isModule = sym.is(Module)
2504+
isEnumValue || isModule || (ref.info match {
2505+
case tp: TermRef => isEnumValueOrModule(tp)
2506+
case _ => false
2507+
})
25032508

25042509
/** Can we enumerate all instantiations of this type? */
25052510
def isClosedSum(tp: Symbol): Boolean =
@@ -2608,11 +2613,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
26082613
provablyDisjoint(tp1, gadtBounds(tp2.symbol).hi) || provablyDisjoint(tp1, tp2.superType)
26092614
case (tp1: TermRef, tp2: TermRef) if isEnumValueOrModule(tp1) && isEnumValueOrModule(tp2) =>
26102615
tp1.termSymbol != tp2.termSymbol
2611-
case (tp1: TermRef, tp2: TypeRef) if isEnumValueOrModule(tp1) && !tp1.classSymbols.exists(_.derivesFrom(tp2.classSymbol)) =>
2612-
// Note: enum values may have multiple parents
2613-
true
2614-
case (tp1: TypeRef, tp2: TermRef) if isEnumValueOrModule(tp2) && !tp2.classSymbols.exists(_.derivesFrom(tp1.classSymbol)) =>
2615-
true
2616+
case (tp1: TermRef, tp2: TypeRef) if isEnumValueOrModule(tp1) && tp2.symbol.isClass =>
2617+
!isSubType(tp1, tp2)
2618+
case (tp1: TypeRef, tp2: TermRef) if isEnumValueOrModule(tp2) && tp1.symbol.isClass =>
2619+
!isSubType(tp2, tp1)
26162620
case (tp1: Type, tp2: Type) if defn.isTupleType(tp1) =>
26172621
provablyDisjoint(tp1.toNestedPairs, tp2)
26182622
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)