discardable async procs are now an error (#14176)

* add discard warning in manual
This commit is contained in:
hlaaftana
2020-05-01 10:49:13 +03:00
committed by GitHub
parent d5fc35c968
commit 9b01c6cf48
4 changed files with 26 additions and 10 deletions

View File

@@ -2568,7 +2568,8 @@ Example:
discard p(3, 4) # discard the return value of `p`
The ``discard`` statement evaluates its expression for side-effects and
throws the expression's resulting value away.
throws the expression's resulting value away, and should only be used
when ignoring this value is known not to cause problems.
Ignoring the return value of a procedure without using a discard statement is
a static error.

View File

@@ -112,7 +112,7 @@ proc getName(node: NimNode): string {.compileTime.} =
of nnkEmpty:
return "anonymous"
else:
error("Unknown name.")
error("Unknown name.", node)
proc getFutureVarIdents(params: NimNode): seq[NimNode] {.compileTime.} =
result = @[]
@@ -125,10 +125,10 @@ proc getFutureVarIdents(params: NimNode): seq[NimNode] {.compileTime.} =
proc isInvalidReturnType(typeName: string): bool =
return typeName notin ["Future"] #, "FutureStream"]
proc verifyReturnType(typeName: string) {.compileTime.} =
proc verifyReturnType(typeName: string, node: NimNode = nil) {.compileTime.} =
if typeName.isInvalidReturnType:
error("Expected return type of 'Future' got '$1'" %
typeName)
typeName, node)
proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
## This macro transforms a single procedure into a closure iterator.
@@ -141,7 +141,13 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
if prc.kind notin {nnkProcDef, nnkLambda, nnkMethodDef, nnkDo}:
error("Cannot transform this node kind into an async proc." &
" proc/method definition or lambda node expected.")
" proc/method definition or lambda node expected.", prc)
if prc[4].kind != nnkEmpty:
for prag in prc[4]:
if prag.eqIdent("discardable"):
error("Cannot make async proc discardable. Futures have to be " &
"checked with `asyncCheck` instead of discarded", prag)
let prcName = prc.name.getName
@@ -153,16 +159,16 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
# Verify that the return type is a Future[T]
if returnType.kind == nnkBracketExpr:
let fut = repr(returnType[0])
verifyReturnType(fut)
verifyReturnType(fut, returnType[0])
baseType = returnType[1]
elif returnType.kind in nnkCallKinds and returnType[0].eqIdent("[]"):
let fut = repr(returnType[1])
verifyReturnType(fut)
verifyReturnType(fut, returnType[0])
baseType = returnType[2]
elif returnType.kind == nnkEmpty:
baseType = returnType
else:
verifyReturnType(repr(returnType))
verifyReturnType(repr(returnType), returntype)
let subtypeIsVoid = returnType.kind == nnkEmpty or
(baseType.kind == nnkIdent and returnType[1].eqIdent("void"))
@@ -303,7 +309,7 @@ proc stripReturnType(returnType: NimNode): NimNode =
result = returnType
if returnType.kind == nnkBracketExpr:
let fut = repr(returnType[0])
verifyReturnType(fut)
verifyReturnType(fut, returnType)
result = returnType[1]
proc splitProc(prc: NimNode): (NimNode, NimNode) =

View File

@@ -0,0 +1,9 @@
discard """
errmsg: "Cannot make async proc discardable. Futures have to be checked with `asyncCheck` instead of discarded"
"""
import async
proc foo {.async, discardable.} = discard
foo()

View File

@@ -26,5 +26,5 @@ proc hop(): bool =
echo "done"
const r = hop()
const r {.used.} = hop()