Improved equality for Manifests. Implements symmetry via

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.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@21043 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2010-03-02 19:44:01 +00:00
parent 083c58b755
commit 89e63633b1
2 changed files with 24 additions and 6 deletions

View File

@ -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. */
@ -72,14 +72,18 @@ trait ClassManifest[T] extends OptManifest[T] {
* erasure of the type. */
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

View File

@ -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)
}