diff options
author | Paul Phillips <paulp@improving.org> | 2010-03-02 19:44:01 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-03-02 19:44:01 +0000 |
commit | 2a04d577874fa2a4a447a6caef8076e3ba98b32d (patch) | |
tree | 6428793b78e99cbc35305deae8158083dc2620ec | |
parent | dc9bb2630601b49d5cee326566854b96a61b412b (diff) | |
download | scala-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.
-rw-r--r-- | src/library/scala/reflect/ClassManifest.scala | 10 | ||||
-rw-r--r-- | src/library/scala/reflect/Manifest.scala | 18 |
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) } |