From 7a9831e13398dcdf1a45733b815f7e1a5d7c1337 Mon Sep 17 00:00:00 2001 From: hlaaftana <10591326+hlaaftana@users.noreply.github.com> Date: Sun, 5 Dec 2021 08:44:22 +0300 Subject: [PATCH] treat do with pragmas but no parens as proc (#19191) fixes #19188 --- compiler/parser.nim | 12 +++++++++--- doc/manual.rst | 8 ++++---- tests/parser/tdo.nim | 19 +++++++++++++++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/compiler/parser.nim b/compiler/parser.nim index 0ef6d1f54e18d..9ff847ef68fa2 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1110,11 +1110,14 @@ proc optPragmas(p: var Parser): PNode = proc parseDoBlock(p: var Parser; info: TLineInfo): PNode = #| doBlock = 'do' paramListArrow pragma? colcom stmt - let params = parseParamList(p, retColon=false) + var params = parseParamList(p, retColon=false) let pragmas = optPragmas(p) colcom(p, result) 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, body = result, params = params, name = p.emptyNode, pattern = 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] 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, params = openingParams, name = p.emptyNode, pattern = p.emptyNode, diff --git a/doc/manual.rst b/doc/manual.rst index 4fcc516ec9266..6705e673e8f30 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -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 will bind to the immediately preceding expression rather than the command call. -`do` with a parameter list corresponds to an anonymous `proc`, however -`do` without parameters is treated as a normal statement list. This allows -macros to receive both indented statement lists as an argument in inline -calls, as well as a direct mirror of Nim's routine syntax. +`do` with a parameter list or pragma list corresponds to an anonymous `proc`, +however `do` without parameters or pragmas is treated as a normal statement +list. This allows macros to receive both indented statement lists as an +argument in inline calls, as well as a direct mirror of Nim's routine syntax. .. code-block:: nim # Passing a statement list to an inline macro: diff --git a/tests/parser/tdo.nim b/tests/parser/tdo.nim index 7bd1f74116209..382d033985b60 100644 --- a/tests/parser/tdo.nim +++ b/tests/parser/tdo.nim @@ -1,8 +1,12 @@ discard """ - output: '''true + output: ''' true true -true inner B''' +true +true inner B +running with pragma +ran with pragma +''' """ template withValue(a, b, c, d, e: untyped) = @@ -77,3 +81,14 @@ proc main2 = echo "true inner B" 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))