summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-09-27 17:02:50 +0000
committerAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-09-27 17:02:50 +0000
commit148f4ef194180e03afdeba563aa822e7fb459c75 (patch)
tree5c36c73595d83d50f1a9474d5e30d763836c6dc7 /src
parent7dfb214aaae80675d5c0c95d1faaf9d5fd6da5be (diff)
downloadscala-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.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala29
2 files changed, 23 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 ==)
}