From ee551a1c56fdc508ac7323e0a7b14bc5b41e1bc9 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 19 May 2026 20:06:37 +0800 Subject: [PATCH] fixes #25725; environment misses: s with iterator --- compiler/transf.nim | 58 ++++++++++++++++++++++++++++++++----- tests/iter/titer_issues.nim | 22 +++++++++++++- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/compiler/transf.nim b/compiler/transf.nim index 3059d8fe6b..a320fe3807 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -90,11 +90,20 @@ proc getCurrOwner(c: PTransf): PSym = if c.transCon != nil: result = c.transCon.owner else: result = c.module +proc freshOwnedSym(c: PTransf; s, owner: PSym): PNode = + # We need to copy the symbol here because we might need to change its owner and + # we don't want to mess with the original symbol which might be used in other places. + # This can happen for example for iterators which are transformed multiple times when + # they are used in different contexts. + var fresh = copySym(s, c.idgen) + incl(fresh.flagsImpl, sfFromGeneric) + setOwner(fresh, owner) + result = newSymNode(fresh) + proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode = let r = newSym(skTemp, getIdent(c.graph.cache, genPrefix), c.idgen, getCurrOwner(c), info) r.typ = typ #skipTypes(typ, {tyGenericInst, tyAlias, tySink}) incl(r.flagsImpl, sfFromGeneric) - let owner = getCurrOwner(c) result = newSymNode(r) proc transform(c: PTransf, n: PNode, noConstFold = false): PNode @@ -185,11 +194,39 @@ proc transformSym(c: PTransf, n: PNode): PNode = result = transformSymAux(c, n) proc freshVar(c: PTransf; v: PSym): PNode = - let owner = getCurrOwner(c) - var newVar = copySym(v, c.idgen) - incl(newVar.flagsImpl, sfFromGeneric) - setOwner(newVar, owner) - result = newSymNode(newVar) + result = freshOwnedSym(c, v, getCurrOwner(c)) + +proc introduceNewRoutineHeaderSyms(c: PTransf; n: PNode; oldOwner, newOwner: PSym) = + # We need to introduce new symbols for the parameters and result of a routine when + # we copy it for inlining or closure generation. + # Otherwise, we would have multiple nodes referring to the same parameter symbols which + # can lead to problems when we need to change the owner of these symbols. + case n.kind + of nkSym: + if n.sym.owner == oldOwner: + c.transCon.mapping[n.sym.itemId] = freshOwnedSym(c, n.sym, newOwner) + of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: + discard + else: + for i in 0.. 0: + newProc.typ.n.add copyNode(oldProc.typ.n[0]) + for i in 1..