Nim: Pragmas async+discardable should be a Syntax Error

Created on 17 Dec 2019  路  9Comments  路  Source: nim-lang/Nim

Pragmas {.async.} and {.multisync.} combined with {.discardable.}
should be a Syntax Error or at least a compile time Warning.

Example

import asyncdispatch

proc foo(): Future[void] {.async, discardable.} = discard
proc bar(): Future[void] {.multisync, discardable.} = discard

Similar but not the same https://github.com/nim-lang/Nim/issues/11912#issue-478298948
recommends adding an {.undiscardable.} pragma for discard asyncProc(),
this bug is about the combination of {.async, discardable.} should be a Syntax Error.
I guess should not be too complicated to get a list of pragmas and if both found together thrown error.

Async Error messages Macros RFC Stdlib

Most helpful comment

macros as pragmas have visibility into the other pragmas of a proc

import macros

macro myPragma(procDef: untyped): untyped =
  echo procDef.toStrLit()
  result = procDef

proc randomInt(): int {.myPragma, discardable.} =
  result = 4 # A perfectly random integer

randomInt()

CompileTime output:

proc randomInt(): int {.discardable.} =
  result = 4

So it's just a matter of policy, the change is easy and can be done without compiler support.

All 9 comments

I think #11912 is a better solution. (Hardcoding a check like proposed in this issue into the compiler is a bad idea/hack IMO)
In this case with type T {.undiscardable.} a definition like this: proc foo(): T {.discardable.} = ... should error as well.

I agree, but still something can be done to improve when using {.async, discardable.},
it can even be improving the documentation on that specific topic,
Ive observed new people tend to try to use such construct when the compiler says that the Future can not be discarded.
:thinking:

I am not sure what you mean by Hardcoding checks,
all Syntax Errors are kinda "Hardcoded checks" arent they?,
how do you configure a Syntax Error?, theres no way a {.async, noreturn.} is the desired syntax whatsoever.
:thinking:

I think you're missing that async is a custom pragma, not one built into the compiler.
https://nim-lang.org/docs/manual.html#macros-macros-as-pragmas

macros as pragmas have visibility into the other pragmas of a proc

import macros

macro myPragma(procDef: untyped): untyped =
  echo procDef.toStrLit()
  result = procDef

proc randomInt(): int {.myPragma, discardable.} =
  result = 4 # A perfectly random integer

randomInt()

CompileTime output:

proc randomInt(): int {.discardable.} =
  result = 4

So it's just a matter of policy, the change is easy and can be done without compiler support.

Yeah, this should be a trivial change in the macro and I fully support it.

and what if it is discardable, async

@alehander92 Doesn't matter :)

sorry, i now realized how it must work :D

Was this page helpful?
0 / 5 - 0 ratings