* fixes #15804 * fix the existing test * add the testcase for #15804 Co-authored-by: narimiran <narimiran@disroot.org>
This commit is contained in:
parent
eb429988cd
commit
dfd8a83f35
3 changed files with 27 additions and 15 deletions
|
|
@ -129,6 +129,15 @@ proc verifyReturnType(typeName: string, node: NimNode = nil) {.compileTime.} =
|
||||||
error("Expected return type of 'Future' got '$1'" %
|
error("Expected return type of 'Future' got '$1'" %
|
||||||
typeName, node)
|
typeName, node)
|
||||||
|
|
||||||
|
template await*(f: typed): untyped {.used.} =
|
||||||
|
static:
|
||||||
|
error "await expects Future[T], got " & $typeof(f)
|
||||||
|
|
||||||
|
template await*[T](f: Future[T]): auto {.used.} =
|
||||||
|
var internalTmpFuture: FutureBase = f
|
||||||
|
yield internalTmpFuture
|
||||||
|
(cast[typeof(f)](internalTmpFuture)).read()
|
||||||
|
|
||||||
proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
## This macro transforms a single procedure into a closure iterator.
|
## This macro transforms a single procedure into a closure iterator.
|
||||||
## The ``async`` macro supports a stmtList holding multiple async procedures.
|
## The ``async`` macro supports a stmtList holding multiple async procedures.
|
||||||
|
|
@ -262,20 +271,8 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
result.params[0] = parseExpr("owned(Future[void])")
|
result.params[0] = parseExpr("owned(Future[void])")
|
||||||
|
|
||||||
# based on the yglukhov's patch to chronos: https://github.com/status-im/nim-chronos/pull/47
|
# based on the yglukhov's patch to chronos: https://github.com/status-im/nim-chronos/pull/47
|
||||||
# however here the overloads are placed inside each expanded async
|
|
||||||
var awaitDefinition = quote:
|
|
||||||
template await(f: typed): untyped {.used.} =
|
|
||||||
static:
|
|
||||||
error "await expects Future[T], got " & $typeof(f)
|
|
||||||
|
|
||||||
template await[T](f: Future[T]): auto {.used.} =
|
|
||||||
var internalTmpFuture: FutureBase = f
|
|
||||||
yield internalTmpFuture
|
|
||||||
(cast[type(f)](internalTmpFuture)).read()
|
|
||||||
|
|
||||||
if procBody.kind != nnkEmpty:
|
if procBody.kind != nnkEmpty:
|
||||||
body2.add quote do:
|
body2.add quote do:
|
||||||
`awaitDefinition`
|
|
||||||
`outerProcBody`
|
`outerProcBody`
|
||||||
result.body = body2
|
result.body = body2
|
||||||
|
|
||||||
|
|
|
||||||
15
tests/async/t15804.nim
Normal file
15
tests/async/t15804.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import asyncdispatch
|
||||||
|
|
||||||
|
type
|
||||||
|
Foo*[E] = ref object
|
||||||
|
op: proc(): Future[bool] {.gcsafe.}
|
||||||
|
|
||||||
|
proc newFoo*[E](): Foo[E] =
|
||||||
|
result = Foo[E]()
|
||||||
|
result.op = proc(): Future[bool] {.gcsafe,async.} =
|
||||||
|
await sleepAsync(100)
|
||||||
|
result = false
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let f = newFoo[int]()
|
||||||
|
echo waitFor f.op()
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "undeclared identifier: 'await'"
|
errormsg: "'yield' only allowed in an iterator"
|
||||||
cmd: "nim c $file"
|
cmd: "nim c $file"
|
||||||
file: "tasync_noasync.nim"
|
file: "asyncmacro.nim"
|
||||||
"""
|
"""
|
||||||
import async
|
import async
|
||||||
|
|
||||||
|
|
@ -12,4 +12,4 @@ await a()
|
||||||
|
|
||||||
# if we overload a fallback handler to get
|
# if we overload a fallback handler to get
|
||||||
# await only available within {.async.}
|
# await only available within {.async.}
|
||||||
# we would need `{.dirty.}` templates for await
|
# we would need `{.dirty.}` templates for await
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue