@@ -542,6 +542,15 @@ trait Implicits { self: Typer =>
542
542
}
543
543
544
544
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
+
545
554
val lift = new TypeMap {
546
555
def apply (t : Type ) = t match {
547
556
case t : TypeRef =>
@@ -553,7 +562,7 @@ trait Implicits { self: Typer =>
553
562
if (variance > 0 ) mapOver(t) else t
554
563
}
555
564
}
556
- ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp)
565
+ ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp) || eqNullable
557
566
}
558
567
559
568
/** Check that equality tests between types `ltp` and `rtp` make sense */
@@ -670,27 +679,10 @@ trait Implicits { self: Typer =>
670
679
case _ => false
671
680
}
672
681
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
-
683
682
def validEqAnyArgs (tp1 : Type , tp2 : Type ) = {
684
683
List (tp1, tp2).foreach(fullyDefinedType(_, " eqAny argument" , pos))
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
684
+ assumedCanEqual(tp1, tp2) || ! hasEq(tp1) && ! hasEq(tp2) ||
685
+ { implicits.println(i " invalid eqAny[ $tp1, $tp2] " ); false }
694
686
}
695
687
if (ctx.reporter.hasErrors)
696
688
nonMatchingImplicit(ref, ctx.reporter.removeBufferedMessages)
0 commit comments