Skip to content

Commit a479fa4

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 f91c8d4 commit a479fa4

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2813,6 +2813,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28132813
tp.symbol match
28142814
case cls: ClassSymbol =>
28152815
if cls == defn.SingletonClass then defn.AnyType
2816+
else if cls.typeParams.nonEmpty then EtaExpansion(tp)
28162817
else tp
28172818
case sym =>
28182819
if !ctx.erasedTypes && sym == defn.FromJavaObjectSymbol then defn.AnyType
@@ -2833,6 +2834,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28332834
tp
28342835
case tp: ConstantType =>
28352836
tp
2837+
case tp: HKTypeLambda =>
2838+
tp
28362839
case tp: TypeProxy =>
28372840
disjointnessBoundary(tp.superTypeNormalized)
28382841
case tp: WildcardType =>
@@ -2858,6 +2861,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28582861
case (tp1: AndType, tp2) =>
28592862
provablyDisjoint(tp1.tp1, tp2, pending) || provablyDisjoint(tp1.tp2, tp2, pending)
28602863

2864+
// Cases involving type lambdas
2865+
case (tp1: HKTypeLambda, tp2: HKTypeLambda) =>
2866+
tp1.paramNames.sizeCompare(tp2.paramNames) != 0
2867+
|| provablyDisjoint(tp1.resultType, tp2.resultType, pending)
2868+
case (tp1: HKTypeLambda, tp2) =>
2869+
!tp2.isDirectRef(defn.AnyKindClass)
2870+
case (tp1, tp2: HKTypeLambda) =>
2871+
!tp1.isDirectRef(defn.AnyKindClass)
2872+
28612873
/* Cases where both are unique values (enum cases or constant types)
28622874
*
28632875
* When both are TermRef's, we look at the symbols. We do not try to
@@ -2918,7 +2930,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
29182930
def existsCommonBaseTypeWithDisjointArguments: Boolean =
29192931
if !typeArgsMatch(tp1, cls1) || !typeArgsMatch(tp2, cls2) then
29202932
/* We have an unapplied polymorphic class type or otherwise not star-kinded one.
2921-
* This does not happen with match types, but happens when comming from the Space engine.
2933+
* This does not happen with match types, but happens when coming from the Space engine.
29222934
* In that case, we cannot prove disjointness based on type arguments.
29232935
*/
29242936
false

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)