summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYuriy Glukhov <yglukhov@users.noreply.github.com>2018-11-19 00:09:33 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-11-18 23:09:33 +0100
commit5a2290f788ebc160b3490a9f81d0478c0fad3aaf (patch)
treef89647ae53135258608550c674e893109adf4661
parent5dfcc4e91ca38362e417b29becfa5c0e638c3d78 (diff)
downloadNim-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.nim24
-rw-r--r--tests/iter/tyieldintry.nim15
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"
+