diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Duplicators.scala | 31 |
1 files changed, 19 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) } } - + } } |