mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-06 07:38:24 +00:00
Nested transformBody/liftLambdas passes used a fresh DetectionPass, so getEnvTypeForOwner could allocate a duplicate PType for the same owner while :envP already referenced the inner pass type. When addClosureParam saw cp.typ != t, it errored. If both types are env objects for the same routine owner, reuse cp.typ and sync ownerToType. Adds regression test tests/iter/t21242_nested_closure_in_iter.nim.
This commit is contained in:
@@ -408,6 +408,12 @@ Consider:
|
||||
proc isTypeOf(n: PNode): bool =
|
||||
n.kind == nkSym and n.sym.magic in {mTypeOf, mType}
|
||||
|
||||
proc isEnvTypeForRoutine(envTyp: PType; routine: PSym): bool =
|
||||
## True if `envTyp` is (maybe wrapped) env object type owned by `routine`, as
|
||||
## created by `getEnvTypeForOwner` / `createEnvObj`.
|
||||
let obj = envTyp.skipTypes({tyOwned, tyRef, tyPtr})
|
||||
result = obj.kind == tyObject and obj.owner.id == routine.id
|
||||
|
||||
proc addClosureParam(c: var DetectionPass; fn: PSym; info: TLineInfo) =
|
||||
var cp = getEnvParam(fn)
|
||||
let owner = if fn.kind == skIterator: fn else: fn.skipGenericOwner
|
||||
@@ -418,7 +424,13 @@ proc addClosureParam(c: var DetectionPass; fn: PSym; info: TLineInfo) =
|
||||
cp.typ = t
|
||||
addHiddenParam(fn, cp)
|
||||
elif cp.typ != t and fn.kind != skIterator:
|
||||
localError(c.graph.config, fn.info, "internal error: inconsistent environment type")
|
||||
# Nested `liftLambdas` uses a fresh `DetectionPass`, so `getEnvTypeForOwner`
|
||||
# can allocate another PType for the same logical env; the hidden param from
|
||||
# the inner pass is authoritative (bug #21242).
|
||||
if isEnvTypeForRoutine(cp.typ, owner) and isEnvTypeForRoutine(t, owner):
|
||||
c.ownerToType[owner.id] = cp.typ
|
||||
else:
|
||||
localError(c.graph.config, fn.info, "internal error: inconsistent environment type")
|
||||
#echo "adding closure to ", fn.name.s
|
||||
|
||||
proc iterEnvHasUpField(g: ModuleGraph, iter: PSym): bool =
|
||||
|
||||
23
tests/iter/t21242_nested_closure_in_iter.nim
Normal file
23
tests/iter/t21242_nested_closure_in_iter.nim
Normal file
@@ -0,0 +1,23 @@
|
||||
# Regression test for bug #21242
|
||||
discard """
|
||||
action: compile
|
||||
"""
|
||||
|
||||
iterator iterSome(): int =
|
||||
proc inner1() =
|
||||
let something = 6
|
||||
proc inner2() =
|
||||
let othersomething = something
|
||||
inner2()
|
||||
|
||||
for n in 0 .. 10:
|
||||
inner1()
|
||||
yield n
|
||||
|
||||
proc test() =
|
||||
proc test1() =
|
||||
for v in iterSome():
|
||||
discard
|
||||
test1()
|
||||
|
||||
test()
|
||||
Reference in New Issue
Block a user