diff options
author | Vlad Ureche <vlad.ureche@gmail.com> | 2012-08-06 20:05:49 +0200 |
---|---|---|
committer | Vlad Ureche <vlad.ureche@gmail.com> | 2012-08-06 20:10:20 +0200 |
commit | f492d0aaaa956cfeb1f5efdd29bccf4bc8a35e18 (patch) | |
tree | 4d28b3d08a886067160de3a098f6e8a51a627c7b | |
parent | ba402c457aecf7d94038534775b7b063d7d5bd9e (diff) | |
download | scala-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.scala | 31 | ||||
-rw-r--r-- | test/files/pos/SI-5788.scala | 4 |
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]() +} |