Skip to content

Commit 7e47294

Browse files
committed
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.
1 parent 5439e98 commit 7e47294

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/TypeComparer.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -2841,10 +2841,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28412841
case (tp1: TypeRef, tp2: TypeRef) if tp1.symbol.isClass && tp2.symbol.isClass =>
28422842
val cls1 = tp1.classSymbol
28432843
val cls2 = tp2.classSymbol
2844-
def isDecomposable(tp: Symbol): Boolean =
2845-
tp.is(Sealed) && !tp.hasAnonymousChild
2844+
val sameKind = tp1.hasSameKindAs(tp2)
2845+
def isDecomposable(sym: Symbol): Boolean =
2846+
sameKind && sym.is(Sealed) && !sym.hasAnonymousChild
28462847
def decompose(sym: Symbol, tp: Type): List[Type] =
2847-
sym.children.map(x => refineUsingParent(tp, x)).filter(_.exists)
2848+
val tpSimple = tp.applyIfParameterized(tp.typeParams.map(_ => WildcardType))
2849+
sym.children.map(x => refineUsingParent(tpSimple, x)).filter(_.exists)
28482850
if (cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1))
28492851
false
28502852
else

Diff for: tests/pos/i19031.ci-reg1.scala

+12
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)