Skip to content

Commit 4c32e1b

Browse files
committed
Fix #1793: allow multiversal comparisons between Null and X
1 parent 59f783a commit 4c32e1b

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,28 @@ trait Implicits { self: Typer =>
669669
case result: AmbiguousImplicits => true
670670
case _ => false
671671
}
672+
673+
// Is Eq[X, Null] or Eq[Null, X] where !(X <:< AnyVal)?
674+
def eqNullable(tp1: Type, tp2: Type): Boolean = {
675+
val other =
676+
if (tp1.stripTypeVar eq defn.NullType) tp2
677+
else if (tp2.stripTypeVar eq defn.NullType) tp1
678+
else NoType
679+
680+
(other ne NoType) && !other.derivesFrom(defn.AnyValClass)
681+
}
682+
672683
def validEqAnyArgs(tp1: Type, tp2: Type) = {
673684
List(tp1, tp2).foreach(fullyDefinedType(_, "eqAny argument", pos))
674-
assumedCanEqual(tp1, tp2) || !hasEq(tp1) && !hasEq(tp2) ||
675-
{ implicits.println(i"invalid eqAny[$tp1, $tp2]"); false }
685+
def invalidEqAny = {
686+
implicits.println(i"invalid eqAny[$tp1, $tp2]")
687+
false
688+
}
689+
690+
assumedCanEqual(tp1, tp2) ||
691+
!hasEq(tp1) && !hasEq(tp2) ||
692+
eqNullable(tp1, tp2) ||
693+
invalidEqAny
676694
}
677695
if (ctx.reporter.hasErrors)
678696
nonMatchingImplicit(ref, ctx.reporter.removeBufferedMessages)

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)