summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala29
-rw-r--r--test/files/pos/code-pos.log6
-rw-r--r--test/files/pos/t4716.scala10
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
+ }
+}