Better error message and tests for bad await (#19622)

* Better error message and tests for bad await

* Use compiles to check if await is valid

* temp: disable windows noasync test

* Better error report, simplify test

Co-authored-by: flywind <xzsflywind@gmail.com>
This commit is contained in:
huantian
2022-04-13 14:03:46 -07:00
committed by GitHub
parent 98cebad7de
commit ef7d7f2459
2 changed files with 45 additions and 6 deletions

View File

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

View File

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