diff options
-rw-r--r-- | compiler/injectdestructors.nim | 15 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 11 | ||||
-rw-r--r-- | compiler/sempass2.nim | 11 | ||||
-rw-r--r-- | tests/destructor/tgcdestructors.nim | 4 |
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, " ")] |