mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
* fixes #15804 * fix the existing test * add the testcase for #15804 Co-authored-by: narimiran <narimiran@disroot.org>
This commit is contained in:
@@ -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
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 """
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user