diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 7e0f54b12e..835cbf0ca7 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -1451,6 +1451,14 @@ proc detectCapturedVars(c: var Ctx, n: PNode, stateIdx: int) = detectCapturedVars(c, n[0][1], stateIdx) else: detectCapturedVars(c, n[0], stateIdx) + of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, + nkTemplateDef, nkTypeSection, nkProcDef, nkMethodDef, + nkConverterDef, nkMacroDef, nkFuncDef, nkCommentStmt, + nkTypeOfExpr, nkMixinStmt, nkBindStmt: + discard + of nkLambdaKinds, nkIteratorDef: + if n.typ != nil: + detectCapturedVars(c, n[namePos], stateIdx) else: for i in 0 ..< n.safeLen: detectCapturedVars(c, n[i], stateIdx) @@ -1481,6 +1489,12 @@ proc liftLocals(c: var Ctx, n: PNode): PNode = n[0][1] = liftLocals(c, n[0][1]) else: n[0] = liftLocals(c, n[0]) + of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, + nkTemplateDef, nkTypeSection, nkProcDef, nkMethodDef, + nkConverterDef, nkMacroDef, nkFuncDef, nkCommentStmt, + nkTypeOfExpr, nkMixinStmt, nkBindStmt, + nkLambdaKinds, nkIteratorDef: + discard else: for i in 0 ..< n.safeLen: n[i] = liftLocals(c, n[i]) diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 640bb4b2f8..c8c5acf974 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -199,7 +199,7 @@ proc interestingVar(s: PSym): bool {.inline.} = proc illegalCapture(s: PSym): bool {.inline.} = result = classifyViewType(s.typ) != noView or s.kind == skResult -proc isInnerProc(s: PSym): bool = +proc isInnerProc*(s: PSym): bool = if s.kind in {skProc, skFunc, skMethod, skConverter, skIterator} and s.magic == mNone: result = s.skipGenericOwner.kind in routineKinds else: diff --git a/tests/iter/t24863.nim b/tests/iter/t24863.nim new file mode 100644 index 0000000000..96ddbcef7c --- /dev/null +++ b/tests/iter/t24863.nim @@ -0,0 +1,30 @@ +# issue #24863 + +type M = object + p: iterator(): M {.gcsafe.} + +template h(f: M): int = + yield f + 456 + +proc s(): M = + iterator g(): M {.closure.} = discard + let v = M(p: g) + doAssert(not isNil(v.p)) + discard v.p() + v + +proc c(): M = + iterator b(): M {.closure.} = + let r = h(s()) + doAssert r == 456 + proc n(): M = + iterator y(): M {.closure.} = + let _ = r + let _ = y + let _ = proc () = discard n() + let j = M(p: b) + doAssert(not isNil(j.p)) + discard j.p() + +let _ = c() diff --git a/tests/iter/tnestedclosures.nim b/tests/iter/tnestedclosures.nim index e23fa1355f..f2dc7a51d4 100644 --- a/tests/iter/tnestedclosures.nim +++ b/tests/iter/tnestedclosures.nim @@ -25,6 +25,9 @@ Test 7: 0 1 2 +Test 8: +123 +456 ''' """ @@ -156,3 +159,20 @@ block: # issue #12487 doAssert s == @["something"] main() + +block: # minimized issue #24863 + echo "Test 8:" + proc c() = + iterator b(): int {.closure.} = + let r = 456 + yield 123 + proc n() = + echo r + let a = proc () = n() + a() + + let j = b + echo j() + discard j() + + c()