summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-21 05:28:07 +0000
committerPaul Phillips <paulp@improving.org>2010-04-21 05:28:07 +0000
commit0b0513fd6c57ea38fe4eea0c1818d3e65f04f593 (patch)
tree75baa6258c66e15dc5480aab0afe39f6210eed5c /src/compiler
parent4214e738c0fc29cbef7bb8c61ddfcd03816d881e (diff)
downloadscala-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.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala48
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)
/*