aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-12-19 16:58:07 +0100
committerGitHub <noreply@github.com>2016-12-19 16:58:07 +0100
commit334db9777d674ed17763375d5b80cb884b9eca44 (patch)
treee5ddba2e0ac8e5b4dfc22799f1f713c11a4af2e0
parent51042d1834674e9c56a8247ab76252a74d5bbc07 (diff)
parentaaf0a630c9d24b628e5ec115f963ead8c9aaa3f8 (diff)
downloaddotty-334db9777d674ed17763375d5b80cb884b9eca44.tar.gz
dotty-334db9777d674ed17763375d5b80cb884b9eca44.tar.bz2
dotty-334db9777d674ed17763375d5b80cb884b9eca44.zip
Merge pull request #1833 from dotty-staging/fix-#1793
Fix #1793: allow multiversal comparisons between Null and X
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala12
-rw-r--r--compiler/test/dotc/scala-collections.blacklist5
-rw-r--r--compiler/test/dotc/scala-collections.whitelist1
-rw-r--r--tests/neg/i1793.scala7
-rw-r--r--tests/pos/i1793.scala7
5 files changed, 26 insertions, 6 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index 331533204..303953e73 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -542,6 +542,15 @@ trait Implicits { self: Typer =>
}
private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) = {
+ def eqNullable: Boolean = {
+ val other =
+ if (ltp.isRef(defn.NullClass)) rtp
+ else if (rtp.isRef(defn.NullClass)) ltp
+ else NoType
+
+ (other ne NoType) && !other.derivesFrom(defn.AnyValClass)
+ }
+
val lift = new TypeMap {
def apply(t: Type) = t match {
case t: TypeRef =>
@@ -553,7 +562,7 @@ trait Implicits { self: Typer =>
if (variance > 0) mapOver(t) else t
}
}
- ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp)
+ ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp) || eqNullable
}
/** Check that equality tests between types `ltp` and `rtp` make sense */
@@ -669,6 +678,7 @@ trait Implicits { self: Typer =>
case result: AmbiguousImplicits => true
case _ => false
}
+
def validEqAnyArgs(tp1: Type, tp2: Type) = {
List(tp1, tp2).foreach(fullyDefinedType(_, "eqAny argument", pos))
assumedCanEqual(tp1, tp2) || !hasEq(tp1) && !hasEq(tp2) ||
diff --git a/compiler/test/dotc/scala-collections.blacklist b/compiler/test/dotc/scala-collections.blacklist
index f7744401a..97f12244e 100644
--- a/compiler/test/dotc/scala-collections.blacklist
+++ b/compiler/test/dotc/scala-collections.blacklist
@@ -164,11 +164,6 @@
# | ^^^
# | not found: msg
-../scala-scala/src/library/scala/ref/WeakReference.scala
-# 33 | if (x != null) Some(x) else None
-# | ^^^^^^^^^^^
-# | Values of types wr.underlying.java$lang$ref$WeakReference$$T and Null cannot be compared with == or !=
-
../scala-scala/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
# 51 | import Manifest._
# | ^^^^^^^^
diff --git a/compiler/test/dotc/scala-collections.whitelist b/compiler/test/dotc/scala-collections.whitelist
index 33c8e22f0..cdec1ab12 100644
--- a/compiler/test/dotc/scala-collections.whitelist
+++ b/compiler/test/dotc/scala-collections.whitelist
@@ -423,6 +423,7 @@
../scala-scala/src/library/scala/ref/ReferenceQueue.scala
../scala-scala/src/library/scala/ref/ReferenceWrapper.scala
../scala-scala/src/library/scala/ref/SoftReference.scala
+../scala-scala/src/library/scala/ref/WeakReference.scala
../scala-scala/src/library/scala/reflect/macros/internal/macroImpl.scala
../scala-scala/src/library/scala/reflect/NoManifest.scala
diff --git a/tests/neg/i1793.scala b/tests/neg/i1793.scala
new file mode 100644
index 000000000..ea6d3bcb7
--- /dev/null
+++ b/tests/neg/i1793.scala
@@ -0,0 +1,7 @@
+object Test {
+ import scala.ref.WeakReference
+ def unapply[T <: AnyVal](wr: WeakReference[T]): Option[T] = {
+ val x = wr.underlying.get
+ if (x != null) Some(x) else None // error
+ }
+}
diff --git a/tests/pos/i1793.scala b/tests/pos/i1793.scala
new file mode 100644
index 000000000..fed8a6165
--- /dev/null
+++ b/tests/pos/i1793.scala
@@ -0,0 +1,7 @@
+object Test {
+ import scala.ref.WeakReference
+ def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = {
+ val x = wr.underlying.get
+ if (x != null) Some(x) else None
+ }
+}