mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 13:30:33 +00:00
await x where x is Fut var now reads after yield. Fixes #3964.
This commit is contained in:
@@ -1316,6 +1316,23 @@ proc generateExceptionCheck(futSym,
|
|||||||
)
|
)
|
||||||
result.add elseNode
|
result.add elseNode
|
||||||
|
|
||||||
|
template useVar(result: var NimNode, futureVarNode: NimNode, valueReceiver,
|
||||||
|
rootReceiver: expr, fromNode: NimNode) =
|
||||||
|
## Params:
|
||||||
|
## futureVarNode: The NimNode which is a symbol identifying the Future[T]
|
||||||
|
## variable to yield.
|
||||||
|
## fromNode: Used for better debug information (to give context).
|
||||||
|
## valueReceiver: The node which defines an expression that retrieves the
|
||||||
|
## future's value.
|
||||||
|
##
|
||||||
|
## rootReceiver: ??? TODO
|
||||||
|
# -> yield future<x>
|
||||||
|
result.add newNimNode(nnkYieldStmt, fromNode).add(futureVarNode)
|
||||||
|
# -> future<x>.read
|
||||||
|
valueReceiver = newDotExpr(futureVarNode, newIdentNode("read"))
|
||||||
|
result.add generateExceptionCheck(futureVarNode, tryStmt, rootReceiver,
|
||||||
|
fromNode)
|
||||||
|
|
||||||
template createVar(result: var NimNode, futSymName: string,
|
template createVar(result: var NimNode, futSymName: string,
|
||||||
asyncProc: NimNode,
|
asyncProc: NimNode,
|
||||||
valueReceiver, rootReceiver: expr,
|
valueReceiver, rootReceiver: expr,
|
||||||
@@ -1323,9 +1340,7 @@ template createVar(result: var NimNode, futSymName: string,
|
|||||||
result = newNimNode(nnkStmtList, fromNode)
|
result = newNimNode(nnkStmtList, fromNode)
|
||||||
var futSym = genSym(nskVar, "future")
|
var futSym = genSym(nskVar, "future")
|
||||||
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
||||||
result.add newNimNode(nnkYieldStmt, fromNode).add(futSym) # -> yield future<x>
|
useVar(result, futSym, valueReceiver, rootReceiver, fromNode)
|
||||||
valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
|
|
||||||
result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode)
|
|
||||||
|
|
||||||
proc processBody(node, retFutureSym: NimNode,
|
proc processBody(node, retFutureSym: NimNode,
|
||||||
subTypeIsVoid: bool,
|
subTypeIsVoid: bool,
|
||||||
@@ -1352,7 +1367,11 @@ proc processBody(node, retFutureSym: NimNode,
|
|||||||
case node[1].kind
|
case node[1].kind
|
||||||
of nnkIdent, nnkInfix:
|
of nnkIdent, nnkInfix:
|
||||||
# await x
|
# await x
|
||||||
result = newNimNode(nnkYieldStmt, node).add(node[1]) # -> yield x
|
result = newNimNode(nnkStmtList, node)
|
||||||
|
var futureValue: NimNode
|
||||||
|
result.useVar(node[1], futureValue, futureValue, node)
|
||||||
|
# -> yield x
|
||||||
|
# -> x.read()
|
||||||
of nnkCall, nnkCommand:
|
of nnkCall, nnkCommand:
|
||||||
# await foo(p, x)
|
# await foo(p, x)
|
||||||
var futureValue: NimNode
|
var futureValue: NimNode
|
||||||
@@ -1550,6 +1569,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
|||||||
for i in 0 .. <result[4].len:
|
for i in 0 .. <result[4].len:
|
||||||
if result[4][i].kind == nnkIdent and result[4][i].ident == !"async":
|
if result[4][i].kind == nnkIdent and result[4][i].ident == !"async":
|
||||||
result[4].del(i)
|
result[4].del(i)
|
||||||
|
result[4] = newEmptyNode()
|
||||||
if subtypeIsVoid:
|
if subtypeIsVoid:
|
||||||
# Add discardable pragma.
|
# Add discardable pragma.
|
||||||
if returnType.kind == nnkEmpty:
|
if returnType.kind == nnkEmpty:
|
||||||
@@ -1559,7 +1579,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
|||||||
result[6] = outerProcBody
|
result[6] = outerProcBody
|
||||||
|
|
||||||
#echo(treeRepr(result))
|
#echo(treeRepr(result))
|
||||||
#if prc[0].getName == "hubConnectionLoop":
|
#if prc[0].getName == "g":
|
||||||
# echo(toStrLit(result))
|
# echo(toStrLit(result))
|
||||||
|
|
||||||
macro async*(prc: stmt): stmt {.immediate.} =
|
macro async*(prc: stmt): stmt {.immediate.} =
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ proc main() {.async.} =
|
|||||||
var file = openAsync(fn, fmAppend)
|
var file = openAsync(fn, fmAppend)
|
||||||
await file.write("\ntest2")
|
await file.write("\ntest2")
|
||||||
let errorTest = file.readAll()
|
let errorTest = file.readAll()
|
||||||
await errorTest
|
echo await errorTest
|
||||||
doAssert errorTest.failed
|
doAssert errorTest.failed
|
||||||
file.close()
|
file.close()
|
||||||
file = openAsync(fn, fmRead)
|
file = openAsync(fn, fmRead)
|
||||||
|
|||||||
Reference in New Issue
Block a user