summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-12-09 17:03:48 +0000
committerPaul Phillips <paulp@improving.org>2009-12-09 17:03:48 +0000
commita4f1bfec2c2e1067964fad4868ae701374ab1ccd (patch)
tree932a770e73b585afd4dd6a9f783bc9c4671cdfc5 /src
parent8bd78809c494666cb49904458c09f256b27a9e2f (diff)
downloadscala-a4f1bfec2c2e1067964fad4868ae701374ab1ccd.tar.gz
scala-a4f1bfec2c2e1067964fad4868ae701374ab1ccd.tar.bz2
scala-a4f1bfec2c2e1067964fad4868ae701374ab1ccd.zip
Took manifests a little closer to the finish line.
doesn't work but the relationships between all the top, nearly top, and bottom types should all be all correct. (See lengthy test case.)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala30
-rw-r--r--src/library/scala/reflect/ClassManifest.scala19
-rw-r--r--src/library/scala/reflect/Manifest.scala53
3 files changed, 64 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index bb7f99f222..2bd296b65d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -724,16 +724,20 @@ self: Analyzer =>
/** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree =
if (args contains EmptyTree) EmptyTree
- else
- typed { atPos(tree.pos.focus) {
- Apply(
- TypeApply(
- Select(gen.mkAttributedRef(if (full) FullManifestModule else PartialManifestModule), constructor),
- List(TypeTree(tparg))
- ),
- args.toList
- )
- }}
+ else typedPos(tree.pos.focus) {
+ Apply(
+ TypeApply(
+ Select(gen.mkAttributedRef(if (full) FullManifestModule else PartialManifestModule), constructor),
+ List(TypeTree(tparg))
+ ),
+ args.toList
+ )
+ }
+
+ /** Creates a tree representing one of the singleton manifests.*/
+ def findSingletonManifest(name: String) = typedPos(tree.pos.focus) {
+ Select(gen.mkAttributedRef(FullManifestModule), name)
+ }
/** Re-wraps a type in a manifest before calling inferImplicit on the result */
def findManifest(tp: Type, manifestClass: Symbol = if (full) FullManifestClass else PartialManifestClass) =
@@ -750,9 +754,9 @@ self: Analyzer =>
manifestOfType(tp1.deconst, full)
case TypeRef(pre, sym, args) =>
if (isValueClass(sym) || isPhantomClass(sym)) {
- typed { atPos(tree.pos.focus) {
- Select(gen.mkAttributedRef(FullManifestModule), sym.name.toString)
- }}
+ findSingletonManifest(sym.name.toString)
+ } else if (sym == ObjectClass || sym == AnyRefClass) {
+ findSingletonManifest("Object")
} else if (sym == ArrayClass && args.length == 1) {
manifestFactoryCall("arrayType", args.head, findSubManifest(args.head))
} else if (sym.isClass) {
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala
index dd15e2f8b8..81c36fffcb 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifest.scala
@@ -52,8 +52,18 @@ trait ClassManifest[T] extends OptManifest[T] {
case _ => false
}
}
- (this.erasure == that.erasure || subtype(this.erasure, that.erasure)) &&
- subargs(this.typeArguments, that.typeArguments)
+
+ import Manifest.{ AnyVal, Nothing, Null }
+
+ that match {
+ // All types which conform to AnyVal will override <:<.
+ case _: AnyValManifest[_] => false
+ // Anything which conforms to a bottom type will override <:<.
+ case AnyVal | Nothing | Null => false
+ case _ =>
+ (this.erasure == that.erasure || subtype(this.erasure, that.erasure)) &&
+ subargs(this.typeArguments, that.typeArguments)
+ }
}
/** Tests whether the type represented by this manifest is a supertype
@@ -68,7 +78,8 @@ trait ClassManifest[T] extends OptManifest[T] {
* implementation is an approximation, as the test is done on the
* erasure of the type. */
override def equals(that: Any): Boolean = that match {
- case m: ClassManifest[_] => this.erasure == m.erasure
+ case _: AnyValManifest[_] => false
+ case m: ClassManifest[_] => this.erasure == m.erasure
case _ => false
}
@@ -153,7 +164,7 @@ object ClassManifest {
case _ => classType[T with AnyRef](clazz).asInstanceOf[ClassManifest[T]]
}
- def singleType[T](value: Any): Manifest[T] = Manifest.singleType(value)
+ def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest.singleType(value)
/** ClassManifest for the class type `clazz', where `clazz' is
* a top-level or static class.
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index f7ed9b4be9..71324a9802 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -34,6 +34,13 @@ trait Manifest[T] extends ClassManifest[T] {
Manifest.classType[Array[T]](arrayClass[T](erasure))
}
+@serializable
+trait AnyValManifest[T] extends Manifest[T] {
+ import Manifest.{ Any, AnyVal }
+ override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) || (that eq AnyVal)
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
+}
+
/** <ps>
* This object is used by the compiler and <b>should not be used in client
* code</b>. The object <code>Manifest</code> defines factory methods for
@@ -45,8 +52,7 @@ trait Manifest[T] extends ClassManifest[T] {
* </p>
*/
object Manifest {
-
- val Byte = new (Manifest[Byte] @serializable) {
+ val Byte = new (AnyValManifest[Byte] @serializable) {
def erasure = java.lang.Byte.TYPE
override def toString = "Byte"
override def newArray(len: Int): Array[Byte] = new Array[Byte](len)
@@ -54,7 +60,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte()
}
- val Short = new (Manifest[Short] @serializable) {
+ val Short = new (AnyValManifest[Short] @serializable) {
def erasure = java.lang.Short.TYPE
override def toString = "Short"
override def newArray(len: Int): Array[Short] = new Array[Short](len)
@@ -62,7 +68,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort()
}
- val Char = new (Manifest[Char] @serializable) {
+ val Char = new (AnyValManifest[Char] @serializable) {
def erasure = java.lang.Character.TYPE
override def toString = "Char"
override def newArray(len: Int): Array[Char] = new Array[Char](len)
@@ -70,7 +76,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar()
}
- val Int = new (Manifest[Int] @serializable) {
+ val Int = new (AnyValManifest[Int] @serializable) {
def erasure = java.lang.Integer.TYPE
override def toString = "Int"
override def newArray(len: Int): Array[Int] = new Array[Int](len)
@@ -78,7 +84,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt()
}
- val Long = new (Manifest[Long] @serializable) {
+ val Long = new (AnyValManifest[Long] @serializable) {
def erasure = java.lang.Long.TYPE
override def toString = "Long"
override def newArray(len: Int): Array[Long] = new Array[Long](len)
@@ -86,7 +92,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong()
}
- val Float = new (Manifest[Float] @serializable) {
+ val Float = new (AnyValManifest[Float] @serializable) {
def erasure = java.lang.Float.TYPE
override def toString = "Float"
override def newArray(len: Int): Array[Float] = new Array[Float](len)
@@ -94,7 +100,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat()
}
- val Double = new (Manifest[Double] @serializable) {
+ val Double = new (AnyValManifest[Double] @serializable) {
def erasure = java.lang.Double.TYPE
override def toString = "Double"
override def newArray(len: Int): Array[Double] = new Array[Double](len)
@@ -102,7 +108,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble()
}
- val Boolean = new (Manifest[Boolean] @serializable) {
+ val Boolean = new (AnyValManifest[Boolean] @serializable) {
def erasure = java.lang.Boolean.TYPE
override def toString = "Boolean"
override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len)
@@ -110,7 +116,7 @@ object Manifest {
override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean()
}
- val Unit = new (Manifest[Unit] @serializable) {
+ val Unit = new (AnyValManifest[Unit] @serializable) {
def erasure = java.lang.Void.TYPE
override def toString = "Unit"
override def newArray(len: Int): Array[Unit] = new Array[Unit](len)
@@ -120,37 +126,42 @@ object Manifest {
val Any: Manifest[Any] = new ClassTypeManifest[Any](None, classOf[java.lang.Object], List()) {
override def toString = "Any"
- // todo: re-implement <:<
+ override def <:<(that: ClassManifest[_]): Boolean = (that eq this)
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
val Object: Manifest[Object] = new ClassTypeManifest[Object](None, classOf[java.lang.Object], List()) {
override def toString = "Object"
- // todo: re-implement <:<
+ override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
val AnyVal: Manifest[AnyVal] = new ClassTypeManifest[AnyVal](None, classOf[java.lang.Object], List()) {
override def toString = "AnyVal"
- // todo: re-implement <:<
+ override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
val Null: Manifest[Null] = new ClassTypeManifest[Null](None, classOf[java.lang.Object], List()) {
override def toString = "Null"
- // todo: re-implement <:<
+ override def <:<(that: ClassManifest[_]): Boolean =
+ (that ne null) && (that ne Nothing) && !(that <:< AnyVal)
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
val Nothing: Manifest[Nothing] = new ClassTypeManifest[Nothing](None, classOf[java.lang.Object], List()) {
override def toString = "Nothing"
- // todo: re-implement <:<
+ override def <:<(that: ClassManifest[_]): Boolean = (that ne null)
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
/** Manifest for the singleton type `value.type'. */
- def singleType[T](value: Any): Manifest[T] =
+ def singleType[T <: AnyRef](value: AnyRef): Manifest[T] =
new (Manifest[T] @serializable) {
- lazy val erasure =
- value match {
- case anyRefValue: AnyRef => anyRefValue.getClass
- case anyValue => error("There is no singleton type for AnyVal values")
- }
+ /** Note - this was doing a type match on value to exclude AnyVal, which does not work.
+ * Pattern matching _: AnyRef matches everything because of boxing.
+ */
+ lazy val erasure = value.getClass
override lazy val toString = value.toString + ".type"
}