* Fixed yield in nkObjConstr. Fixes #9694 * Separate expr lowering from state splitting, introduce a clear lowering internal error
This commit is contained in:
parent
5dfcc4e91c
commit
5a2290f788
2 changed files with 30 additions and 9 deletions
|
|
@ -462,10 +462,17 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
|
|
||||||
for i in 0 ..< n.len:
|
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])
|
let (st, ex) = exprToStmtList(n[i])
|
||||||
result.add(st)
|
result.add(st)
|
||||||
n[i] = ex
|
n[i] = ex
|
||||||
|
else: discard
|
||||||
result.add(n)
|
result.add(n)
|
||||||
|
|
||||||
of nkIfStmt, nkIfExpr:
|
of nkIfStmt, nkIfExpr:
|
||||||
|
|
@ -852,15 +859,8 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode
|
||||||
discard
|
discard
|
||||||
|
|
||||||
of nkStmtList, nkStmtListExpr:
|
of nkStmtList, nkStmtListExpr:
|
||||||
assert(isEmptyType(n.typ), "nkStmtListExpr not lowered")
|
|
||||||
|
|
||||||
result = addGotoOut(result, gotoOut)
|
result = addGotoOut(result, gotoOut)
|
||||||
for i in 0 ..< n.len:
|
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:
|
if n[i].hasYields:
|
||||||
# Create a new split
|
# Create a new split
|
||||||
let go = newNodeI(nkGotoState, n[i].info)
|
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.stateVarSym.typ = g.createClosureIterStateType(fn)
|
||||||
|
|
||||||
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info)
|
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)
|
discard ctx.newState(n, nil)
|
||||||
let gotoOut = newTree(nkGotoState, g.newIntLit(n.info, -1))
|
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
|
# Splitting transformation
|
||||||
discard ctx.transformClosureIteratorBody(n, gotoOut)
|
discard ctx.transformClosureIteratorBody(n, gotoOut)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -440,4 +440,19 @@ block:
|
||||||
|
|
||||||
test(it, 1, 2, 5)
|
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"
|
echo "ok"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue