diff options
-rw-r--r-- | lib/pure/asyncmacro.nim | 16 | ||||
-rw-r--r-- | tests/async/tasync_noasync.nim | 35 |
2 files changed, 45 insertions, 6 deletions
diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim index ce538913f..63c8e6e5c 100644 --- a/lib/pure/asyncmacro.nim +++ b/lib/pure/asyncmacro.nim @@ -126,9 +126,19 @@ template await*(f: typed): untyped {.used.} = 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() + template yieldFuture = yield FutureBase() + + when compiles(yieldFuture): + var internalTmpFuture: FutureBase = f + yield internalTmpFuture + (cast[typeof(f)](internalTmpFuture)).read() + else: + macro errorAsync(futureError: Future[T]) = + error( + "Can only 'await' inside a proc marked as 'async'. Use " & + "'waitFor' when calling an 'async' proc in a non-async scope instead", + futureError) + errorAsync(f) proc asyncSingleProc(prc: NimNode): NimNode = ## This macro transforms a single procedure into a closure iterator. diff --git a/tests/async/tasync_noasync.nim b/tests/async/tasync_noasync.nim index 54f4f597f..0927148bf 100644 --- a/tests/async/tasync_noasync.nim +++ b/tests/async/tasync_noasync.nim @@ -1,13 +1,42 @@ discard """ - errormsg: "'yield' only allowed in an iterator" - cmd: "nim c $file" - file: "asyncmacro.nim" + cmd: "nim check --hints:off --warnings:off $file" + action: "reject" + nimout: ''' +tasync_noasync.nim(21, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(25, 12) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(28, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(31, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(35, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(38, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(40, 8) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +''' """ import async proc a {.async.} = discard +# Bad await usage +proc nonAsyncProc = + await a() + +proc nestedNonAsyncProc {.async.} = + proc nested = + await a() + +iterator customIterator: int = + await a() + +macro awaitInMacro = + await a() + +type DummyRef = ref object of RootObj +method awaitInMethod(_: DummyRef) {.base.} = + await a() + +proc improperMultisync {.multisync.} = + await a() + await a() # if we overload a fallback handler to get |