Skip to content

Commit 54923f8

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 80d705b commit 54923f8

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
@@ -2814,6 +2814,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28142814
tp.symbol match
28152815
case cls: ClassSymbol =>
28162816
if cls == defn.SingletonClass then defn.AnyType
2817+
else if cls.typeParams.nonEmpty then EtaExpansion(tp)
28172818
else tp
28182819
case sym =>
28192820
if !ctx.erasedTypes && sym == defn.FromJavaObjectSymbol then defn.AnyType
@@ -2834,6 +2835,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28342835
tp
28352836
case tp: ConstantType =>
28362837
tp
2838+
case tp: HKTypeLambda =>
2839+
tp
28372840
case tp: TypeProxy =>
28382841
disjointnessBoundary(tp.superTypeNormalized)
28392842
case tp: WildcardType =>
@@ -2859,6 +2862,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28592862
case (tp1: AndType, tp2) =>
28602863
provablyDisjoint(tp1.tp1, tp2, pending) || provablyDisjoint(tp1.tp2, tp2, pending)
28612864

2865+
// Cases involving type lambdas
2866+
case (tp1: HKTypeLambda, tp2: HKTypeLambda) =>
2867+
tp1.paramNames.sizeCompare(tp2.paramNames) != 0
2868+
|| provablyDisjoint(tp1.resultType, tp2.resultType, pending)
2869+
case (tp1: HKTypeLambda, tp2) =>
2870+
!tp2.isDirectRef(defn.AnyKindClass)
2871+
case (tp1, tp2: HKTypeLambda) =>
2872+
!tp1.isDirectRef(defn.AnyKindClass)
2873+
28622874
/* Cases where both are unique values (enum cases or constant types)
28632875
*
28642876
* 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
@@ -154,7 +154,11 @@ object TypeTestsCasts {
154154

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

0 commit comments

Comments
 (0)