summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/asyncmacro.nim21
-rw-r--r--tests/async/t15804.nim15
-rw-r--r--tests/async/tasync_noasync.nim6
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