diff options
-rw-r--r-- | compiler/dfa.nim | 5 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 21 |
2 files changed, 17 insertions, 9 deletions
diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 656e3013b..528e71b31 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -634,11 +634,14 @@ proc isAnalysableFieldAccess*(n: PNode; owner: PSym): bool = # XXX Allow closure deref operations here if we know # the owner controlled the closure allocation? result = n.kind == nkSym and n.sym.owner == owner and - owner.kind != skModule and (n.sym.kind != skParam or isSinkParam(n.sym)) + owner.kind != skModule and + (n.sym.kind != skParam or isSinkParam(n.sym)) # or n.sym.typ.kind == tyVar) proc genDef(c: var Con; n: PNode) = if n.kind == nkSym and n.sym.kind in InterestingSyms: c.code.add Instr(n: n, kind: def, sym: n.sym) + elif isAnalysableFieldAccess(n, c.owner): + c.code.add Instr(n: n, kind: def, sym: nil) proc canRaise(fn: PNode): bool = const magicsThatCanRaise = { diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 1f225aee4..4bcc38cb3 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -317,13 +317,12 @@ proc makePtrType(c: Con, baseType: PType): PType = proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode = var op = t.attachedOps[kind] - when false: - if op == nil: - # give up and find the canonical type instead: - let h = sighashes.hashType(t, {CoType, CoConsiderOwned}) - let canon = c.graph.canonTypes.getOrDefault(h) - if canon != nil: - op = canon.attachedOps[kind] + if op == nil: + # give up and find the canonical type instead: + let h = sighashes.hashType(t, {CoType, CoConsiderOwned}) + let canon = c.graph.canonTypes.getOrDefault(h) + if canon != nil: + op = canon.attachedOps[kind] if op == nil: globalError(c.graph.config, dest.info, "internal error: '" & AttachedOpToStr[kind] & @@ -535,9 +534,15 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym): # unpacking of tuple: move out the elements result = genSink(c, dest.typ, dest, ri) + result.add p(ri, c) + elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c): + # Rule 3: `=sink`(x, z); wasMoved(z) + var snk = genSink(c, dest.typ, dest, ri) + snk.add ri + result = newTree(nkStmtList, snk, genWasMoved(ri, c)) else: result = genCopy(c, dest.typ, dest, ri) - result.add p(ri, c) + result.add p(ri, c) of nkStmtListExpr: result = newNodeI(nkStmtList, ri.info) for i in 0..ri.len-2: |