fixes #1725
This commit is contained in:
parent
b4c62d5fed
commit
8fb6865b24
2 changed files with 28 additions and 7 deletions
|
|
@ -334,7 +334,7 @@ proc addClosureParam(c: var DetectionPass; fn: PSym) =
|
||||||
incl(cp.flags, sfFromGeneric)
|
incl(cp.flags, sfFromGeneric)
|
||||||
cp.typ = t
|
cp.typ = t
|
||||||
addHiddenParam(fn, cp)
|
addHiddenParam(fn, cp)
|
||||||
elif cp.typ != t:
|
elif cp.typ != t and fn.kind != skIterator:
|
||||||
localError(fn.info, "internal error: inconsistent environment type")
|
localError(fn.info, "internal error: inconsistent environment type")
|
||||||
#echo "adding closure to ", fn.name.s
|
#echo "adding closure to ", fn.name.s
|
||||||
|
|
||||||
|
|
@ -342,7 +342,7 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
if s.kind in {skProc, skMethod, skConverter, skIterator} and s.typ != nil and s.typ.callConv == ccClosure and tfCapturesEnv notin s.typ.flags:
|
if s.kind in {skProc, skMethod, skConverter, skIterator} and s.typ != nil and s.typ.callConv == ccClosure:
|
||||||
# this handles the case that the inner proc was declared as
|
# this handles the case that the inner proc was declared as
|
||||||
# .closure but does not actually capture anything:
|
# .closure but does not actually capture anything:
|
||||||
addClosureParam(c, s)
|
addClosureParam(c, s)
|
||||||
|
|
@ -524,11 +524,16 @@ proc closureCreationForIter(iter: PNode;
|
||||||
var v = newSym(skVar, getIdent(envName), owner, iter.info)
|
var v = newSym(skVar, getIdent(envName), owner, iter.info)
|
||||||
incl(v.flags, sfShadowed)
|
incl(v.flags, sfShadowed)
|
||||||
v.typ = getHiddenParam(iter.sym).typ
|
v.typ = getHiddenParam(iter.sym).typ
|
||||||
let vnode = v.newSymNode
|
var vnode: PNode
|
||||||
|
if owner.isIterator:
|
||||||
var vs = newNodeI(nkVarSection, iter.info)
|
let it = getHiddenParam(owner)
|
||||||
addVar(vs, vnode)
|
addUniqueField(it.typ.sons[0], v)
|
||||||
result.add(vs)
|
vnode = indirectAccess(newSymNode(it), v, v.info)
|
||||||
|
else:
|
||||||
|
vnode = v.newSymNode
|
||||||
|
var vs = newNodeI(nkVarSection, iter.info)
|
||||||
|
addVar(vs, vnode)
|
||||||
|
result.add(vs)
|
||||||
result.add(newCall(getSysSym"internalNew", vnode))
|
result.add(newCall(getSysSym"internalNew", vnode))
|
||||||
|
|
||||||
let upField = lookupInRecord(v.typ.lastSon.n, getIdent(upName))
|
let upField = lookupInRecord(v.typ.lastSon.n, getIdent(upName))
|
||||||
|
|
|
||||||
16
tests/iter/tnested_closure_iter.nim
Normal file
16
tests/iter/tnested_closure_iter.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
discard """
|
||||||
|
output: '''0
|
||||||
|
1
|
||||||
|
2'''
|
||||||
|
"""
|
||||||
|
# bug #1725
|
||||||
|
iterator factory(): int {.closure.} =
|
||||||
|
iterator bar(): int {.closure.} =
|
||||||
|
yield 0
|
||||||
|
yield 1
|
||||||
|
yield 2
|
||||||
|
|
||||||
|
for x in bar(): yield x
|
||||||
|
|
||||||
|
for x in factory():
|
||||||
|
echo x
|
||||||
Loading…
Add table
Add a link
Reference in a new issue