fixes #1803
This commit is contained in:
parent
8cb31d86b6
commit
27141f6016
2 changed files with 53 additions and 6 deletions
|
|
@ -187,6 +187,7 @@ proc addHiddenParam(routine: PSym, param: PSym) =
|
|||
param.position = params.len-1
|
||||
addSon(params, newSymNode(param))
|
||||
incl(routine.typ.flags, tfCapturesEnv)
|
||||
assert sfFromGeneric in param.flags
|
||||
#echo "produced environment: ", param.id, " for ", routine.name.s
|
||||
|
||||
proc getHiddenParam(routine: PSym): PSym =
|
||||
|
|
@ -194,12 +195,14 @@ proc getHiddenParam(routine: PSym): PSym =
|
|||
let hidden = lastSon(params)
|
||||
internalAssert hidden.kind == nkSym and hidden.sym.kind == skParam
|
||||
result = hidden.sym
|
||||
assert sfFromGeneric in result.flags
|
||||
|
||||
proc getEnvParam(routine: PSym): PSym =
|
||||
let params = routine.ast.sons[paramsPos]
|
||||
let hidden = lastSon(params)
|
||||
if hidden.kind == nkSym and hidden.sym.name.s == paramName:
|
||||
result = hidden.sym
|
||||
assert sfFromGeneric in result.flags
|
||||
|
||||
proc initIter(iter: PSym): TIter =
|
||||
result.fn = iter
|
||||
|
|
@ -716,15 +719,17 @@ proc outerProcSons(o: POuterContext, n: PNode, it: TIter) =
|
|||
let x = transformOuterProc(o, n.sons[i], it)
|
||||
if x != nil: n.sons[i] = x
|
||||
|
||||
proc liftIterSym*(n: PNode): PNode =
|
||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||
proc liftIterSym(n: PNode): PNode =
|
||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||
let iter = n.sym
|
||||
assert iter.kind == skClosureIterator
|
||||
|
||||
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
|
||||
|
||||
var env = copySym(getHiddenParam(iter))
|
||||
env.kind = skLet
|
||||
let hp = getHiddenParam(iter)
|
||||
let env = newSym(skLet, iter.name, iter.owner, iter.info)
|
||||
env.typ = hp.typ
|
||||
env.flags = hp.flags
|
||||
var v = newNodeI(nkVarSection, n.info)
|
||||
addVar(v, newSymNode(env))
|
||||
result.add(v)
|
||||
|
|
@ -853,7 +858,6 @@ proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode =
|
|||
addUniqueField(it.obj, local)
|
||||
return indirectAccess(newSymNode(it.closureParam), local, n.info)
|
||||
|
||||
var closure = PEnv(idTableGet(o.lambdasToEnv, local))
|
||||
if local.kind == skClosureIterator:
|
||||
# consider: [i1, i2, i1] Since we merged the iterator's closure
|
||||
# with the captured owning variables, we need to generate the
|
||||
|
|
@ -861,13 +865,25 @@ proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode =
|
|||
if local == o.fn or local == it.fn:
|
||||
message(n.info, errRecursiveDependencyX, local.name.s)
|
||||
# XXX why doesn't this work?
|
||||
var closure = PEnv(idTableGet(o.lambdasToEnv, local))
|
||||
if closure.isNil:
|
||||
return liftIterSym(n)
|
||||
else:
|
||||
let createdVar = generateIterClosureCreation(o, closure,
|
||||
closure.attachedNode)
|
||||
let lpt = getHiddenParam(local).typ
|
||||
if lpt != createdVar.typ:
|
||||
assert lpt.kind == tyRef and createdVar.typ.kind == tyRef
|
||||
# fix bug 'tshallowcopy_closures' but report if this gets any weirder:
|
||||
if createdVar.typ.sons[0].len == 1 and lpt.sons[0].len >= 1:
|
||||
createdVar.typ = lpt
|
||||
if createdVar.kind == nkSym: createdVar.sym.typ = lpt
|
||||
closure.obj = lpt.sons[0]
|
||||
else:
|
||||
internalError(n.info, "environment computation failed")
|
||||
return makeClosure(local, createdVar, n.info)
|
||||
|
||||
var closure = PEnv(idTableGet(o.lambdasToEnv, local))
|
||||
if closure != nil:
|
||||
# we need to replace the lambda with '(lambda, env)':
|
||||
let a = closure.createdVar
|
||||
|
|
@ -935,7 +951,7 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode =
|
|||
# ignore forward declaration:
|
||||
result = body
|
||||
else:
|
||||
#if fn.name.s == "cbOuter":
|
||||
#if fn.name.s == "sort":
|
||||
# echo rendertree(fn.ast, {renderIds})
|
||||
var o = newOuterContext(fn)
|
||||
let ex = closureCreationPoint(body)
|
||||
|
|
|
|||
31
tests/iter/tshallowcopy_closures.nim
Normal file
31
tests/iter/tshallowcopy_closures.nim
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
discard """
|
||||
ccodecheck: "!@('{' \\s* 'NI HEX3Astate;' \\s* '}')"
|
||||
"""
|
||||
|
||||
# bug #1803
|
||||
type TaskFn = iterator (): float
|
||||
|
||||
iterator a1(): float {.closure.} =
|
||||
var k = 10
|
||||
while k > 0:
|
||||
echo "a1 ", k
|
||||
dec k
|
||||
yield 1.0
|
||||
|
||||
|
||||
iterator a2(): float {.closure.} =
|
||||
var k = 15
|
||||
while k > 0:
|
||||
echo "a2 ", k
|
||||
dec k
|
||||
yield 2.0
|
||||
|
||||
var
|
||||
x = a1
|
||||
y = a2
|
||||
z: TaskFn
|
||||
|
||||
discard x()
|
||||
z = x #shallowCopy(z, x)
|
||||
z = y #shallowCopy(z, y)
|
||||
discard x()
|
||||
Loading…
Add table
Add a link
Reference in a new issue