diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index ca5059c944c6..fa84b914a561 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -2881,6 +2881,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling true case (_, _: HKLambda) => true + /* Nothing is not a class type in the spec but dotc represents it as if it were one. + * Get it out of the way early to avoid mistakes (see for example #20897). + * Nothing ⋔ T and T ⋔ Nothing for all T. + */ + case (tp1, tp2) if tp1.isExactlyNothing || tp2.isExactlyNothing => + true case (tp1: OrType, _) => provablyDisjoint(tp1.tp1, tp2) && provablyDisjoint(tp1.tp2, tp2) case (_, tp2: OrType) => @@ -2891,6 +2897,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling case (_, tp2: AndType) => !(tp2 <:< tp1) && (provablyDisjoint(tp1, tp2.tp2) || provablyDisjoint(tp1, tp2.tp1)) + /* Handle AnyKind now for the same reason as Nothing above: it is not a real class type. + * Other than the rules with Nothing, unions and intersections, there is structurally + * no rule such that AnyKind ⋔ T or T ⋔ AnyKind for any T. + */ + case (tp1, tp2) if tp1.isDirectRef(AnyKindClass) || tp2.isDirectRef(AnyKindClass) => + false case (tp1: NamedType, _) if gadtBounds(tp1.symbol) != null => provablyDisjoint(gadtBounds(tp1.symbol).uncheckedNN.hi, tp2) || provablyDisjoint(tp1.superTypeNormalized, tp2) diff --git a/compiler/test/dotc/pos-test-pickling.blacklist b/compiler/test/dotc/pos-test-pickling.blacklist index fd40d8b3577a..8293d0a69d79 100644 --- a/compiler/test/dotc/pos-test-pickling.blacklist +++ b/compiler/test/dotc/pos-test-pickling.blacklist @@ -57,6 +57,7 @@ i15158.scala i15155.scala i15827.scala i18211.scala +i20897.scala # Opaque type i5720.scala @@ -112,4 +113,3 @@ i15525.scala i19955a.scala i19955b.scala i20053b.scala - diff --git a/tests/pos/i20897.scala b/tests/pos/i20897.scala new file mode 100644 index 000000000000..ecfac5b1615e --- /dev/null +++ b/tests/pos/i20897.scala @@ -0,0 +1,10 @@ +object Test: + type Disj[A, B] = + A match + case B => true + case _ => false + + def f(a: Disj[1 | Nothing, 2 | Nothing]): Unit = () + + val t = f(false) +end Test