From 1fc3a68205697c2ad33b2f0e1cfcb526e73b0677 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 30 Jul 2018 08:34:15 +0200 Subject: [PATCH] Access implicit `result` trough envP in closures (#8471) Reuse the existing machinery, most of the changes are only needed to handle the `result = result` node in nkReturnStmt produced by the closure iterator transform. Fixes #338 --- compiler/lambdalifting.nim | 14 +++++++++++++- tests/iter/t338.nim | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/iter/t338.nim diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 0a48011504..d8c0461ce8 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -222,7 +222,7 @@ proc interestingIterVar(s: PSym): bool {.inline.} = # XXX optimization: Only lift the variable if it lives across # yield/return boundaries! This can potentially speed up # closure iterators quite a bit. - result = s.kind in {skVar, skLet, skTemp, skForVar} and sfGlobal notin s.flags + result = s.kind in {skResult, skVar, skLet, skTemp, skForVar} and sfGlobal notin s.flags template isIterator*(owner: PSym): bool = owner.kind == skIterator and owner.typ.callConv == ccClosure @@ -458,6 +458,10 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) = of nkLambdaKinds, nkIteratorDef, nkFuncDef: if n.typ != nil: detectCapturedVars(n[namePos], owner, c) + of nkReturnStmt: + if n[0].kind in {nkAsgn, nkFastAsgn}: + detectCapturedVars(n[0].sons[1], owner, c) + else: assert n[0].kind == nkEmpty else: for i in 0..