diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-06-20 07:40:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-20 07:40:45 +0200 |
commit | c65a5d754b791dfad72420fa27cfe933c6a7782c (patch) | |
tree | b146a231876a8351ba586912ee867c121ac6218c /compiler/injectdestructors.nim | |
parent | 1a074fffa421b6cab0357e86d1011cc39eafcc61 (diff) | |
download | Nim-c65a5d754b791dfad72420fa27cfe933c6a7782c.tar.gz |
[bugfix] owned closures (#11544)
Diffstat (limited to 'compiler/injectdestructors.nim')
-rw-r--r-- | compiler/injectdestructors.nim | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index b1a5e63c0..b9fa1e3ae 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -165,12 +165,12 @@ proc isLastRead(location: PNode; c: var Con; pc, comesFrom: int): int = while pc < c.g.len: case c.g[pc].kind of def: - if instrTargets(c.g[pc], location): + if defInstrTargets(c.g[pc], location): # the path lead to a redefinition of 's' --> abandon it. return high(int) inc pc of use: - if instrTargets(c.g[pc], location): + if useInstrTargets(c.g[pc], location): c.otherRead = c.g[pc].n return -1 inc pc @@ -349,8 +349,10 @@ proc genSink(c: Con; t: PType; dest, ri: PNode): PNode = # we generate a fast assignment in this case: result = newTree(nkFastAsgn, dest) -proc genCopy(c: Con; t: PType; dest, ri: PNode): PNode = +proc genCopy(c: var Con; t: PType; dest, ri: PNode): PNode = if tfHasOwned in t.flags: + # try to improve the error message here: + if c.otherRead == nil: discard isLastRead(ri, c) checkForErrorPragma(c, t, ri, "=") let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) result = genOp(c, t, attachedAsgn, dest, ri) @@ -410,7 +412,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode = add(v, vpart) result.add v - result.add genWasMoved(n, c) + result.add genWasMoved(skipConv(n), c) result.add tempAsNode proc sinkParamIsLastReadCheck(c: var Con, s: PNode) = @@ -611,7 +613,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = of nkTupleConstr, nkClosure: result = genSink(c, dest.typ, dest, ri) let ri2 = copyTree(ri) - for i in 0..<ri.len: + for i in ord(ri.kind == nkClosure)..<ri.len: # everything that is passed to an tuple constructor is consumed, # so these all act like 'sink' parameters: if ri[i].kind == nkExprColonExpr: @@ -757,7 +759,7 @@ proc p(n: PNode; c: var Con): PNode = else: result = n of nkAsgn, nkFastAsgn: - if hasDestructor(n[0].typ) and n[1].kind notin {nkProcDef, nkDo, nkLambda, nkClosure}: + if hasDestructor(n[0].typ) and n[1].kind notin {nkProcDef, nkDo, nkLambda}: result = moveOrCopy(n[0], n[1], c) else: result = copyNode(n) |