summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Iry <jamesiry@gmail.com>2013-11-08 11:28:06 -0800
committerJames Iry <jamesiry@gmail.com>2013-11-08 11:28:06 -0800
commit2af25d797ed34997f0b08e5350774f19b32c6bdd (patch)
tree23f9ff37c5d36b007e11ac6e4e9ea4c34a466840
parent4cdce8546181d96db1b982f00ff4cd229aa0bd2f (diff)
parent5e0dc87e7c124ccd0a4b3456e16756844cee4fd9 (diff)
downloadscala-2af25d797ed34997f0b08e5350774f19b32c6bdd.tar.gz
scala-2af25d797ed34997f0b08e5350774f19b32c6bdd.tar.bz2
scala-2af25d797ed34997f0b08e5350774f19b32c6bdd.zip
Merge pull request #3094 from retronym/topic/erasure-opt
Avoid needless TypeRef allocation during erasure.
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala28
-rw-r--r--test/files/run/t6028.check4
4 files changed, 21 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index a4854dfbeb..6fe0f34105 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -1043,7 +1043,7 @@ abstract class Erasure extends AddInterfaces
case Literal(ct) if ct.tag == ClazzTag
&& ct.typeValue.typeSymbol != definitions.UnitClass =>
val erased = ct.typeValue match {
- case TypeRef(pre, clazz, args) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(pre, clazz)
+ case tr @ TypeRef(_, clazz, _) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(tr)
case tpe => specialScalaErasure(tpe)
}
treeCopy.Literal(tree, Constant(erased))
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index ba785c14bd..bd17c18119 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -885,7 +885,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol a constant? */
final def isConstant: Boolean = isStable && isConstantType(tpe.resultType)
- /** Is this class nested in another class or module (not a package)? */
+ /** Is this class nested in another class or module (not a package). Includes locally defined classes. */
def isNestedClass = false
/** Is this class locally defined?
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 3eb3a4cdf4..addc7eb389 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -73,9 +73,8 @@ trait Erasure {
// included (use pre.baseType(cls.owner)).
//
// This requires that cls.isClass.
- protected def rebindInnerClass(pre: Type, cls: Symbol): Type = {
- if (cls.owner.isClass) cls.owner.tpe_* else pre // why not cls.isNestedClass?
- }
+ protected def rebindInnerClass(pre: Type, cls: Symbol): Type =
+ if (cls.isTopLevel || cls.isLocal) pre else cls.owner.tpe_*
/** The type of the argument of a value class reference after erasure
* This method needs to be called at a phase no later than erasurephase
@@ -104,14 +103,21 @@ trait Erasure {
abstract class ErasureMap extends TypeMap {
def mergeParents(parents: List[Type]): Type
- def eraseNormalClassRef(pre: Type, clazz: Symbol): Type =
- typeRef(apply(rebindInnerClass(pre, clazz)), clazz, List()) // #2585
+ def eraseNormalClassRef(tref: TypeRef): Type = {
+ val TypeRef(pre, clazz, args) = tref
+ val pre1 = apply(rebindInnerClass(pre, clazz))
+ val args1 = Nil
+ if ((pre eq pre1) && (args eq args1)) tref // OPT
+ else typeRef(pre1, clazz, args1) // #2585
+ }
protected def eraseDerivedValueClassRef(tref: TypeRef): Type = erasedValueClassArg(tref)
def apply(tp: Type): Type = tp match {
case ConstantType(_) =>
tp
+ case st: ThisType if st.sym.isPackageClass =>
+ tp
case st: SubType =>
apply(st.supertype)
case tref @ TypeRef(pre, sym, args) =>
@@ -123,7 +129,7 @@ trait Erasure {
else if (sym == UnitClass) BoxedUnitTpe
else if (sym.isRefinementClass) apply(mergeParents(tp.parents))
else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(tref)
- else if (sym.isClass) eraseNormalClassRef(pre, sym)
+ else if (sym.isClass) eraseNormalClassRef(tref)
else apply(sym.info asSeenFrom (pre, sym.owner)) // alias type or abstract type
case PolyType(tparams, restpe) =>
apply(restpe)
@@ -151,7 +157,7 @@ trait Erasure {
}
def applyInArray(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args) if (sym.isDerivedValueClass) => eraseNormalClassRef(pre, sym)
+ case tref @ TypeRef(_, sym, _) if sym.isDerivedValueClass => eraseNormalClassRef(tref)
case _ => apply(tp)
}
}
@@ -274,11 +280,11 @@ trait Erasure {
}
object boxingErasure extends ScalaErasureMap {
- override def eraseNormalClassRef(pre: Type, clazz: Symbol) =
- if (isPrimitiveValueClass(clazz)) boxedClass(clazz).tpe
- else super.eraseNormalClassRef(pre, clazz)
+ override def eraseNormalClassRef(tref: TypeRef) =
+ if (isPrimitiveValueClass(tref.sym)) boxedClass(tref.sym).tpe
+ else super.eraseNormalClassRef(tref)
override def eraseDerivedValueClassRef(tref: TypeRef) =
- super.eraseNormalClassRef(tref.pre, tref.sym)
+ super.eraseNormalClassRef(tref)
}
/** The intersection dominator (SLS 3.7) of a list of types is computed as follows.
diff --git a/test/files/run/t6028.check b/test/files/run/t6028.check
index b37bf51d73..a6c4db8f11 100644
--- a/test/files/run/t6028.check
+++ b/test/files/run/t6028.check
@@ -24,7 +24,7 @@ package <empty> {
(new <$anon: Function0>(T.this, tryyParam, tryyLocal): Function0)
}
};
- @SerialVersionUID(0) final <synthetic> class $anonfun$foo$1 extends runtime.AbstractFunction0$mcI$sp with Serializable {
+ @SerialVersionUID(0) final <synthetic> class $anonfun$foo$1 extends scala.runtime.AbstractFunction0$mcI$sp with Serializable {
def <init>($outer: T, methodParam$1: Int, methodLocal$1: Int): <$anon: Function0> = {
$anonfun$foo$1.super.<init>();
()
@@ -60,7 +60,7 @@ package <empty> {
};
scala.this.Predef.print(scala.Int.box(barParam$1))
};
- @SerialVersionUID(0) final <synthetic> class $anonfun$tryy$1 extends runtime.AbstractFunction0$mcV$sp with Serializable {
+ @SerialVersionUID(0) final <synthetic> class $anonfun$tryy$1 extends scala.runtime.AbstractFunction0$mcV$sp with Serializable {
def <init>($outer: T, tryyParam$1: Int, tryyLocal$1: runtime.IntRef): <$anon: Function0> = {
$anonfun$tryy$1.super.<init>();
()