summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/lowerings.nim26
-rw-r--r--compiler/semexprs.nim8
2 files changed, 34 insertions, 0 deletions
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index 647ea59d6..20800b809 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -63,6 +63,32 @@ proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode =
     if n.sons[i].kind == nkSym: v.addVar(n.sons[i])
     result.add newAsgnStmt(n.sons[i], newTupleAccess(tempAsNode, i))
 
+proc newTupleAccessRaw*(tup: PNode, i: int): PNode =
+  result = newNodeI(nkBracketExpr, tup.info)
+  addSon(result, copyTree(tup))
+  var lit = newNodeI(nkIntLit, tup.info)
+  lit.intVal = i
+  addSon(result, lit)
+
+proc lowerTupleUnpackingForAsgn*(n: PNode; owner: PSym): PNode =
+  let value = n.lastSon
+  result = newNodeI(nkStmtList, n.info)
+
+  var temp = newSym(skTemp, getIdent(genPrefix), owner, value.info)
+  var v = newNodeI(nkLetSection, value.info)
+  let tempAsNode = newIdentNode(getIdent(genPrefix & $temp.id), value.info)
+
+  var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
+  vpart.sons[0] = tempAsNode
+  vpart.sons[1] = ast.emptyNode
+  vpart.sons[2] = value
+  addSon(v, vpart)
+  result.add(v)
+
+  let lhs = n.sons[0]
+  for i in 0 .. lhs.len-1:
+    result.add newAsgnStmt(lhs.sons[i], newTupleAccessRaw(tempAsNode, i))
+
 proc lowerSwap*(n: PNode; owner: PSym): PNode =
   result = newNodeI(nkStmtList, n.info)
   # note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index bb3ec9df0..d6f6e3a2c 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1282,6 +1282,14 @@ proc semAsgn(c: PContext, n: PNode): PNode =
     result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=")
     add(result, n[1])
     return semExprNoType(c, result)
+  of nkPar:
+    if a.len >= 2:
+      # unfortunately we need to rewrite ``(x, y) = foo()`` already here so
+      # that overloading of the assignment operator still works. Usually we
+      # prefer to do these rewritings in transf.nim:
+      return semStmt(c, lowerTupleUnpackingForAsgn(n, c.p.owner))
+    else:
+      a = semExprWithType(c, a, {efLValue})
   else:
     a = semExprWithType(c, a, {efLValue})
   n.sons[0] = a
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227