ARC: closure inside object constructor now works
This commit is contained in:
parent
bcab3ed06c
commit
f22d3c75aa
3 changed files with 30 additions and 4 deletions
|
|
@ -382,9 +382,16 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
# sink parameter (bug #11524). Note that the string implementation is
|
# sink parameter (bug #11524). Note that the string implementation is
|
||||||
# different and can deal with 'const string sunk into var'.
|
# different and can deal with 'const string sunk into var'.
|
||||||
result = passCopyToSink(arg, c)
|
result = passCopyToSink(arg, c)
|
||||||
elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure} + nkLiterals:
|
elif arg.kind in nkLiterals:
|
||||||
|
result = arg # literal to sink parameter: nothing to do
|
||||||
|
elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure}:
|
||||||
# object construction to sink parameter: nothing to do
|
# object construction to sink parameter: nothing to do
|
||||||
result = arg
|
result = copyTree(arg)
|
||||||
|
for i in ord(arg.kind in {nkObjConstr, nkClosure})..<arg.len:
|
||||||
|
if arg[i].kind == nkExprColonExpr:
|
||||||
|
result[i][1] = pArg(arg[i][1], c, isSink = true)
|
||||||
|
else:
|
||||||
|
result[i] = pArg(arg[i], c, isSink = true)
|
||||||
elif arg.kind == nkSym and isSinkParam(arg.sym):
|
elif arg.kind == nkSym and isSinkParam(arg.sym):
|
||||||
# Sinked params can be consumed only once. We need to reset the memory
|
# Sinked params can be consumed only once. We need to reset the memory
|
||||||
# to disable the destructor which we have not elided
|
# to disable the destructor which we have not elided
|
||||||
|
|
@ -396,6 +403,12 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
result = destructiveMoveVar(arg, c)
|
result = destructiveMoveVar(arg, c)
|
||||||
elif arg.kind in {nkStmtListExpr, nkBlockExpr, nkBlockStmt, nkIfExpr, nkIfStmt, nkCaseStmt}:
|
elif arg.kind in {nkStmtListExpr, nkBlockExpr, nkBlockStmt, nkIfExpr, nkIfStmt, nkCaseStmt}:
|
||||||
handleNested(arg): pArg(node, c, isSink)
|
handleNested(arg): pArg(node, c, isSink)
|
||||||
|
elif arg.kind in {nkHiddenSubConv, nkHiddenStdConv, nkConv}:
|
||||||
|
result = copyTree(arg)
|
||||||
|
result[1] = pArg(arg[1], c, isSink = true)
|
||||||
|
elif arg.kind in {nkObjDownConv, nkObjUpConv}:
|
||||||
|
result = copyTree(arg)
|
||||||
|
result[0] = pArg(arg[0], c, isSink = true)
|
||||||
else:
|
else:
|
||||||
# an object that is not temporary but passed to a 'sink' parameter
|
# an object that is not temporary but passed to a 'sink' parameter
|
||||||
# results in a copy.
|
# results in a copy.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''Success
|
output: '''
|
||||||
|
@[1, 2, 3]
|
||||||
|
Success
|
||||||
@["a", "b", "c"]
|
@["a", "b", "c"]
|
||||||
0'''
|
0'''
|
||||||
cmd: '''nim c --gc:destructors $file'''
|
cmd: '''nim c --gc:destructors $file'''
|
||||||
|
|
@ -32,7 +34,18 @@ proc tsimpleClosureIterator =
|
||||||
for it in foobar(myc):
|
for it in foobar(myc):
|
||||||
echo it
|
echo it
|
||||||
|
|
||||||
|
type
|
||||||
|
LazyList = ref object
|
||||||
|
c: proc() {.closure.}
|
||||||
|
|
||||||
|
proc tlazyList =
|
||||||
|
let dep = @[1, 2, 3]
|
||||||
|
var x = LazyList(c: proc () = echo(dep))
|
||||||
|
x.c()
|
||||||
|
|
||||||
let startMem = getOccupiedMem()
|
let startMem = getOccupiedMem()
|
||||||
|
tlazyList()
|
||||||
|
|
||||||
mkManyLeaks()
|
mkManyLeaks()
|
||||||
tsimpleClosureIterator()
|
tsimpleClosureIterator()
|
||||||
echo getOccupiedMem() - startMem
|
echo getOccupiedMem() - startMem
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
cmd: '''nim c --newruntime $file'''
|
cmd: '''nim c --newruntime $file'''
|
||||||
errormsg: "'=' is not available for type <owned Widget>; requires a copy because it's not the last read of ':envAlt.b1()'; another read is done here: tuse_ownedref_after_move.nim(53, 4)"
|
errormsg: "'=' is not available for type <owned Button>; requires a copy because it's not the last read of ':envAlt.b1'; another read is done here: tuse_ownedref_after_move.nim(53, 4)"
|
||||||
line: 49
|
line: 49
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue