Skip to content

Commit f87a634

Browse files
dwijnandWojciechMazur
authored andcommitted
Fix provablyDisjoint handling of HK types
If refineUsingParent/instantiateToSubType is passed a HK then it's not possible to instantiate a class to that type (at the moment and perhaps ever). So it's important we guard against that. This came up while trying to see if Mark[?] and Foo[Int] (from pos/i19031.ci-reg1.scala) are provably disjoint - which they should be reported not to be. Because they're not applied types of the same type constructor we end up trying to prove that HK type Mark is disjoint from HK type Foo. Because we don't know how to instantiate Foo's subclasses (e.g Bar2) such that it's a subtype of higher-kinded type "Mark", we end up discarding all of Foo's subclasses, which implies that Foo & Mark is uninhabited, thus they are provably disjoint - which is incorrect. We originally didn't encounter this because we eagerly decomposed in Space intersection, while now we've dispatched it to provablyDisjoint. (edit) We allow for some kindness in provablyDisjoint. [Cherry-picked 7e47294]
1 parent c1dfcef commit f87a634

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,10 +2758,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
27582758
case (tp1: TypeRef, tp2: TypeRef) if tp1.symbol.isClass && tp2.symbol.isClass =>
27592759
val cls1 = tp1.classSymbol
27602760
val cls2 = tp2.classSymbol
2761-
def isDecomposable(tp: Symbol): Boolean =
2762-
tp.is(Sealed) && !tp.hasAnonymousChild
2761+
val sameKind = tp1.hasSameKindAs(tp2)
2762+
def isDecomposable(sym: Symbol): Boolean =
2763+
sameKind && sym.is(Sealed) && !sym.hasAnonymousChild
27632764
def decompose(sym: Symbol, tp: Type): List[Type] =
2764-
sym.children.map(x => refineUsingParent(tp, x)).filter(_.exists)
2765+
val tpSimple = tp.applyIfParameterized(tp.typeParams.map(_ => WildcardType))
2766+
sym.children.map(x => refineUsingParent(tpSimple, x)).filter(_.exists)
27652767
if (cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1))
27662768
false
27672769
else

tests/pos/i19031.ci-reg1.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//> using options -Werror
2+
3+
sealed trait Mark[T]
4+
5+
trait Foo[T]
6+
class Bar1[T] extends Foo[T]
7+
class Bar2[T] extends Foo[T] with Mark[T]
8+
9+
class Test:
10+
def t1(foo: Foo[Int]): Unit = foo match
11+
case _: Mark[t] =>
12+
case _ =>

0 commit comments

Comments
 (0)