diff options
author | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2011-09-27 17:02:50 +0000 |
---|---|---|
committer | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2011-09-27 17:02:50 +0000 |
commit | 148f4ef194180e03afdeba563aa822e7fb459c75 (patch) | |
tree | 5c36c73595d83d50f1a9474d5e30d763836c6dc7 | |
parent | 7dfb214aaae80675d5c0c95d1faaf9d5fd6da5be (diff) | |
download | scala-148f4ef194180e03afdeba563aa822e7fb459c75.tar.gz scala-148f4ef194180e03afdeba563aa822e7fb459c75.tar.bz2 scala-148f4ef194180e03afdeba563aa822e7fb459c75.zip |
Fixes #4716.
During the generation of the specialized method implementation, local
lazy vals in specialized classes were getting duplicated and assigned
new (different) names. Also, the identifiers referring to them were not
getting updated. This is fixed now. Further, the mutable flag is no
longer getting set for a lazy val during method body duplication.
Review by Dragos.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Duplicators.scala | 29 | ||||
-rw-r--r-- | test/files/pos/code-pos.log | 6 | ||||
-rw-r--r-- | test/files/pos/t4716.scala | 10 |
4 files changed, 39 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 2c5ba4e874..c9cc8e46a8 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1494,7 +1494,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private def duplicateBody(tree: DefDef, source: Symbol) = { val symbol = tree.symbol val meth = addBody(tree, source) - debuglog("now typing: " + meth + " in " + symbol.owner.fullName) val d = new Duplicator d.retyped( diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index c3d22d34e0..035030bd88 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -134,6 +134,7 @@ abstract class Duplicators extends Analyzer { sym private def invalidate(tree: Tree) { + debuglog("attempting to invalidate " + tree.symbol + ", owner - " + (if (tree.symbol ne null) tree.symbol.owner else "<NULL>")) if (tree.isDef && tree.symbol != NoSymbol) { log("invalid " + tree.symbol) invalidSyms(tree.symbol) = tree @@ -148,6 +149,14 @@ abstract class Duplicators extends Analyzer { ldef.symbol = newsym log("newsym: " + newsym + " info: " + newsym.info) + case vdef @ ValDef(mods, name, _, rhs) if mods.hasFlag(Flags.LAZY) => + log("ValDef " + name + " sym.info: " + vdef.symbol.info) + invalidSyms(vdef.symbol) = vdef + val newsym = vdef.symbol.cloneSymbol(context.owner) + newsym.setInfo(fixType(vdef.symbol.info)) + vdef.symbol = newsym + log("newsym: " + newsym + " info: " + newsym.info) + case DefDef(_, name, tparams, vparamss, _, rhs) => // invalidate parameters invalidate(tparams ::: vparamss.flatten) @@ -203,7 +212,8 @@ abstract class Duplicators extends Analyzer { * namer/typer handle them, or Idents that refer to them. */ override def typed(tree: Tree, mode: Int, pt: Type): Tree = { - debuglog("typing " + tree + ": " + tree.tpe) + debuglog("typing " + tree + ": " + tree.tpe + ", " + tree.getClass) + val origtreesym = tree.symbol if (tree.hasSymbol && tree.symbol != NoSymbol && !tree.symbol.isLabel // labels cannot be retyped by the type checker as LabelDef has no ValDef/return type trees && invalidSyms.isDefinedAt(tree.symbol)) { @@ -213,7 +223,7 @@ abstract class Duplicators extends Analyzer { tree match { case ttree @ TypeTree() => - log("fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol) + // log("fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol) ttree.tpe = fixType(ttree.tpe) ttree @@ -225,7 +235,7 @@ abstract class Duplicators extends Analyzer { super.typed(tree, mode, pt) case ClassDef(_, _, _, tmpl @ Template(parents, _, stats)) => -// log("invalidating classdef " + tree.tpe) + // log("invalidating classdef " + tree.tpe) tmpl.symbol = tree.symbol.newLocalDummy(tree.pos) invalidate(stats) tree.tpe = null @@ -236,8 +246,9 @@ abstract class Duplicators extends Analyzer { ddef.tpe = null super.typed(ddef, mode, pt) - case vdef @ ValDef(_, _, tpt, rhs) => -// log("vdef fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol + " and " + invalidSyms) + case vdef @ ValDef(mods, name, tpt, rhs) => + // log("vdef fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol + " and " + invalidSyms) + if (mods.hasFlag(Flags.LAZY)) vdef.symbol.resetFlag(Flags.MUTABLE) vdef.tpt.tpe = fixType(vdef.tpt.tpe) vdef.tpe = null super.typed(vdef, mode, pt) @@ -260,6 +271,12 @@ abstract class Duplicators extends Analyzer { tree.tpe = null super.typed(tree, mode, pt) + case Ident(_) if (origtreesym ne null) && origtreesym.isLazy => + log("Ident to a lazy val " + tree + ", " + tree.symbol + " updated to " + origtreesym) + tree.symbol = updateSym(origtreesym) + tree.tpe = null + super.typed(tree, mode, pt) + case Select(th @ This(_), sel) if (oldClassOwner ne null) && (th.symbol == oldClassOwner) => // log("selection on this, no type ascription required") // we use the symbol name instead of the tree name because the symbol may have been @@ -310,7 +327,7 @@ abstract class Duplicators extends Analyzer { tree case _ => - // log("default: " + tree) + log("default: " + tree + " - " + (if (tree.symbol ne null) tree.symbol.isLazy else "")) if (tree.hasSymbol && tree.symbol != NoSymbol && (tree.symbol.owner == definitions.AnyClass)) { tree.symbol = NoSymbol // maybe we can find a more specific member in a subclass of Any (see AnyVal members, like ==) } diff --git a/test/files/pos/code-pos.log b/test/files/pos/code-pos.log new file mode 100644 index 0000000000..cdfc8f194c --- /dev/null +++ b/test/files/pos/code-pos.log @@ -0,0 +1,6 @@ +code.scala:16: error: type mismatch; + found : reflect.runtime.Mirror.Tree + required: reflect.package.mirror.Tree + val ttree = toolbox.typeCheck(tree, targetType) + ^ +one error found diff --git a/test/files/pos/t4716.scala b/test/files/pos/t4716.scala new file mode 100644 index 0000000000..ec29e8d2cb --- /dev/null +++ b/test/files/pos/t4716.scala @@ -0,0 +1,10 @@ + + + + +trait Bug2[@specialized(Int) +A] extends TraversableOnce[A] { + def ++[B >: A](that: TraversableOnce[B]) = { + lazy val it = that.toIterator + it + } +} |