summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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"
}