Fix `async` `proc` types & small cleanups (#347)
* Fix `async` `proc` types & small cleanups * review comments
This commit is contained in:
parent
4ada7fc0e1
commit
f3b77d8661
|
@ -72,6 +72,13 @@ proc verifyReturnType(typeName: string) {.compileTime.} =
|
||||||
macro unsupported(s: static[string]): untyped =
|
macro unsupported(s: static[string]): untyped =
|
||||||
error s
|
error s
|
||||||
|
|
||||||
|
proc params2(someProc: NimNode): NimNode =
|
||||||
|
# until https://github.com/nim-lang/Nim/pull/19563 is available
|
||||||
|
if someProc.kind == nnkProcTy:
|
||||||
|
someProc[0]
|
||||||
|
else:
|
||||||
|
params(someProc)
|
||||||
|
|
||||||
proc cleanupOpenSymChoice(node: NimNode): NimNode {.compileTime.} =
|
proc cleanupOpenSymChoice(node: NimNode): NimNode {.compileTime.} =
|
||||||
# Replace every Call -> OpenSymChoice by a Bracket expr
|
# Replace every Call -> OpenSymChoice by a Bracket expr
|
||||||
# ref https://github.com/nim-lang/Nim/issues/11091
|
# ref https://github.com/nim-lang/Nim/issues/11091
|
||||||
|
@ -92,21 +99,20 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
error("Cannot transform " & $prc.kind & " into an async proc." &
|
error("Cannot transform " & $prc.kind & " into an async proc." &
|
||||||
" proc/method definition or lambda node expected.")
|
" proc/method definition or lambda node expected.")
|
||||||
|
|
||||||
let returnType =
|
let returnType = cleanupOpenSymChoice(prc.params2[0])
|
||||||
cleanupOpenSymChoice(if prc.kind == nnkProcTy: prc[0][0] else: prc.params[0])
|
|
||||||
var baseType: NimNode
|
|
||||||
# Verify that the return type is a Future[T]
|
|
||||||
if returnType.kind == nnkBracketExpr:
|
|
||||||
let fut = repr(returnType[0])
|
|
||||||
verifyReturnType(fut)
|
|
||||||
baseType = returnType[1]
|
|
||||||
elif returnType.kind == nnkEmpty:
|
|
||||||
baseType = returnType
|
|
||||||
else:
|
|
||||||
verifyReturnType(repr(returnType))
|
|
||||||
|
|
||||||
let subtypeIsVoid = returnType.kind == nnkEmpty or
|
# Verify that the return type is a Future[T]
|
||||||
(baseType.kind == nnkIdent and returnType[1].eqIdent("void"))
|
let baseType =
|
||||||
|
if returnType.kind == nnkBracketExpr:
|
||||||
|
let fut = repr(returnType[0])
|
||||||
|
verifyReturnType(fut)
|
||||||
|
returnType[1]
|
||||||
|
elif returnType.kind == nnkEmpty:
|
||||||
|
ident("void")
|
||||||
|
else:
|
||||||
|
raiseAssert("Unhandled async return type: " & $prc.kind)
|
||||||
|
|
||||||
|
let subtypeIsVoid = baseType.eqIdent("void")
|
||||||
|
|
||||||
if prc.kind in {nnkProcDef, nnkLambda, nnkMethodDef, nnkDo}:
|
if prc.kind in {nnkProcDef, nnkLambda, nnkMethodDef, nnkDo}:
|
||||||
let
|
let
|
||||||
|
@ -260,13 +266,12 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
# Add discardable pragma.
|
# Add discardable pragma.
|
||||||
if returnType.kind == nnkEmpty:
|
if returnType.kind == nnkEmpty:
|
||||||
# Add Future[void]
|
# Add Future[void]
|
||||||
prc.params[0] =
|
prc.params2[0] =
|
||||||
newNimNode(nnkBracketExpr, prc)
|
newNimNode(nnkBracketExpr, prc)
|
||||||
.add(newIdentNode("Future"))
|
.add(newIdentNode("Future"))
|
||||||
.add(newIdentNode("void"))
|
.add(newIdentNode("void"))
|
||||||
|
|
||||||
prc
|
prc
|
||||||
#echo(treeRepr(result))
|
|
||||||
|
|
||||||
template await*[T](f: Future[T]): untyped =
|
template await*[T](f: Future[T]): untyped =
|
||||||
when declared(chronosInternalRetFuture):
|
when declared(chronosInternalRetFuture):
|
||||||
|
@ -318,8 +323,8 @@ macro async*(prc: untyped): untyped =
|
||||||
## Macro which processes async procedures into the appropriate
|
## Macro which processes async procedures into the appropriate
|
||||||
## iterators and yield statements.
|
## iterators and yield statements.
|
||||||
if prc.kind == nnkStmtList:
|
if prc.kind == nnkStmtList:
|
||||||
|
result = newStmtList()
|
||||||
for oneProc in prc:
|
for oneProc in prc:
|
||||||
result = newStmtList()
|
|
||||||
result.add asyncSingleProc(oneProc)
|
result.add asyncSingleProc(oneProc)
|
||||||
else:
|
else:
|
||||||
result = asyncSingleProc(prc)
|
result = asyncSingleProc(prc)
|
||||||
|
|
|
@ -13,6 +13,7 @@ when defined(nimHasUsed): {.used.}
|
||||||
|
|
||||||
type
|
type
|
||||||
RetValueType = proc(n: int): Future[int] {.async.}
|
RetValueType = proc(n: int): Future[int] {.async.}
|
||||||
|
RetImplicitVoidType = proc(n: int) {.async.}
|
||||||
RetVoidType = proc(n: int): Future[void] {.async.}
|
RetVoidType = proc(n: int): Future[void] {.async.}
|
||||||
|
|
||||||
proc asyncRetValue(n: int): Future[int] {.async.} =
|
proc asyncRetValue(n: int): Future[int] {.async.} =
|
||||||
|
@ -59,6 +60,9 @@ proc testAwait(): Future[bool] {.async.} =
|
||||||
block:
|
block:
|
||||||
let fn: RetVoidType = asyncRetVoid
|
let fn: RetVoidType = asyncRetVoid
|
||||||
await fn(100)
|
await fn(100)
|
||||||
|
block:
|
||||||
|
let fn: RetImplicitVoidType = asyncRetVoid
|
||||||
|
await fn(100)
|
||||||
block:
|
block:
|
||||||
let fn: RetValueType = asyncRetValue
|
let fn: RetValueType = asyncRetValue
|
||||||
if (await fn(100)) != 1000:
|
if (await fn(100)) != 1000:
|
||||||
|
|
Loading…
Reference in New Issue