summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/dfa.nim5
-rw-r--r--compiler/injectdestructors.nim21
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: