@@ -2929,6 +2929,13 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2929
2929
case pair if pending != null && pending.contains(pair) =>
2930
2930
false
2931
2931
2932
+ /* Nothing is not a class type in the spec but dotc represents it as if it were one.
2933
+ * Get it out of the way early to avoid mistakes (see for example #20897).
2934
+ * Nothing ⋔ T and T ⋔ Nothing for all T.
2935
+ */
2936
+ case (tp1, tp2) if tp1.isExactlyNothing || tp2.isExactlyNothing =>
2937
+ true
2938
+
2932
2939
// Cases where there is an intersection or union on the right
2933
2940
case (tp1, tp2 : OrType ) =>
2934
2941
provablyDisjoint(tp1, tp2.tp1, pending) && provablyDisjoint(tp1, tp2.tp2, pending)
@@ -2941,14 +2948,21 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2941
2948
case (tp1 : AndType , tp2) =>
2942
2949
provablyDisjoint(tp1.tp1, tp2, pending) || provablyDisjoint(tp1.tp2, tp2, pending)
2943
2950
2951
+ /* Handle AnyKind now for the same reason as Nothing above: it is not a real class type.
2952
+ * Other than the rules with Nothing, unions and intersections, there is structurally
2953
+ * no rule such that AnyKind ⋔ T or T ⋔ AnyKind for any T.
2954
+ */
2955
+ case (tp1, tp2) if tp1.isDirectRef(AnyKindClass ) || tp2.isDirectRef(AnyKindClass ) =>
2956
+ false
2957
+
2944
2958
// Cases involving type lambdas
2945
2959
case (tp1 : HKTypeLambda , tp2 : HKTypeLambda ) =>
2946
2960
tp1.paramNames.sizeCompare(tp2.paramNames) != 0
2947
2961
|| provablyDisjoint(tp1.resultType, tp2.resultType, pending)
2948
2962
case (tp1 : HKTypeLambda , tp2) =>
2949
- ! tp2.isDirectRef(defn. AnyKindClass )
2963
+ true
2950
2964
case (tp1, tp2 : HKTypeLambda ) =>
2951
- ! tp1.isDirectRef(defn. AnyKindClass )
2965
+ true
2952
2966
2953
2967
/* Cases where both are unique values (enum cases or constant types)
2954
2968
*
@@ -3052,17 +3066,13 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
3052
3066
else child
3053
3067
}.filter(child => child.exists && child != cls)
3054
3068
3055
- // TODO? Special-case for Nothing and Null? We probably need Nothing/Null disjoint from Nothing/Null
3056
3069
def eitherDerivesFromOther (cls1 : Symbol , cls2 : Symbol ): Boolean =
3057
3070
cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1)
3058
3071
3059
3072
def smallestNonTraitBase (cls : Symbol ): Symbol =
3060
3073
cls.asClass.baseClasses.find(! _.is(Trait )).get
3061
3074
3062
- if cls1 == defn.AnyKindClass || cls2 == defn.AnyKindClass then
3063
- // For some reason, A.derivesFrom(AnyKind) returns false, so we have to handle it specially
3064
- false
3065
- else if (eitherDerivesFromOther(cls1, cls2))
3075
+ if (eitherDerivesFromOther(cls1, cls2))
3066
3076
false
3067
3077
else
3068
3078
if (cls1.is(Final ) || cls2.is(Final ))
0 commit comments