summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-03-02 19:44:01 +0000
committerPaul Phillips <paulp@improving.org>2010-03-02 19:44:01 +0000
commit2a04d577874fa2a4a447a6caef8076e3ba98b32d (patch)
tree6428793b78e99cbc35305deae8158083dc2620ec /src
parentdc9bb2630601b49d5cee326566854b96a61b412b (diff)
downloadscala-2a04d577874fa2a4a447a6caef8076e3ba98b32d.tar.gz
scala-2a04d577874fa2a4a447a6caef8076e3ba98b32d.tar.bz2
scala-2a04d577874fa2a4a447a6caef8076e3ba98b32d.zip
Improved equality for Manifests.
canEquals, and has ClassManifests compare according to erasure but full manifests also compare type arguments. Preserving symmetry means that some things you might expect to be equal are not: val m1 = scala.reflect.ClassManifest.fromClass(classOf[List[String]]) val m2 = manifest[List[String]] (m1 == m2) // false However you can always compare the erasures. (m1.erasure == m2.erasure) // true Review by dpp.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/reflect/ClassManifest.scala10
-rw-r--r--src/library/scala/reflect/Manifest.scala18
2 files changed, 23 insertions, 5 deletions
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala
index a026d162d1..8a6a573048 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifest.scala
@@ -27,7 +27,7 @@ import scala.collection.mutable.{WrappedArray, ArrayBuilder}
* </p>
*/
@serializable
-trait ClassManifest[T] extends OptManifest[T] {
+trait ClassManifest[T] extends OptManifest[T] with Equals {
/** A class representing the type U to which T would be erased. Note
* that there is no subtyping relationship between T and U. */
@@ -73,13 +73,17 @@ trait ClassManifest[T] extends OptManifest[T] {
def >:>(that: ClassManifest[_]): Boolean =
that <:< this
+ def canEqual(other: Any) = other match {
+ case _: ClassManifest[_] => true
+ case _ => false
+ }
+
/** Tests whether the type represented by this manifest is equal to the
* type represented by `that' manifest. BE AWARE: the current
* implementation is an approximation, as the test is done on the
* erasure of the type. */
override def equals(that: Any): Boolean = that match {
- case _: AnyValManifest[_] => false
- case m: ClassManifest[_] => this.erasure == m.erasure
+ case m: ClassManifest[_] if m canEqual this => this.erasure == m.erasure
case _ => false
}
override def hashCode = this.erasure.hashCode
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index 6ca64df67a..b7cb86e1bd 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -27,17 +27,31 @@ import scala.collection.immutable.{List, Nil}
* </p>
*/
@serializable
-trait Manifest[T] extends ClassManifest[T] {
+trait Manifest[T] extends ClassManifest[T] with Equals {
override def typeArguments: List[Manifest[_]] = List()
override def arrayManifest: Manifest[Array[T]] =
Manifest.classType[Array[T]](arrayClass[T](erasure))
+
+ override def canEqual(that: Any): Boolean = that match {
+ case _: Manifest[_] => true
+ case _ => false
+ }
+ override def equals(that: Any): Boolean = that match {
+ case m: Manifest[_] if m canEqual this => (this <:< m) && (m <:< this)
+ case _ => false
+ }
+ override def hashCode = this.erasure.hashCode
}
@serializable
-trait AnyValManifest[T] extends Manifest[T] {
+trait AnyValManifest[T] extends Manifest[T] with Equals {
import Manifest.{ Any, AnyVal }
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) || (that eq AnyVal)
+ override def canEqual(other: Any) = other match {
+ case _: AnyValManifest[_] => true
+ case _ => false
+ }
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
override def hashCode = System.identityHashCode(this)
}