diff options
author | Paul Phillips <paulp@improving.org> | 2010-04-21 05:28:07 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-04-21 05:28:07 +0000 |
commit | 0b0513fd6c57ea38fe4eea0c1818d3e65f04f593 (patch) | |
tree | 75baa6258c66e15dc5480aab0afe39f6210eed5c /src/compiler | |
parent | 4214e738c0fc29cbef7bb8c61ddfcd03816d881e (diff) | |
download | scala-0b0513fd6c57ea38fe4eea0c1818d3e65f04f593.tar.gz scala-0b0513fd6c57ea38fe4eea0c1818d3e65f04f593.tar.bz2 scala-0b0513fd6c57ea38fe4eea0c1818d3e65f04f593.zip |
Fixed bug in update method visibility which cau...
Fixed bug in update method visibility which caused x += y not to find
x's update method when defined generically. Closes #3278. Already
reviewed by odersky.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 31 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 48 |
2 files changed, 46 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 0f31a3a9f2..430967298c 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -102,17 +102,20 @@ abstract class TreeInfo { case _ => false } - def isVariableOrGetter(tree: Tree) = tree match { - case Ident(_) => - tree.symbol.isVariable - case Select(qual, _) => - tree.symbol.isVariable || - (mayBeVarGetter(tree.symbol) && - tree.symbol.owner.info.member(nme.getterToSetter(tree.symbol.name)) != NoSymbol) - case Apply(Select(qual, nme.apply), _) => - qual.tpe.member(nme.update) != NoSymbol - case _ => - false + def isVariableOrGetter(tree: Tree) = { + def sym = tree.symbol + def isVar = sym.isVariable + def isGetter = mayBeVarGetter(sym) && sym.owner.info.member(nme.getterToSetter(sym.name)) != NoSymbol + + tree match { + case Ident(_) => isVar + case Select(_, _) => isVar || isGetter + case _ => + methPart(tree) match { + case Select(qual, nme.apply) => qual.tpe.member(nme.update) != NoSymbol + case _ => false + } + } } /** Is tree a self constructor call? @@ -295,10 +298,10 @@ abstract class TreeInfo { /** The method part of an application node */ def methPart(tree: Tree): Tree = tree match { - case Apply(fn, _) => methPart(fn) - case TypeApply(fn, _) => methPart(fn) + case Apply(fn, _) => methPart(fn) + case TypeApply(fn, _) => methPart(fn) case AppliedTypeTree(fn, _) => methPart(fn) - case _ => tree + case _ => tree } def firstArgument(tree: Tree): Tree = tree match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 0274dc8871..0311d3e53c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3334,31 +3334,41 @@ trait Typers { self: Analyzer => Apply( Select(vble.duplicate, prefix) setPos fun.pos.focus, args) setPos tree.pos.makeTransparent ) setPos tree.pos + + def mkUpdate(table: Tree, indices: List[Tree]) = { + gen.evalOnceAll(table :: indices, context.owner, context.unit) { ts => + val tab = ts.head + val is = ts.tail + Apply( + Select(tab(), nme.update) setPos table.pos, + ((is map (i => i())) ::: List( + Apply( + Select( + Apply( + Select(tab(), nme.apply) setPos table.pos, + is map (i => i())) setPos qual.pos, + prefix) setPos fun.pos, + args) setPos tree.pos) + ) + ) setPos tree.pos + } + } + val tree1 = qual match { + case Ident(_) => + mkAssign(qual) + case Select(qualqual, vname) => gen.evalOnce(qualqual, context.owner, context.unit) { qq => val qq1 = qq() mkAssign(Select(qq1, vname) setPos qual.pos) } - case Apply(Select(table, nme.apply), indices) => - gen.evalOnceAll(table :: indices, context.owner, context.unit) { ts => - val tab = ts.head - val is = ts.tail - Apply( - Select(tab(), nme.update) setPos table.pos, - ((is map (i => i())) ::: List( - Apply( - Select( - Apply( - Select(tab(), nme.apply) setPos table.pos, - is map (i => i())) setPos qual.pos, - prefix) setPos fun.pos, - args) setPos tree.pos) - ) - ) setPos tree.pos - } - case Ident(_) => - mkAssign(qual) + + case Apply(fn, indices) => + treeInfo.methPart(fn) match { + case Select(table, nme.apply) => mkUpdate(table, indices) + case _ => errorTree(qual, "Unexpected tree during assignment conversion.") + } } typed1(tree1, mode, pt) /* |