summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
diff options
context:
space:
mode:
authorAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-09-26 12:44:24 +0000
committerAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-09-26 12:44:24 +0000
commitaeda72b2ea265c7960e8055f526d1bef93940c04 (patch)
treea545420871a718bf307555b39440841ccd219440 /src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
parent567e9f2980999b8c3c0931f44e0b6ae10331a0d9 (diff)
downloadscala-aeda72b2ea265c7960e8055f526d1bef93940c04.tar.gz
scala-aeda72b2ea265c7960e8055f526d1bef93940c04.tar.bz2
scala-aeda72b2ea265c7960e8055f526d1bef93940c04.zip
Fixes #4351.
Added an "Abstract" method info to the specialized phase, which denotes that no implementation should be generated. Previously: trait A[@specialized(Boolean) T] { def foo: T } used to generate: trait A$mcZ$sp extends A[Boolean] { def foo$mcZ$sp = this.foo } which caused cyclic calls because of linearization rules when several traits are mixed together. Now, the following is generated: trait A$mcZ$sp extends A[Boolean] { def foo$mcZ$sp: Boolean } Review by dragos.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index bdb76181a5..2c5ba4e874 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -67,7 +67,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
emptyEnv ++ (sym.info.typeParams zip args filter (kv => isSpecialized(kv._1)))
}
- /** Is typeenv `t1` included in `t2`? All type variables in `t1`
+ /** Does typeenv `t1` include `t2`? All type variables in `t1`
* are defined in `t2` and:
* - are bound to the same type, or
* - are an AnyRef specialization and `t2` is bound to a subtype of AnyRef
@@ -150,6 +150,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
def target = t
}
+ /** Symbol is a specialized abstract method, either specialized or original. The original `t` is abstract. */
+ case class Abstract(t: Symbol) extends SpecializedInfo {
+ def target = t
+ }
+
/** Symbol is a specialized accessor for the `target` field. */
case class SpecializedAccessor(target: Symbol) extends SpecializedInfo {
override def isAccessor = true
@@ -301,7 +306,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
loop(keys map concreteTypes) map (keys zip _ toMap)
}
- /** Does the given tpe need to be specialized in the environment 'env'?
+ /** Does the given 'sym' need to be specialized in the environment 'env'?
* Specialization is needed for
* - members with specialized type parameters found in the given environment
* - constructors of specialized classes
@@ -587,13 +592,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
log("conflicting env for " + m + " env: " + env)
}
else if (m.isDeferred) { // abstract methods
- val specMember = enterMember(m.cloneSymbol(cls)).setFlag(SPECIALIZED).resetFlag(DEFERRED)
- debuglog("deferred " + specMember.fullName + " is forwarded")
-
- info(specMember) = new Forward(specMember) {
- override def target = m.owner.info.member(specializedName(m, env))
- }
+ val specMember = enterMember(m.cloneSymbol(cls)).setFlag(SPECIALIZED).setFlag(DEFERRED)
+ debuglog("deferred " + specMember.fullName + " remains abstract")
+ info(specMember) = new Abstract(specMember)
+ // was: new Forward(specMember) {
+ // override def target = m.owner.info.member(specializedName(m, env))
+ // }
} else if (m.isMethod && !m.hasAccessorFlag) { // other concrete methods
// log("other concrete " + m)
forwardToOverload(m)
@@ -812,15 +817,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
)
}
- /** For each method m that overrides inherited method m', add a special
+ /** For each method m that overrides an inherited method m', add a special
* overload method `om` that overrides the corresponding overload in the
* superclass. For the following example:
*
* class IntFun extends Function1[Int, Int] {
- * def apply(x: Int): Int = ..
+ * def apply(x: Int): Int = ..
* }
*
- * this method will return List('apply$spec$II')
+ * this method will return List('apply$mcII$sp')
*/
private def specialOverrides(clazz: Symbol): List[Symbol] = {
/** Return the overridden symbol in syms that needs a specialized overriding symbol,
@@ -1431,6 +1436,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
Assign(gen.mkAttributedRef(target), Ident(vparamss.head.head.symbol))
log("specialized accessor: " + target + " -> " + rhs1)
localTyper.typed(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs1))
+
+ case Abstract(targ) =>
+ log("abstract: " + targ)
+ val DefDef(mods, name, tparams, vparamss, tpt, rhs) = tree
+ val t = treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs)
+ localTyper.typed(t)
}
case ValDef(mods, name, tpt, rhs) if symbol.hasFlag(SPECIALIZED) && !symbol.isParamAccessor =>