Skip to content

Commit 2b709e7

Browse files
committed
Be more specific about higher-kinded types in provablyDisjoint.
Previously the disjointnessBoundary of HKTypeLambda's was implicitly their `resultType`, through the use of `superTypeNormalized`. This was fine as long as both sides of `provablyDisjoint` ended up being HKTypeLambda's at the same time, but this may not always be the case (notably with any-kinded types). It is safer to consider type lambdas as boundaries themselves, and explicitly recurse on the result types when arities match. This change surfaced a weird case in `TypeTestsCasts`, which called `provablyDisjoint` with ill-kinded types. We now explicitly apply what I suspect are partially-erased types to wildcards to recover appropriate kinds.
1 parent 4af0b0e commit 2b709e7

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2812,6 +2812,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28122812
tp.symbol match
28132813
case cls: ClassSymbol =>
28142814
if cls == defn.SingletonClass then defn.AnyType
2815+
else if cls.typeParams.nonEmpty then EtaExpansion(tp)
28152816
else tp
28162817
case sym =>
28172818
if !ctx.erasedTypes && sym == defn.FromJavaObjectSymbol then defn.AnyType
@@ -2832,6 +2833,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28322833
tp
28332834
case tp: ConstantType =>
28342835
tp
2836+
case tp: HKTypeLambda =>
2837+
tp
28352838
case tp: TypeProxy =>
28362839
disjointnessBoundary(tp.superTypeNormalized)
28372840
case tp: WildcardType =>
@@ -2857,6 +2860,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28572860
case (tp1: AndType, tp2) =>
28582861
provablyDisjoint(tp1.tp1, tp2, pending) || provablyDisjoint(tp1.tp2, tp2, pending)
28592862

2863+
// Cases involving type lambdas
2864+
case (tp1: HKTypeLambda, tp2: HKTypeLambda) =>
2865+
tp1.paramNames.sizeCompare(tp2.paramNames) != 0
2866+
|| provablyDisjoint(tp1.resultType, tp2.resultType, pending)
2867+
case (tp1: HKTypeLambda, tp2) =>
2868+
!tp2.isDirectRef(defn.AnyKindClass)
2869+
case (tp1, tp2: HKTypeLambda) =>
2870+
!tp1.isDirectRef(defn.AnyKindClass)
2871+
28602872
/* Cases where both are unique values (enum cases or constant types)
28612873
*
28622874
* When both are TermRef's, we look at the symbols. We do not try to

compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,11 @@ object TypeTestsCasts {
153153

154154
case x =>
155155
// always false test warnings are emitted elsewhere
156-
TypeComparer.provablyDisjoint(x, tpe.derivedAppliedType(tycon, targs.map(_ => WildcardType)))
156+
// provablyDisjoint wants fully applied types as input; because we're in the middle of erasure, we sometimes get raw types here
157+
val xApplied =
158+
val tparams = x.typeParams
159+
if tparams.isEmpty then x else x.appliedTo(tparams.map(_ => WildcardType))
160+
TypeComparer.provablyDisjoint(xApplied, tpe.derivedAppliedType(tycon, targs.map(_ => WildcardType)))
157161
|| typeArgsDeterminable(X, tpe)
158162
||| i"its type arguments can't be determined from $X"
159163
}

0 commit comments

Comments
 (0)