summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/injectdestructors.nim15
-rw-r--r--compiler/liftdestructors.nim11
-rw-r--r--compiler/sempass2.nim11
-rw-r--r--tests/destructor/tgcdestructors.nim4
4 files changed, 29 insertions, 12 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index eb8f86e8e..f1bda866b 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -660,13 +660,13 @@ proc p(n: PNode; c: var Con): PNode =
 
     for i in 0..<n.len:
       let it = n[i]
-      let L = it.len-1
-      let ri = it[L]
+      let L = it.len
+      let ri = it[L-1]
       if it.kind == nkVarTuple and hasDestructor(ri.typ):
         let x = lowerTupleUnpacking(c.graph, it, c.owner)
         result.add p(x, c)
       elif it.kind == nkIdentDefs and hasDestructor(it[0].typ) and not isCursor(it[0]):
-        for j in 0..L-2:
+        for j in 0..L-3:
           let v = it[j]
           doAssert v.kind == nkSym
           # move the variable declaration to the top of the frame:
@@ -681,7 +681,7 @@ proc p(n: PNode; c: var Con): PNode =
         # keep it, but transform 'ri':
         var varSection = copyNode(n)
         var itCopy = copyNode(it)
-        for j in 0..L-1:
+        for j in 0..L-2:
           itCopy.add it[j]
         itCopy.add p(ri, c)
         varSection.add itCopy
@@ -722,8 +722,9 @@ proc p(n: PNode; c: var Con): PNode =
     recurse(n, result)
 
 proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
-  when false: # defined(nimDebugDestroys):
-    echo "injecting into ", n
+  when defined(nimDebugDestroys):
+    if owner.name.s == "main":
+      echo "injecting into ", n
   if sfGeneratedOp in owner.flags: return n
   var c: Con
   c.owner = owner
@@ -758,7 +759,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
     result.add body
 
   when defined(nimDebugDestroys):
-    if true:
+    if owner.name.s == "main":
       echo "------------------------------------"
       echo owner.name.s, " transformed to: "
       echo result
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index 1cac61094..dba09b4ef 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -266,7 +266,7 @@ proc newSeqCall(g: ModuleGraph; x, y: PNode): PNode =
 proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode =
   let lenCall = genBuiltin(g, mLengthStr, "len", y)
   lenCall.typ = getSysType(g, x.info, tyInt)
-  result = genBuiltin(g, mSetLengthStr, "setLen", genAddr(g, x))
+  result = genBuiltin(g, mSetLengthStr, "setLen", x) # genAddr(g, x))
   result.add lenCall
 
 proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
@@ -274,7 +274,7 @@ proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
   lenCall.typ = getSysType(c.graph, x.info, tyInt)
   var op = getSysMagic(c.graph, x.info, "setLen", mSetLengthSeq)
   op = c.c.instTypeBoundOp(c.c, op, t, c.info, attachedAsgn, 1)
-  result = newTree(nkCall, newSymNode(op, x.info), genAddr(c.graph, x), lenCall)
+  result = newTree(nkCall, newSymNode(op, x.info), x, lenCall)
 
 proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   let i = declareCounter(c, body, firstOrd(c.graph.config, t))
@@ -606,6 +606,8 @@ template inst(field, t) =
     if field.ast != nil:
       patchBody(c, field.ast, info)
 
+proc isTrival(s: PSym): bool {.inline.} = s == nil or s.ast[bodyPos].len == 0
+
 proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
   ## In the semantic pass this is called in strategic places
   ## to ensure we lift assignment, destructors and moves properly.
@@ -647,3 +649,8 @@ proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
     orig.destructor = canon.destructor
     orig.assignment = canon.assignment
     orig.sink = canon.sink
+
+  #if not isTrival(orig.destructor):
+    #or not isTrival(orig.assignment) or
+    # not isTrival(orig.sink):
+  #  orig.flags.incl tfHasAsgn
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index a07053643..f09a45ce8 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -821,7 +821,16 @@ proc track(tracked: PEffects, n: PNode) =
   of nkForStmt, nkParForStmt:
     # we are very conservative here and assume the loop is never executed:
     let oldState = tracked.init.len
-    for i in 0 ..< len(n):
+    for i in 0 .. len(n)-3:
+      let it = n[i]
+      track(tracked, it)
+      if tracked.owner.kind != skMacro:
+        if it.kind == nkVarTuple:
+          for x in it:
+            createTypeBoundOps(tracked.c, x.typ, x.info)
+        else:
+          createTypeBoundOps(tracked.c, it.typ, it.info)
+    for i in len(n)-2..len(n)-1:
       track(tracked, n.sons[i])
     setLen(tracked.init, oldState)
   of nkObjConstr:
diff --git a/tests/destructor/tgcdestructors.nim b/tests/destructor/tgcdestructors.nim
index 31631ac80..4b7f4ccb4 100644
--- a/tests/destructor/tgcdestructors.nim
+++ b/tests/destructor/tgcdestructors.nim
@@ -3,7 +3,7 @@ discard """
   output: '''hi
 ho
 ha
-1 1'''
+7 1'''
 """
 
 import allocators
@@ -75,7 +75,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
       break
     i = j
 
-when false:
+when true:
   let input = "$test{}  $this is ${an{  example}}  "
   let expected = @[(ikVar, "test"), (ikStr, "{}  "), (ikVar, "this"),
                   (ikStr, " is "), (ikExpr, "an{  example}"), (ikStr, "  ")]