* fixes #15804

* fix the existing test

* add the testcase for #15804

Co-authored-by: narimiran <narimiran@disroot.org>
This commit is contained in:
Andreas Rumpf
2020-11-02 14:17:09 +01:00
committed by GitHub
parent eb429988cd
commit dfd8a83f35
3 changed files with 27 additions and 15 deletions

View File

@@ -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

15
tests/async/t15804.nim Normal file
View 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()

View File

@@ -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
# we would need `{.dirty.}` templates for await