Skip to content

Commit 38be47a

Browse files
authored
Merge pull request scala#5770 from som-snytt/issue/6714
SI-6714 Update assignment preserves apply args
2 parents 6e7c960 + 6457382 commit 38be47a

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4759,7 +4759,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
47594759
Select(vble.duplicate, prefix) setPos fun.pos.focus, args) setPos tree.pos.makeTransparent
47604760
) setPos tree.pos
47614761

4762-
def mkUpdate(table: Tree, indices: List[Tree]) =
4762+
def mkUpdate(table: Tree, indices: List[Tree], argss: List[List[Tree]]) =
47634763
gen.evalOnceAll(table :: indices, context.owner, context.unit) {
47644764
case tab :: is =>
47654765
def mkCall(name: Name, extraArgs: Tree*) = (
@@ -4768,9 +4768,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
47684768
is.map(i => i()) ++ extraArgs
47694769
) setPos tree.pos
47704770
)
4771+
def mkApplies(core: Tree) = argss.foldLeft(core)((x, args) => Apply(x, args))
47714772
mkCall(
47724773
nme.update,
4773-
Apply(Select(mkCall(nme.apply), prefix) setPos fun.pos, args) setPos tree.pos
4774+
Apply(Select(mkApplies(mkCall(nme.apply)), prefix) setPos fun.pos, args) setPos tree.pos
47744775
)
47754776
case _ => EmptyTree
47764777
}
@@ -4785,9 +4786,18 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
47854786
mkAssign(Select(qq1, vname) setPos qual.pos)
47864787
}
47874788

4789+
case Apply(fn, extra) if qual.isInstanceOf[ApplyToImplicitArgs] =>
4790+
fn match {
4791+
case treeInfo.Applied(Select(table, nme.apply), _, indices :: Nil) =>
4792+
// table(indices)(implicits)
4793+
mkUpdate(table, indices, extra :: Nil)
4794+
case _ => UnexpectedTreeAssignmentConversionError(qual)
4795+
}
4796+
47884797
case Apply(fn, indices) =>
47894798
fn match {
4790-
case treeInfo.Applied(Select(table, nme.apply), _, _) => mkUpdate(table, indices)
4799+
case treeInfo.Applied(Select(table, nme.apply), _, Nil) =>
4800+
mkUpdate(table, indices, Nil)
47914801
case _ => UnexpectedTreeAssignmentConversionError(qual)
47924802
}
47934803
}

test/files/neg/t6714.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
t6714.scala:19: error: Unexpected tree during assignment conversion.
2+
a(1)(9000) += 20 // Not OK
3+
^
4+
t6714.scala:21: error: Unexpected tree during assignment conversion.
5+
b(1)(5) += 20 // Not OK
6+
^
7+
two errors found

test/files/neg/t6714.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
case class A(a: Int, index: Int) {
3+
def apply(i: Int)(implicit ev: Int): A = new A(ev, i)
4+
def update(i: Int, value: Int): A = if (i == index) A(i, value) else A(i, 0)
5+
def +(j: Int) = a + j
6+
}
7+
8+
case class B(a: Int, index: Int) {
9+
def apply(i: Int)(j: Int)(implicit ev: Int): B = new B(j + ev, i)
10+
def update(i: Int, value: Int): B = if (i == index) B(i, value) else B(i, 0)
11+
def +(j: Int) = a + j
12+
}
13+
14+
object Test extends App {
15+
implicit def ev: Int = 8000
16+
val a = A(5, 1)
17+
a(1) = 10 // OK
18+
a(1) += 20 // OK
19+
a(1)(9000) += 20 // Not OK
20+
val b = B(5, 1)
21+
b(1)(5) += 20 // Not OK
22+
}

test/files/run/t6714.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
case class A(a: Int, index: Int) {
3+
def apply(i: Int)(implicit ev: Int): A = new A(ev, i)
4+
def update(i: Int, value: Int): A = if (i == index) A(i, value) else A(i, 0)
5+
def +(j: Int) = a + j
6+
}
7+
8+
object Test extends App {
9+
def checkA(x: A, y: Int, z: Int) = assert(x == A(y, z))
10+
implicit def ev: Int = 8000
11+
val a = A(5, 1)
12+
checkA(a(1) = 10, 1, 10)
13+
checkA(a(1) += 20, 1, 8020)
14+
}
15+
16+
/*
17+
A(1,10)
18+
A(1,8020) // was A(8000,0)
19+
*/

0 commit comments

Comments
 (0)