aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-05-10 14:46:43 +0200
committerMartin Odersky <odersky@gmail.com>2016-05-23 16:11:45 +0200
commitcae7b7828934f5b31bfc6b506ca2b5bac8dcde05 (patch)
tree36ab8f12b6bc4211906fb6e1d8a01d18312a3364 /src
parent77498660dbef6cb34e5ebe5bb99647714d9ffeba (diff)
downloaddotty-cae7b7828934f5b31bfc6b506ca2b5bac8dcde05.tar.gz
dotty-cae7b7828934f5b31bfc6b506ca2b5bac8dcde05.tar.bz2
dotty-cae7b7828934f5b31bfc6b506ca2b5bac8dcde05.zip
Add Eq instances of standard types to Predef
To make tests pass, this required a looser specification of `assumedCanEquals`, so that an abstract type T can be compared to arbitrary values, as long as its upper bound can be compared. E.g. T == null T == "abc"
Diffstat (limited to 'src')
-rw-r--r--src/dotty/DottyPredef.scala24
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala16
2 files changed, 38 insertions, 2 deletions
diff --git a/src/dotty/DottyPredef.scala b/src/dotty/DottyPredef.scala
index 9170da476..9e1f2102c 100644
--- a/src/dotty/DottyPredef.scala
+++ b/src/dotty/DottyPredef.scala
@@ -3,6 +3,7 @@ package dotty
import scala.reflect.runtime.universe.TypeTag
import scala.reflect.ClassTag
import scala.Predef.???
+import scala.collection.Seq
/** unimplemented implicit for TypeTag */
object DottyPredef {
@@ -10,4 +11,27 @@ object DottyPredef {
implicit def arrayTag[T](implicit ctag: ClassTag[T]): ClassTag[Array[T]] =
ctag.wrap
+
+ implicit def eqNumber : Eq[Number, Number] = Eq
+ implicit def eqString : Eq[String, String] = Eq
+
+ // true asymmetry, modeling the (somewhat problematic) nature of equals on Proxies
+ implicit def eqProxy : Eq[Proxy, Any] = Eq
+
+ implicit def eqSeq[T, U](implicit eq: Eq[T, U]): Eq[Seq[T], Seq[U]] = Eq
+
+ implicit def eqByteNum : Eq[Byte, Number] = Eq
+ implicit def eqNumByte : Eq[Number, Byte] = Eq
+ implicit def eqCharNum : Eq[Char, Number] = Eq
+ implicit def eqNumChar : Eq[Number, Char] = Eq
+ implicit def eqShortNum : Eq[Short, Number] = Eq
+ implicit def eqNumShort : Eq[Number, Short] = Eq
+ implicit def eqIntNum : Eq[Int, Number] = Eq
+ implicit def eqNumInt : Eq[Number, Int] = Eq
+ implicit def eqLongNum : Eq[Long, Number] = Eq
+ implicit def eqNumLong : Eq[Number, Long] = Eq
+ implicit def eqFloatNum : Eq[Float, Number] = Eq
+ implicit def eqNumFloat : Eq[Number, Float] = Eq
+ implicit def eqDoubleNum: Eq[Double, Number] = Eq
+ implicit def eqNumDouble: Eq[Number, Double] = Eq
}
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index bbad799e0..a5d415d97 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -472,8 +472,20 @@ trait Implicits { self: Typer =>
EmptyTree
}
- private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) =
- ltp.isError || rtp.isError || ltp <:< rtp || rtp <:< ltp
+ private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) = {
+ val lift = new TypeMap {
+ def apply(t: Type) = t match {
+ case t: TypeRef =>
+ t.info match {
+ case TypeBounds(lo, hi) if lo ne hi => hi
+ case _ => t
+ }
+ case _ =>
+ if (variance > 0) mapOver(t) else t
+ }
+ }
+ ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp)
+ }
/** Check that equality tests between types `ltp` and `rtp` make sense */
def checkCanEqual(ltp: Type, rtp: Type, pos: Position)(implicit ctx: Context): Unit =