diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 0acf7fac258f6..d9a17cf7a2bfd 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -133,10 +133,10 @@ proc initialized(code: ControlFlowGraph; pc: int, inc pc return pc -template isUnpackedTuple(s: PSym): bool = +template isUnpackedTuple(n: PNode): bool = ## we move out all elements of unpacked tuples, ## hence unpacked tuples themselves don't need to be destroyed - s.kind == skTemp and s.typ.kind == tyTuple + (n.kind == nkSym and n.sym.kind == skTemp and n.sym.typ.kind == tyTuple) proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) = var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">" @@ -542,7 +542,7 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode = # move the variable declaration to the top of the frame: c.addTopVar v # make sure it's destroyed at the end of the proc: - if not isUnpackedTuple(it[0].sym): + if not isUnpackedTuple(v): c.destroys.add genDestroy(c, v) if ri.kind == nkEmpty and c.inLoop > 0: ri = genDefaultCall(v.typ, c, v.info) @@ -612,13 +612,15 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode = proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = case ri.kind of nkCallKinds: - result = genSink(c, dest, ri) - result.add p(ri, c, consumed) - of nkBracketExpr: - if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym): - # unpacking of tuple: move out the elements + if isUnpackedTuple(dest): + result = newTree(nkFastAsgn, dest, p(ri, c, consumed)) + else: result = genSink(c, dest, ri) result.add p(ri, c, consumed) + of nkBracketExpr: + if isUnpackedTuple(ri[0]): + # unpacking of tuple: take over elements + result = newTree(nkFastAsgn, dest, p(ri, c, consumed)) elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c): # Rule 3: `=sink`(x, z); wasMoved(z) var snk = genSink(c, dest, ri) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index ac29d600bf860..cf8445820580b 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -60,7 +60,6 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode = var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options) temp.typ = skipTypes(value.typ, abstractInst) incl(temp.flags, sfFromGeneric) - incl(temp.flags, sfCursor) var v = newNodeI(nkVarSection, value.info) let tempAsNode = newSymNode(temp) diff --git a/tests/destructor/t12037.nim b/tests/destructor/t12037.nim index 57ebae9e4e5b7..1a7d536cc68f9 100644 --- a/tests/destructor/t12037.nim +++ b/tests/destructor/t12037.nim @@ -23,3 +23,12 @@ test() import tables var t = initTable[string, seq[ptr int]]() discard t.hasKeyOrPut("f1", @[]) + + +############################################# +### bug #12989 +proc bug(start: (seq[int], int)) = + let (s, i) = start + +let input = @[0] +bug((input, 0)) diff --git a/tests/destructor/tmisc_destructors.nim b/tests/destructor/tmisc_destructors.nim index fdcea074b2041..7fc8a61c26b77 100644 --- a/tests/destructor/tmisc_destructors.nim +++ b/tests/destructor/tmisc_destructors.nim @@ -28,7 +28,7 @@ proc test(): auto = var (a, b, _) = test() doAssert assign_counter == 0 -doAssert sink_counter == 9 # XXX this is still silly and needs to be investigated +doAssert sink_counter == 6 # bug #11510 proc main =