Skip to content

Commit

Permalink
Fix regression in provablyDisjoint (cherry-picked from scala#12786)
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierBlanvillain committed Jun 11, 2021
1 parent af7b341 commit 610073b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
16 changes: 10 additions & 6 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2494,7 +2494,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling

def isEnumValueOrModule(ref: TermRef): Boolean =
val sym = ref.termSymbol
sym.isAllOf(EnumCase, butNot=JavaDefined) || sym.is(Module)
val isEnumValue = sym.isAllOf(EnumCase, butNot=JavaDefined)
val isModule = sym.is(Module)
isEnumValue || isModule || (ref.info match {
case tp: TermRef => isEnumValueOrModule(tp)
case _ => false
})

/** Can we enumerate all instantiations of this type? */
def isClosedSum(tp: Symbol): Boolean =
Expand Down Expand Up @@ -2603,11 +2608,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
provablyDisjoint(tp1, gadtBounds(tp2.symbol).hi) || provablyDisjoint(tp1, tp2.superType)
case (tp1: TermRef, tp2: TermRef) if isEnumValueOrModule(tp1) && isEnumValueOrModule(tp2) =>
tp1.termSymbol != tp2.termSymbol
case (tp1: TermRef, tp2: TypeRef) if isEnumValueOrModule(tp1) && !tp1.classSymbols.exists(_.derivesFrom(tp2.classSymbol)) =>
// Note: enum values may have multiple parents
true
case (tp1: TypeRef, tp2: TermRef) if isEnumValueOrModule(tp2) && !tp2.classSymbols.exists(_.derivesFrom(tp1.classSymbol)) =>
true
case (tp1: TermRef, tp2: TypeRef) if isEnumValueOrModule(tp1) && tp2.symbol.isClass =>
!isSubType(tp1, tp2)
case (tp1: TypeRef, tp2: TermRef) if isEnumValueOrModule(tp2) && tp1.symbol.isClass =>
!isSubType(tp2, tp1)
case (tp1: Type, tp2: Type) if defn.isTupleType(tp1) =>
provablyDisjoint(tp1.toNestedPairs, tp2)
case (tp1: Type, tp2: Type) if defn.isTupleType(tp2) =>
Expand Down
18 changes: 18 additions & 0 deletions tests/neg/12549.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
enum Bool {
case True
case False
}

import Bool.*

type Not[B <: Bool] = B match {
case True.type => False.type
case False.type => True.type
case _ => "unreachable"
}

def foo[B <: Bool & Singleton]: Unit = {
implicitly[Not[B] =:= "unreachable"] // error

()
}

0 comments on commit 610073b

Please sign in to comment.