summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlad Ureche <vlad.ureche@gmail.com>2012-08-06 20:05:49 +0200
committerVlad Ureche <vlad.ureche@gmail.com>2012-08-06 20:10:20 +0200
commitf492d0aaaa956cfeb1f5efdd29bccf4bc8a35e18 (patch)
tree4d28b3d08a886067160de3a098f6e8a51a627c7b
parentba402c457aecf7d94038534775b7b063d7d5bd9e (diff)
downloadscala-f492d0aaaa956cfeb1f5efdd29bccf4bc8a35e18.tar.gz
scala-f492d0aaaa956cfeb1f5efdd29bccf4bc8a35e18.tar.bz2
scala-f492d0aaaa956cfeb1f5efdd29bccf4bc8a35e18.zip
SI-5788 Tailcalls LabelDefs correctly duplicated
... in specialization. This is a quick hack to get SI-5788 fixed in 2.10.x. The full patch, which fixes the tailcalls LabelDefs will be merged into trunk, as it's too late for big changes. For reference, the complete fix is: e86afe65c8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala31
-rw-r--r--test/files/pos/SI-5788.scala4
2 files changed, 23 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index 63d1bd0e9f..30f9a905f2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -41,7 +41,7 @@ abstract class Duplicators extends Analyzer {
}
protected def newBodyDuplicator(context: Context) = new BodyDuplicator(context)
-
+
def retypedMethod(context: Context, tree: Tree, oldThis: Symbol, newThis: Symbol): Tree =
(newBodyDuplicator(context)).retypedMethod(tree.asInstanceOf[DefDef], oldThis, newThis)
@@ -160,7 +160,7 @@ abstract class Duplicators extends Analyzer {
newsym.setInfo(fixType(ldef.symbol.info))
ldef.symbol = newsym
debuglog("newsym: " + newsym + " info: " + newsym.info)
-
+
case vdef @ ValDef(mods, name, _, rhs) if mods.hasFlag(Flags.LAZY) =>
debuglog("ValDef " + name + " sym.info: " + vdef.symbol.info)
invalidSyms(vdef.symbol) = vdef
@@ -170,7 +170,7 @@ abstract class Duplicators extends Analyzer {
vdef.symbol = newsym
debuglog("newsym: " + newsym + " info: " + newsym.info + ", owner: " + newsym.owner + ", " + newsym.owner.isClass)
if (newsym.owner.isClass) newsym.owner.info.decls enter newsym
-
+
case DefDef(_, name, tparams, vparamss, _, rhs) =>
// invalidate parameters
invalidateAll(tparams ::: vparamss.flatten)
@@ -215,7 +215,7 @@ abstract class Duplicators extends Analyzer {
* Unless overridden, just returns the tree.
*/
def castType(tree: Tree, pt: Type): Tree = tree
-
+
/** Special typer method for re-type checking trees. It expects a typed tree.
* Returns a typed tree that has fresh symbols for all definitions in the original tree.
*
@@ -278,12 +278,19 @@ abstract class Duplicators extends Analyzer {
invalidate(rhs)
ldef.tpe = null
- // since typer does not create the symbols for a LabelDef's params,
- // we do that manually here -- we should really refactor LabelDef to be a subclass of DefDef
- def newParam(p: Tree): Ident = {
- val newsym = p.symbol.cloneSymbol //(context.owner) // TODO owner?
- Ident(newsym.setInfo(fixType(p.symbol.info)))
- }
+ // is this LabelDef generated by tailcalls?
+ val isTailLabel = (ldef.params.length >= 1) && (ldef.params.head.name == nme.THIS)
+
+ // the typer does not create the symbols for a LabelDef's params, so unless they were created before we need
+ // to do it manually here -- but for the tailcalls-generated labels, ValDefs are created before the LabelDef,
+ // so we just need to plug in the name
+ def newParam(p: Tree): Ident =
+ if (isTailLabel)
+ Ident(p.symbol.name) // let the typer pick up the right symbol
+ else {
+ val newsym = p.symbol.cloneSymbol //(context.owner) // TODO owner?
+ Ident(newsym.setInfo(fixType(p.symbol.info)))
+ }
val params1 = params map newParam
val rhs1 = (new TreeSubstituter(params map (_.symbol), params1) transform rhs) // TODO: duplicate?
rhs1.tpe = null
@@ -365,7 +372,7 @@ abstract class Duplicators extends Analyzer {
case EmptyTree =>
// no need to do anything, in particular, don't set the type to null, EmptyTree.tpe_= asserts
tree
-
+
case _ =>
debuglog("Duplicators default case: " + tree.summaryString)
debuglog(" ---> " + tree)
@@ -376,7 +383,7 @@ abstract class Duplicators extends Analyzer {
super.typed(ntree, mode, pt)
}
}
-
+
}
}
diff --git a/test/files/pos/SI-5788.scala b/test/files/pos/SI-5788.scala
new file mode 100644
index 0000000000..93b84bde87
--- /dev/null
+++ b/test/files/pos/SI-5788.scala
@@ -0,0 +1,4 @@
+trait Test {
+ trait B[T]
+ private final def grow[T](): B[T] = grow[T]()
+}