diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index b9fa1e3aeb..dd71e2dfb0 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -450,6 +450,25 @@ proc passCopyToSink(n: PNode; c: var Con): PNode = result.add newTree(nkAsgn, tmp, p(n, c)) result.add tmp +proc isDangerousSeq(t: PType): bool {.inline.} = + let t = t.skipTypes(abstractInst) + result = t.kind == tySequence and tfHasOwned notin t.sons[0].flags + +proc containsConstSeq(n: PNode): bool = + if n.kind == nkBracket and n.len > 0 and n.typ != nil and isDangerousSeq(n.typ): + return true + result = false + case n.kind + of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv: + result = containsConstSeq(n[1]) + of nkObjConstr, nkClosure: + for i in 1 ..< n.len: + if containsConstSeq(n[i]): return true + of nkCurly, nkBracket, nkPar, nkTupleConstr: + for i in 0 ..< n.len: + if containsConstSeq(n[i]): return true + else: discard + proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = template pArgIfTyped(argPart: PNode): PNode = # typ is nil if we are in if/case expr branch with noreturn @@ -466,7 +485,12 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = result.add arg[0] for i in 1.. 0 and isDangerousSeq(ri.typ): + result = genCopy(c, dest.typ, dest, ri) + else: + result = genSink(c, dest.typ, dest, ri) let ri2 = copyTree(ri) for i in 0..