Skip to content

Commit f432d08

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 1b2a16e commit f432d08

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

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

+12
Original file line numberDiff line numberDiff line change
@@ -2820,6 +2820,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28202820
tp.symbol match
28212821
case cls: ClassSymbol =>
28222822
if cls == defn.SingletonClass then defn.AnyType
2823+
else if cls.typeParams.nonEmpty then EtaExpansion(tp)
28232824
else tp
28242825
case sym =>
28252826
if !ctx.erasedTypes && sym == defn.FromJavaObjectSymbol then defn.AnyType
@@ -2840,6 +2841,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28402841
tp
28412842
case tp: ConstantType =>
28422843
tp
2844+
case tp: HKTypeLambda =>
2845+
tp
28432846
case tp: TypeProxy =>
28442847
disjointnessBoundary(tp.superTypeNormalized)
28452848
case tp: WildcardType =>
@@ -2865,6 +2868,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28652868
case (tp1: AndType, tp2) =>
28662869
provablyDisjoint(tp1.tp1, tp2, pending) || provablyDisjoint(tp1.tp2, tp2, pending)
28672870

2871+
// Cases involving type lambdas
2872+
case (tp1: HKTypeLambda, tp2: HKTypeLambda) =>
2873+
tp1.paramNames.sizeCompare(tp2.paramNames) != 0
2874+
|| provablyDisjoint(tp1.resultType, tp2.resultType, pending)
2875+
case (tp1: HKTypeLambda, tp2) =>
2876+
!tp2.isDirectRef(defn.AnyKindClass)
2877+
case (tp1, tp2: HKTypeLambda) =>
2878+
!tp1.isDirectRef(defn.AnyKindClass)
2879+
28682880
/* Cases where both are unique values (enum cases or constant types)
28692881
*
28702882
* When both are TermRef's, we look at the symbols. We do not try to

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

+5-1
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)