diff options
-rw-r--r-- | lib/pure/asyncmacro.nim | 21 | ||||
-rw-r--r-- | tests/async/t15804.nim | 15 | ||||
-rw-r--r-- | tests/async/tasync_noasync.nim | 6 |
3 files changed, 27 insertions, 15 deletions
diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim index 65cf2f3b9..579e9fede 100644 --- a/lib/pure/asyncmacro.nim +++ b/lib/pure/asyncmacro.nim @@ -129,6 +129,15 @@ proc verifyReturnType(typeName: string, node: NimNode = nil) {.compileTime.} = error("Expected return type of 'Future' got '$1'" % 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.} = ## This macro transforms a single procedure into a closure iterator. ## 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])") # 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: body2.add quote do: - `awaitDefinition` `outerProcBody` result.body = body2 diff --git a/tests/async/t15804.nim b/tests/async/t15804.nim new file mode 100644 index 000000000..8de012196 --- /dev/null +++ b/tests/async/t15804.nim @@ -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() diff --git a/tests/async/tasync_noasync.nim b/tests/async/tasync_noasync.nim index 812b40da6..54f4f597f 100644 --- a/tests/async/tasync_noasync.nim +++ b/tests/async/tasync_noasync.nim @@ -1,7 +1,7 @@ discard """ - errormsg: "undeclared identifier: 'await'" + errormsg: "'yield' only allowed in an iterator" cmd: "nim c $file" - file: "tasync_noasync.nim" + file: "asyncmacro.nim" """ import async @@ -12,4 +12,4 @@ await a() # if we overload a fallback handler to get # await only available within {.async.} -# we would need `{.dirty.}` templates for await \ No newline at end of file +# we would need `{.dirty.}` templates for await |