diff options
-rw-r--r-- | compiler/injectdestructors.nim | 15 | ||||
-rw-r--r-- | compiler/lowerings.nim | 5 | ||||
-rw-r--r-- | tests/arc/tmovebug.nim | 11 |
3 files changed, 22 insertions, 9 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index dc431ef38..bdd624281 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -251,7 +251,8 @@ proc canBeMoved(c: Con; t: PType): bool {.inline.} = result = t.attachedOps[attachedSink] != nil proc genSink(c: var Con; dest, ri: PNode): PNode = - if isFirstWrite(dest, c): # optimize sink call into a bitwise memcopy + if isUnpackedTuple(dest) or isFirstWrite(dest, c): + # optimize sink call into a bitwise memcopy result = newTree(nkFastAsgn, dest, ri) else: let t = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink}) @@ -592,6 +593,9 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode = # make sure it's destroyed at the end of the proc: if not isUnpackedTuple(v): c.destroys.add genDestroy(c, v) + elif c.inLoop > 0: + # unpacked tuple needs reset at every loop iteration + result.add newTree(nkFastAsgn, v, genDefaultCall(v.typ, c, v.info)) if ri.kind == nkEmpty and c.inLoop > 0: ri = genDefaultCall(v.typ, c, v.info) if ri.kind != nkEmpty: @@ -660,14 +664,11 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode = proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = case ri.kind of nkCallKinds: - if isUnpackedTuple(dest): - result = newTree(nkFastAsgn, dest, p(ri, c, consumed)) - else: - result = genSink(c, dest, p(ri, c, consumed)) + result = genSink(c, dest, p(ri, c, consumed)) of nkBracketExpr: if isUnpackedTuple(ri[0]): - # unpacking of tuple: take over elements - result = newTree(nkFastAsgn, dest, p(ri, c, consumed)) + # unpacking of tuple: take over the elements + result = genSink(c, dest, p(ri, c, consumed)) elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c) and not aliases(dest, ri): # Rule 3: `=sink`(x, z); wasMoved(z) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index b3b6cbb5c..d569c4dc9 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -74,8 +74,9 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode = result.add(v) for i in 0..<n.len-2: - if n[i].kind == nkSym: v.addVar(n[i]) - result.add newAsgnStmt(n[i], newTupleAccess(g, tempAsNode, i)) + let val = newTupleAccess(g, tempAsNode, i) + if n[i].kind == nkSym: v.addVar(n[i], val) + else: result.add newAsgnStmt(n[i], val) proc evalOnce*(g: ModuleGraph; value: PNode; owner: PSym): PNode = ## Turns (value) into (let tmp = value; tmp) so that 'value' can be re-used diff --git a/tests/arc/tmovebug.nim b/tests/arc/tmovebug.nim index 883543877..95bfb8202 100644 --- a/tests/arc/tmovebug.nim +++ b/tests/arc/tmovebug.nim @@ -86,3 +86,14 @@ proc tbug13314 = execute() tbug13314() + +#------------------------------------------------------------------------- +# bug #13368 + +import strutils +proc procStat() = + for line in @["a b", "c d", "e f"]: + let cols = line.splitWhitespace(maxSplit=1) + let x = cols[0] + let (nm, rest) = (cols[0], cols[1]) +procStat() \ No newline at end of file |