diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 052e090d5985..e8354dcf5768 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -2813,6 +2813,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling tp.symbol match case cls: ClassSymbol => if cls == defn.SingletonClass then defn.AnyType + else if cls.typeParams.nonEmpty then EtaExpansion(tp) else tp case sym => if !ctx.erasedTypes && sym == defn.FromJavaObjectSymbol then defn.AnyType @@ -2833,6 +2834,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling tp case tp: ConstantType => tp + case tp: HKTypeLambda => + tp case tp: TypeProxy => disjointnessBoundary(tp.superTypeNormalized) case tp: WildcardType => @@ -2858,6 +2861,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling case (tp1: AndType, tp2) => provablyDisjoint(tp1.tp1, tp2, pending) || provablyDisjoint(tp1.tp2, tp2, pending) + // Cases involving type lambdas + case (tp1: HKTypeLambda, tp2: HKTypeLambda) => + tp1.paramNames.sizeCompare(tp2.paramNames) != 0 + || provablyDisjoint(tp1.resultType, tp2.resultType, pending) + case (tp1: HKTypeLambda, tp2) => + !tp2.isDirectRef(defn.AnyKindClass) + case (tp1, tp2: HKTypeLambda) => + !tp1.isDirectRef(defn.AnyKindClass) + /* Cases where both are unique values (enum cases or constant types) * * 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 def existsCommonBaseTypeWithDisjointArguments: Boolean = if !typeArgsMatch(tp1, cls1) || !typeArgsMatch(tp2, cls2) then /* We have an unapplied polymorphic class type or otherwise not star-kinded one. - * This does not happen with match types, but happens when comming from the Space engine. + * This does not happen with match types, but happens when coming from the Space engine. * In that case, we cannot prove disjointness based on type arguments. */ false diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index f5cb8eab73a4..352bd54c6915 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -154,7 +154,11 @@ object TypeTestsCasts { case x => // always false test warnings are emitted elsewhere - TypeComparer.provablyDisjoint(x, tpe.derivedAppliedType(tycon, targs.map(_ => WildcardType))) + // provablyDisjoint wants fully applied types as input; because we're in the middle of erasure, we sometimes get raw types here + val xApplied = + val tparams = x.typeParams + if tparams.isEmpty then x else x.appliedTo(tparams.map(_ => WildcardType)) + TypeComparer.provablyDisjoint(xApplied, tpe.derivedAppliedType(tycon, targs.map(_ => WildcardType))) || typeArgsTrivial(X, tpe) ||| i"its type arguments can't be determined from $X" }