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:
parent
98cebad7de
commit
ef7d7f2459
2 changed files with 45 additions and 6 deletions
|
|
@ -126,9 +126,19 @@ template await*(f: typed): untyped {.used.} =
|
||||||
error "await expects Future[T], got " & $typeof(f)
|
error "await expects Future[T], got " & $typeof(f)
|
||||||
|
|
||||||
template await*[T](f: Future[T]): auto {.used.} =
|
template await*[T](f: Future[T]): auto {.used.} =
|
||||||
|
template yieldFuture = yield FutureBase()
|
||||||
|
|
||||||
|
when compiles(yieldFuture):
|
||||||
var internalTmpFuture: FutureBase = f
|
var internalTmpFuture: FutureBase = f
|
||||||
yield internalTmpFuture
|
yield internalTmpFuture
|
||||||
(cast[typeof(f)](internalTmpFuture)).read()
|
(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 =
|
proc asyncSingleProc(prc: NimNode): NimNode =
|
||||||
## This macro transforms a single procedure into a closure iterator.
|
## This macro transforms a single procedure into a closure iterator.
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,42 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "'yield' only allowed in an iterator"
|
cmd: "nim check --hints:off --warnings:off $file"
|
||||||
cmd: "nim c $file"
|
action: "reject"
|
||||||
file: "asyncmacro.nim"
|
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
|
import async
|
||||||
|
|
||||||
proc a {.async.} =
|
proc a {.async.} =
|
||||||
discard
|
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()
|
await a()
|
||||||
|
|
||||||
# if we overload a fallback handler to get
|
# if we overload a fallback handler to get
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue