Skip to content

Commit 334db97

Browse files
authored
Merge pull request #1833 from dotty-staging/fix-#1793
Fix #1793: allow multiversal comparisons between Null and X
2 parents 51042d1 + aaf0a63 commit 334db97

File tree

5 files changed

+26
-6
lines changed

5 files changed

+26
-6
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,15 @@ trait Implicits { self: Typer =>
542542
}
543543

544544
private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) = {
545+
def eqNullable: Boolean = {
546+
val other =
547+
if (ltp.isRef(defn.NullClass)) rtp
548+
else if (rtp.isRef(defn.NullClass)) ltp
549+
else NoType
550+
551+
(other ne NoType) && !other.derivesFrom(defn.AnyValClass)
552+
}
553+
545554
val lift = new TypeMap {
546555
def apply(t: Type) = t match {
547556
case t: TypeRef =>
@@ -553,7 +562,7 @@ trait Implicits { self: Typer =>
553562
if (variance > 0) mapOver(t) else t
554563
}
555564
}
556-
ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp)
565+
ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp) || eqNullable
557566
}
558567

559568
/** Check that equality tests between types `ltp` and `rtp` make sense */
@@ -669,6 +678,7 @@ trait Implicits { self: Typer =>
669678
case result: AmbiguousImplicits => true
670679
case _ => false
671680
}
681+
672682
def validEqAnyArgs(tp1: Type, tp2: Type) = {
673683
List(tp1, tp2).foreach(fullyDefinedType(_, "eqAny argument", pos))
674684
assumedCanEqual(tp1, tp2) || !hasEq(tp1) && !hasEq(tp2) ||

compiler/test/dotc/scala-collections.blacklist

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,6 @@
164164
# | ^^^
165165
# | not found: msg
166166

167-
../scala-scala/src/library/scala/ref/WeakReference.scala
168-
# 33 | if (x != null) Some(x) else None
169-
# | ^^^^^^^^^^^
170-
# | Values of types wr.underlying.java$lang$ref$WeakReference$$T and Null cannot be compared with == or !=
171-
172167
../scala-scala/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
173168
# 51 | import Manifest._
174169
# | ^^^^^^^^

compiler/test/dotc/scala-collections.whitelist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@
423423
../scala-scala/src/library/scala/ref/ReferenceQueue.scala
424424
../scala-scala/src/library/scala/ref/ReferenceWrapper.scala
425425
../scala-scala/src/library/scala/ref/SoftReference.scala
426+
../scala-scala/src/library/scala/ref/WeakReference.scala
426427

427428
../scala-scala/src/library/scala/reflect/macros/internal/macroImpl.scala
428429
../scala-scala/src/library/scala/reflect/NoManifest.scala

tests/neg/i1793.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
import scala.ref.WeakReference
3+
def unapply[T <: AnyVal](wr: WeakReference[T]): Option[T] = {
4+
val x = wr.underlying.get
5+
if (x != null) Some(x) else None // error
6+
}
7+
}

tests/pos/i1793.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
import scala.ref.WeakReference
3+
def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = {
4+
val x = wr.underlying.get
5+
if (x != null) Some(x) else None
6+
}
7+
}

0 commit comments

Comments
 (0)