diff options
-rw-r--r-- | src/library/scala/reflect/ClassManifest.scala | 4 | ||||
-rw-r--r-- | src/library/scala/reflect/Manifest.scala | 25 | ||||
-rw-r--r-- | test/files/run/manifests.scala | 19 |
3 files changed, 36 insertions, 12 deletions
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala index 466b57dea7..d393ac47fa 100644 --- a/src/library/scala/reflect/ClassManifest.scala +++ b/src/library/scala/reflect/ClassManifest.scala @@ -46,7 +46,9 @@ trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable { /** The Scala type described by this manifest. */ - lazy val tpe: mirror.Type = reflect.mirror.classToType(erasure) + lazy val tpe: mirror.Type = mirror.classToType(erasure) + + def symbol: mirror.Symbol = mirror.classToSymbol(erasure) private def subtype(sub: jClass[_], sup: jClass[_]): Boolean = { def loop(left: Set[jClass[_]], seen: Set[jClass[_]]): Boolean = { diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index 6c02878b19..e5df487be9 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -76,6 +76,8 @@ abstract class AnyValManifest[T <: AnyVal](override val toString: String) extend * in client code. */ object Manifest { + import mirror.{ definitions => mdefs } + def valueManifests: List[AnyValManifest[_]] = List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) @@ -152,34 +154,40 @@ object Manifest { } val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") { + override def symbol = mdefs.AnyClass override def <:<(that: ClassManifest[_]): Boolean = (that eq this) private def readResolve(): Any = Manifest.Any } val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") { + override def symbol = mdefs.ObjectClass override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) private def readResolve(): Any = Manifest.Object } val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") { + override def symbol = mdefs.AnyValClass override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) private def readResolve(): Any = Manifest.AnyVal } val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") { + override def symbol = mdefs.NullClass override def <:<(that: ClassManifest[_]): Boolean = (that ne null) && (that ne Nothing) && !(that <:< AnyVal) private def readResolve(): Any = Manifest.Null } val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") { + override def symbol = mdefs.NothingClass override def <:<(that: ClassManifest[_]): Boolean = (that ne null) private def readResolve(): Any = Manifest.Nothing } private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { lazy val erasure = value.getClass - override lazy val tpe = mirror.SingleType(mirror.NoPrefix, InstanceRefSymbol(value)) // todo: change to freevar + override lazy val symbol = InstanceRefSymbol(value) // todo: change to freevar + override lazy val tpe = mirror.SingleType(mirror.NoPrefix, symbol) override lazy val toString = value.toString + ".type" } @@ -208,8 +216,12 @@ object Manifest { def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) + /** Phantom types have no runtime representation; they all erase to Object, + * but the Symbol preserves their identity. + */ private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) { - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] + override lazy val tpe = namedType(mirror.NoPrefix, symbol, Nil) + override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] override val hashCode = System.identityHashCode(this) } @@ -218,13 +230,13 @@ object Manifest { private class ClassTypeManifest[T](prefix: Option[Manifest[_]], val erasure: Predef.Class[_], override val typeArguments: List[Manifest[_]]) extends Manifest[T] { + override lazy val tpe = { - val clazz = classToSymbol(erasure) val pre = prefix match { case Some(pm) => pm.tpe - case None => clazz.owner.thisPrefix + case None => symbol.owner.thisPrefix } - namedType(pre, clazz, typeArguments map (_.tpe)) + namedType(pre, symbol, typeArguments map (_.tpe)) } override def toString = @@ -282,8 +294,9 @@ object Manifest { * instead of in scala-compiler.jar. */ def apply[T](_tpe: mirror.Type): Manifest[T] = new Manifest[T] { + override def symbol = _tpe.typeSymbol override lazy val tpe = _tpe - override def erasure = mirror.typeToClass(_tpe.erasedType) + override def erasure = mirror.typeToClass(_tpe.erasedType) override def toString = _tpe.toString } } diff --git a/test/files/run/manifests.scala b/test/files/run/manifests.scala index 1da06b8aee..6b6ea80b34 100644 --- a/test/files/run/manifests.scala +++ b/test/files/run/manifests.scala @@ -46,11 +46,20 @@ object Test def showsContravariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](CONTRA) showsExpectedVariance - def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = (ev1 <:< ev2, ev2 <:< ev1) match { - case (true, true) => SAME - case (true, false) => SUB - case (false, true) => SUPER - case (false, false) => NONE + def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = { + // checking types as well + if ((ev1 <:< ev2) != (ev1.tpe <:< ev2.tpe)) + println("Failed! " + ((ev1, ev2))) + + if ((ev2 <:< ev1) != (ev2.tpe <:< ev1.tpe)) + println("Failed! " + ((ev2, ev1))) + + (ev1 <:< ev2, ev2 <:< ev1) match { + case (true, true) => SAME + case (true, false) => SUB + case (false, true) => SUPER + case (false, false) => NONE + } } def assertAnyRef[T: Manifest] = List( |