summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhlaaftana <10591326+hlaaftana@users.noreply.github.com>2021-12-05 08:44:22 +0300
committerGitHub <noreply@github.com>2021-12-05 06:44:22 +0100
commit1ef945668d458163cb7116a8c936ff92b63d679d (patch)
tree1a2a614f5359922ed1bf94f02ade77002e4ce637
parentc658de24b04be9f898359a4091c5815f28de8785 (diff)
downloadNim-1ef945668d458163cb7116a8c936ff92b63d679d.tar.gz
treat do with pragmas but no parens as proc (#19191)
fixes #19188
-rw-r--r--compiler/parser.nim12
-rw-r--r--doc/manual.rst8
-rw-r--r--tests/parser/tdo.nim19
3 files changed, 30 insertions, 9 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 0ef6d1f54..9ff847ef6 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 4fcc516ec..6705e673e 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 7bd1f7411..382d03398 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))