Skip to content

Commit

Permalink
Fix scala#20897: Make Nothing ⋔ Nothing and Null ⋔ Null, as per s…
Browse files Browse the repository at this point in the history
…pec.

`derivesFrom` normally returns `false` when the receiver is
`Nothing` or `Null`. However, it returns `true` if the right-hand-
side happens to be exactly the same class. For the purpose of
computing `provablyDisjoint`, we have to explicitly exclude those.

(Note that the spec text per se only explicitly specifies
`Nothing ⋔ Nothing`, not `Null ⋔ Null`, but that's because the spec
text punts on the `Null` issue. The intent of `provablyDisjoint`
is that there is no *non-null* value belonging to both types.)
  • Loading branch information
sjrd committed Jul 22, 2024
1 parent af933c4 commit 9f1ff63
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3187,9 +3187,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
else child
}.filter(child => child.exists && child != cls)

// TODO? Special-case for Nothing and Null? We probably need Nothing/Null disjoint from Nothing/Null
def eitherDerivesFromOther(cls1: Symbol, cls2: Symbol): Boolean =
cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1)
if cls1 eq cls2 then
cls1 != defn.NothingClass && cls1 != defn.NullClass
else
cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1)

def smallestNonTraitBase(cls: Symbol): Symbol =
cls.asClass.baseClasses.find(!_.is(Trait)).get
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/dotc/pos-test-pickling.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ mt-redux-norm.perspective.scala
i18211.scala
10867.scala
named-tuples1.scala
i20897.scala

# Opaque type
i5720.scala
Expand Down Expand Up @@ -134,4 +135,3 @@ parsercombinators-new-syntax.scala
hylolib-deferred-given
hylolib-cb
hylolib

10 changes: 10 additions & 0 deletions tests/pos/i20897.scala
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 9f1ff63

Please sign in to comment.