treat do with pragmas but no parens as proc (#19191)

fixes #19188
This commit is contained in:
hlaaftana 2021-12-05 08:44:22 +03:00 • committed by GitHub
commit 1ef945668d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 9 deletions

View file

@ -1110,11 +1110,14 @@ proc optPragmas(p: var Parser): PNode =
proc parseDoBlock(p: var Parser; info: TLineInfo): PNode = proc parseDoBlock(p: var Parser; info: TLineInfo): PNode =
#| doBlock = 'do' paramListArrow pragma? colcom stmt #| doBlock = 'do' paramListArrow pragma? colcom stmt
let params = parseParamList(p, retColon=false) var params = parseParamList(p, retColon=false)
let pragmas = optPragmas(p) let pragmas = optPragmas(p)
colcom(p, result) colcom(p, result)
result = parseStmt(p) result = parseStmt(p)
if params.kind != nkEmpty: if params.kind != nkEmpty or pragmas.kind != nkEmpty:
if params.kind == nkEmpty:
params = newNodeP(nkFormalParams, p)
params.add(p.emptyNode) # return type
result = newProcNode(nkDo, info, result = newProcNode(nkDo, info,
body = result, params = params, name = p.emptyNode, pattern = p.emptyNode, body = result, params = params, name = p.emptyNode, pattern = p.emptyNode,
genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode) genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
@ -1381,7 +1384,10 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
if stmtList[0].kind == nkStmtList: stmtList = stmtList[0] if stmtList[0].kind == nkStmtList: stmtList = stmtList[0]
stmtList.flags.incl nfBlockArg stmtList.flags.incl nfBlockArg
if openingParams.kind != nkEmpty: if openingParams.kind != nkEmpty or openingPragmas.kind != nkEmpty:
if openingParams.kind == nkEmpty:
openingParams = newNodeP(nkFormalParams, p)
openingParams.add(p.emptyNode) # return type
result.add newProcNode(nkDo, stmtList.info, body = stmtList, result.add newProcNode(nkDo, stmtList.info, body = stmtList,
params = openingParams, params = openingParams,
name = p.emptyNode, pattern = p.emptyNode, name = p.emptyNode, pattern = p.emptyNode,

View file

@ -3834,10 +3834,10 @@ The proc expression represented by the `do` block is appended to the routine
call as the last argument. In calls using the command syntax, the `do` block call as the last argument. In calls using the command syntax, the `do` block
will bind to the immediately preceding expression rather than the command call. will bind to the immediately preceding expression rather than the command call.
`do` with a parameter list corresponds to an anonymous `proc`, however `do` with a parameter list or pragma list corresponds to an anonymous `proc`,
`do` without parameters is treated as a normal statement list. This allows however `do` without parameters or pragmas is treated as a normal statement
macros to receive both indented statement lists as an argument in inline list. This allows macros to receive both indented statement lists as an
calls, as well as a direct mirror of Nim's routine syntax. argument in inline calls, as well as a direct mirror of Nim's routine syntax.
.. code-block:: nim .. code-block:: nim
# Passing a statement list to an inline macro: # Passing a statement list to an inline macro:

View file

@ -1,8 +1,12 @@
discard """ discard """
output: '''true output: '''
true true
true true
true inner B''' true
true inner B
running with pragma
ran with pragma
'''
""" """
template withValue(a, b, c, d, e: untyped) = template withValue(a, b, c, d, e: untyped) =
@ -77,3 +81,14 @@ proc main2 =
echo "true inner B" echo "true inner B"
main2() main2()
proc withPragma(foo: int, bar: proc() {.raises: [].}) =
echo "running with pragma"
bar()
withPragma(3) do {.raises: [].}:
echo "ran with pragma"
doAssert not (compiles do:
withPragma(3) do {.raises: [].}:
raise newException(Exception))