diff options
author | Yuriy Glukhov <yglukhov@users.noreply.github.com> | 2018-11-19 00:09:33 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-11-18 23:09:33 +0100 |
commit | 5a2290f788ebc160b3490a9f81d0478c0fad3aaf (patch) | |
tree | f89647ae53135258608550c674e893109adf4661 | |
parent | 5dfcc4e91ca38362e417b29becfa5c0e638c3d78 (diff) | |
download | Nim-5a2290f788ebc160b3490a9f81d0478c0fad3aaf.tar.gz |
Fixed yield in nkObjConstr. Fixes #9694 [backport] (#9744)
* Fixed yield in nkObjConstr. Fixes #9694 * Separate expr lowering from state splitting, introduce a clear lowering internal error
-rw-r--r-- | compiler/closureiters.nim | 24 | ||||
-rw-r--r-- | tests/iter/tyieldintry.nim | 15 |
2 files changed, 30 insertions, 9 deletions
diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 258372d76..c2d908193 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -462,10 +462,17 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = result.typ = n.typ for i in 0 ..< n.len: - if n[i].kind == nkStmtListExpr: + case n[i].kind + of nkExprColonExpr: + if n[i][1].kind == nkStmtListExpr: + let (st, ex) = exprToStmtList(n[i][1]) + result.add(st) + n[i][1] = ex + of nkStmtListExpr: let (st, ex) = exprToStmtList(n[i]) result.add(st) n[i] = ex + else: discard result.add(n) of nkIfStmt, nkIfExpr: @@ -852,15 +859,8 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode discard of nkStmtList, nkStmtListExpr: - assert(isEmptyType(n.typ), "nkStmtListExpr not lowered") - result = addGotoOut(result, gotoOut) for i in 0 ..< n.len: - if n[i].hasYieldsInExpressions: - # Lower nkStmtListExpr nodes inside `n[i]` first - var ns = false - n[i] = ctx.lowerStmtListExprs(n[i], ns) - if n[i].hasYields: # Create a new split let go = newNodeI(nkGotoState, n[i].info) @@ -1294,11 +1294,17 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode = ctx.stateVarSym.typ = g.createClosureIterStateType(fn) ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info) - let n = n.toStmtList + var n = n.toStmtList discard ctx.newState(n, nil) let gotoOut = newTree(nkGotoState, g.newIntLit(n.info, -1)) + var ns = false + n = ctx.lowerStmtListExprs(n, ns) + + if n.hasYieldsInExpressions(): + internalError(ctx.g.config, "yield in expr not lowered") + # Splitting transformation discard ctx.transformClosureIteratorBody(n, gotoOut) diff --git a/tests/iter/tyieldintry.nim b/tests/iter/tyieldintry.nim index 6d24417a6..ee2790e54 100644 --- a/tests/iter/tyieldintry.nim +++ b/tests/iter/tyieldintry.nim @@ -440,4 +440,19 @@ block: test(it, 1, 2, 5) +block: #9694 - yield in ObjConstr + type Foo = object + a, b: int + + template yieldAndNum: int = + yield 1 + 2 + + iterator it(): int {.closure.} = + let a = Foo(a: 5, b: yieldAndNum()) + checkpoint(a.b) + + test(it, 1, 2) + echo "ok" + |