nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.49k stars 1.46k forks source link

`invalid pragma: stacktrace:false` on macro-generated proc #22198

Closed arnetheduck closed 1 year ago

arnetheduck commented 1 year ago

Description

import std/macros

macro async2(prc: untyped): untyped =
  echo prc.kind
  prc.addPragma(newColonExpr(ident "stackTrace", ident "off"))

  prc

func recurse(tree: NimNode): NimNode {.compileTime.}=
  tree.expectKind {nnkProcDef, nnkIteratorDef, nnkStmtList}
  if tree.kind == nnkStmtList:
    for i, child in tree:
      tree[i] = child.recurse
    tree
  else:
    let name = tree[0]
    quote do:
      proc `name` {.async2.} = discard

macro turnIntoProc(tree: untyped) =
  tree.recurse

proc test0 {.turnIntoProc.}
# OK

iterator test1 {.turnIntoProc.}
# Error: invalid pragma: stackTrace: false

turnIntoProc:
  iterator test2

based on https://github.com/status-im/nim-chronos/issues/367

Nim Version

1.6.12

Current Output

$ nim c -r "testit.nim"
nnkProcDef
nnkProcDef
testit.nim(63, 5) Error: invalid pragma: stackTrace: false


### Expected Output

_No response_

### Possible Solution

_No response_

### Additional Information

_No response_
Araq commented 1 year ago

Works on devel.

juancarlospaco commented 1 year ago

!nim c

import std/macros
macro async2(f: untyped): untyped =
  doAssert f.kind == nnkProcDef
  f.addPragma(newColonExpr(ident "stackTrace", ident "off"))
  f
func recurse(tree: NimNode): NimNode {.compileTime.}=
  doAssert tree.kind in {nnkProcDef, nnkIteratorDef, nnkStmtList}
  if tree.kind == nnkStmtList:
    for i, child in tree: tree[i] = child.recurse
    tree
  else:
    let name = tree[0]
    quote do:
      proc `name` {.async2.} = discard
macro turnIntoProc(tree: untyped) = tree.recurse
proc test0 {.turnIntoProc.}
turnIntoProc: 
  iterator test2
iterator test1 {.turnIntoProc.}
github-actions[bot] commented 1 year ago

@juancarlospaco (contributor)

devel :+1: OK

Output

Stats

  • Created 2023-07-06T18:47:34Z
  • Started 2023-07-06T18:48:07
  • Finished 2023-07-06T18:48:08
  • Duration 1 minute
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
stable :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(13, 5) Error: invalid pragma: stackTrace: false

Stats

  • Created 2023-07-06T18:47:34Z
  • Started 2023-07-06T18:48:08
  • Finished 2023-07-06T18:48:09
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

```cpp #define NIM_INTBITS 64 #include "nimbase.h" #undef LANGUAGE_C #undef MIPSEB #undef MIPSEL #undef PPC #undef R3000 #undef R4000 #undef i386 #undef linux #undef mips #undef near #undef far #undef powerpc #undef unix N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimTestErrorFlag(); } } ```

AST

```nim nnkStmtList.newTree( nnkImportStmt.newTree( nnkInfix.newTree( newIdentNode("/"), newIdentNode("std"), newIdentNode("macros") ) ), nnkMacroDef.newTree( newIdentNode("async2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("untyped"), nnkIdentDefs.newTree( newIdentNode("f"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("kind") ), newIdentNode("nnkProcDef") ) ), nnkCall.newTree( nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("addPragma") ), nnkCall.newTree( newIdentNode("newColonExpr"), nnkCommand.newTree( newIdentNode("ident"), newLit("stackTrace") ), nnkCommand.newTree( newIdentNode("ident"), newLit("off") ) ) ), newIdentNode("f") ) ), nnkFuncDef.newTree( newIdentNode("recurse"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("NimNode"), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("NimNode"), newEmptyNode() ) ), nnkPragma.newTree( newIdentNode("compileTime") ), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("in"), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), nnkCurly.newTree( newIdentNode("nnkProcDef"), newIdentNode("nnkIteratorDef"), newIdentNode("nnkStmtList") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), newIdentNode("nnkStmtList") ), nnkStmtList.newTree( nnkForStmt.newTree( newIdentNode("i"), newIdentNode("child"), newIdentNode("tree"), nnkStmtList.newTree( nnkAsgn.newTree( nnkBracketExpr.newTree( newIdentNode("tree"), newIdentNode("i") ), nnkDotExpr.newTree( newIdentNode("child"), newIdentNode("recurse") ) ) ) ), newIdentNode("tree") ) ), nnkElse.newTree( nnkStmtList.newTree( nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("name"), newEmptyNode(), nnkBracketExpr.newTree( newIdentNode("tree"), newLit(0) ) ) ), nnkCall.newTree( newIdentNode("quote"), nnkStmtList.newTree( nnkProcDef.newTree( nnkAccQuoted.newTree( newIdentNode("name") ), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("async2") ), newEmptyNode(), nnkStmtList.newTree( nnkDiscardStmt.newTree( newEmptyNode() ) ) ) ) ) ) ) ) ) ), nnkMacroDef.newTree( newIdentNode("turnIntoProc"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode(), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("recurse") ) ) ), nnkProcDef.newTree( newIdentNode("test0"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ), nnkCall.newTree( newIdentNode("turnIntoProc"), nnkStmtList.newTree( nnkIteratorDef.newTree( newIdentNode("test2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), newEmptyNode(), newEmptyNode(), newEmptyNode() ) ) ), nnkIteratorDef.newTree( newIdentNode("test1"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ) ) ```
1.6.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(13, 5) Error: invalid pragma: stackTrace: false

Stats

  • Created 2023-07-06T18:47:34Z
  • Started 2023-07-06T18:48:12
  • Finished 2023-07-06T18:48:12
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

```cpp #define NIM_INTBITS 64 #include "nimbase.h" #undef LANGUAGE_C #undef MIPSEB #undef MIPSEL #undef PPC #undef R3000 #undef R4000 #undef i386 #undef linux #undef mips #undef near #undef far #undef powerpc #undef unix N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimTestErrorFlag(); } } ```

AST

```nim nnkStmtList.newTree( nnkImportStmt.newTree( nnkInfix.newTree( newIdentNode("/"), newIdentNode("std"), newIdentNode("macros") ) ), nnkMacroDef.newTree( newIdentNode("async2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("untyped"), nnkIdentDefs.newTree( newIdentNode("f"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("kind") ), newIdentNode("nnkProcDef") ) ), nnkCall.newTree( nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("addPragma") ), nnkCall.newTree( newIdentNode("newColonExpr"), nnkCommand.newTree( newIdentNode("ident"), newLit("stackTrace") ), nnkCommand.newTree( newIdentNode("ident"), newLit("off") ) ) ), newIdentNode("f") ) ), nnkFuncDef.newTree( newIdentNode("recurse"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("NimNode"), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("NimNode"), newEmptyNode() ) ), nnkPragma.newTree( newIdentNode("compileTime") ), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("in"), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), nnkCurly.newTree( newIdentNode("nnkProcDef"), newIdentNode("nnkIteratorDef"), newIdentNode("nnkStmtList") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), newIdentNode("nnkStmtList") ), nnkStmtList.newTree( nnkForStmt.newTree( newIdentNode("i"), newIdentNode("child"), newIdentNode("tree"), nnkStmtList.newTree( nnkAsgn.newTree( nnkBracketExpr.newTree( newIdentNode("tree"), newIdentNode("i") ), nnkDotExpr.newTree( newIdentNode("child"), newIdentNode("recurse") ) ) ) ), newIdentNode("tree") ) ), nnkElse.newTree( nnkStmtList.newTree( nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("name"), newEmptyNode(), nnkBracketExpr.newTree( newIdentNode("tree"), newLit(0) ) ) ), nnkCall.newTree( newIdentNode("quote"), nnkStmtList.newTree( nnkProcDef.newTree( nnkAccQuoted.newTree( newIdentNode("name") ), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("async2") ), newEmptyNode(), nnkStmtList.newTree( nnkDiscardStmt.newTree( newEmptyNode() ) ) ) ) ) ) ) ) ) ), nnkMacroDef.newTree( newIdentNode("turnIntoProc"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode(), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("recurse") ) ) ), nnkProcDef.newTree( newIdentNode("test0"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ), nnkCall.newTree( newIdentNode("turnIntoProc"), nnkStmtList.newTree( nnkIteratorDef.newTree( newIdentNode("test2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), newEmptyNode(), newEmptyNode(), newEmptyNode() ) ) ), nnkIteratorDef.newTree( newIdentNode("test1"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ) ) ```
1.4.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(13, 5) Error: invalid pragma: stackTrace: false

Stats

  • Created 2023-07-06T18:47:34Z
  • Started 2023-07-06T18:48:15
  • Finished 2023-07-06T18:48:15
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

```cpp #define NIM_INTBITS 64 #include "nimbase.h" #undef LANGUAGE_C #undef MIPSEB #undef MIPSEL #undef PPC #undef R3000 #undef R4000 #undef i386 #undef linux #undef mips #undef near #undef far #undef powerpc #undef unix N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimTestErrorFlag(); } } ```

AST

```nim nnkStmtList.newTree( nnkImportStmt.newTree( nnkInfix.newTree( newIdentNode("/"), newIdentNode("std"), newIdentNode("macros") ) ), nnkMacroDef.newTree( newIdentNode("async2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("untyped"), nnkIdentDefs.newTree( newIdentNode("f"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("kind") ), newIdentNode("nnkProcDef") ) ), nnkCall.newTree( nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("addPragma") ), nnkCall.newTree( newIdentNode("newColonExpr"), nnkCommand.newTree( newIdentNode("ident"), newLit("stackTrace") ), nnkCommand.newTree( newIdentNode("ident"), newLit("off") ) ) ), newIdentNode("f") ) ), nnkFuncDef.newTree( newIdentNode("recurse"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("NimNode"), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("NimNode"), newEmptyNode() ) ), nnkPragma.newTree( newIdentNode("compileTime") ), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("in"), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), nnkCurly.newTree( newIdentNode("nnkProcDef"), newIdentNode("nnkIteratorDef"), newIdentNode("nnkStmtList") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), newIdentNode("nnkStmtList") ), nnkStmtList.newTree( nnkForStmt.newTree( newIdentNode("i"), newIdentNode("child"), newIdentNode("tree"), nnkStmtList.newTree( nnkAsgn.newTree( nnkBracketExpr.newTree( newIdentNode("tree"), newIdentNode("i") ), nnkDotExpr.newTree( newIdentNode("child"), newIdentNode("recurse") ) ) ) ), newIdentNode("tree") ) ), nnkElse.newTree( nnkStmtList.newTree( nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("name"), newEmptyNode(), nnkBracketExpr.newTree( newIdentNode("tree"), newLit(0) ) ) ), nnkCall.newTree( newIdentNode("quote"), nnkStmtList.newTree( nnkProcDef.newTree( nnkAccQuoted.newTree( newIdentNode("name") ), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("async2") ), newEmptyNode(), nnkStmtList.newTree( nnkDiscardStmt.newTree( newEmptyNode() ) ) ) ) ) ) ) ) ) ), nnkMacroDef.newTree( newIdentNode("turnIntoProc"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode(), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("recurse") ) ) ), nnkProcDef.newTree( newIdentNode("test0"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ), nnkCall.newTree( newIdentNode("turnIntoProc"), nnkStmtList.newTree( nnkIteratorDef.newTree( newIdentNode("test2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), newEmptyNode(), newEmptyNode(), newEmptyNode() ) ) ), nnkIteratorDef.newTree( newIdentNode("test1"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ) ) ```
1.2.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(13, 5) Error: invalid pragma: stackTrace: false

Stats

  • Created 2023-07-06T18:47:34Z
  • Started 2023-07-06T18:48:30
  • Finished 2023-07-06T18:48:30
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

```cpp #define NIM_INTBITS 64 #include "nimbase.h" #undef LANGUAGE_C #undef MIPSEB #undef MIPSEL #undef PPC #undef R3000 #undef R4000 #undef i386 #undef linux #undef mips #undef near #undef far #undef powerpc #undef unix N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimTestErrorFlag(); } } ```

AST

```nim nnkStmtList.newTree( nnkImportStmt.newTree( nnkInfix.newTree( newIdentNode("/"), newIdentNode("std"), newIdentNode("macros") ) ), nnkMacroDef.newTree( newIdentNode("async2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("untyped"), nnkIdentDefs.newTree( newIdentNode("f"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("kind") ), newIdentNode("nnkProcDef") ) ), nnkCall.newTree( nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("addPragma") ), nnkCall.newTree( newIdentNode("newColonExpr"), nnkCommand.newTree( newIdentNode("ident"), newLit("stackTrace") ), nnkCommand.newTree( newIdentNode("ident"), newLit("off") ) ) ), newIdentNode("f") ) ), nnkFuncDef.newTree( newIdentNode("recurse"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("NimNode"), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("NimNode"), newEmptyNode() ) ), nnkPragma.newTree( newIdentNode("compileTime") ), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("in"), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), nnkCurly.newTree( newIdentNode("nnkProcDef"), newIdentNode("nnkIteratorDef"), newIdentNode("nnkStmtList") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), newIdentNode("nnkStmtList") ), nnkStmtList.newTree( nnkForStmt.newTree( newIdentNode("i"), newIdentNode("child"), newIdentNode("tree"), nnkStmtList.newTree( nnkAsgn.newTree( nnkBracketExpr.newTree( newIdentNode("tree"), newIdentNode("i") ), nnkDotExpr.newTree( newIdentNode("child"), newIdentNode("recurse") ) ) ) ), newIdentNode("tree") ) ), nnkElse.newTree( nnkStmtList.newTree( nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("name"), newEmptyNode(), nnkBracketExpr.newTree( newIdentNode("tree"), newLit(0) ) ) ), nnkCall.newTree( newIdentNode("quote"), nnkStmtList.newTree( nnkProcDef.newTree( nnkAccQuoted.newTree( newIdentNode("name") ), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("async2") ), newEmptyNode(), nnkStmtList.newTree( nnkDiscardStmt.newTree( newEmptyNode() ) ) ) ) ) ) ) ) ) ), nnkMacroDef.newTree( newIdentNode("turnIntoProc"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode(), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("recurse") ) ) ), nnkProcDef.newTree( newIdentNode("test0"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ), nnkCall.newTree( newIdentNode("turnIntoProc"), nnkStmtList.newTree( nnkIteratorDef.newTree( newIdentNode("test2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), newEmptyNode(), newEmptyNode(), newEmptyNode() ) ) ), nnkIteratorDef.newTree( newIdentNode("test1"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ) ) ```
1.0.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(13, 5) Error: invalid pragma: stackTrace: false

Stats

  • Created 2023-07-06T18:47:34Z
  • Started 2023-07-06T18:48:43
  • Finished 2023-07-06T18:48:44
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

```cpp #define NIM_INTBITS 64 #include "nimbase.h" #undef LANGUAGE_C #undef MIPSEB #undef MIPSEL #undef PPC #undef R3000 #undef R4000 #undef i386 #undef linux #undef mips #undef near #undef far #undef powerpc #undef unix N_LIB_PRIVATE N_NIMCALL(void, nimTestErrorFlag)(void); N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000)(void); N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); N_LIB_PRIVATE void PreMainInner(void) { } N_LIB_PRIVATE int cmdCount; N_LIB_PRIVATE char** cmdLine; N_LIB_PRIVATE char** gEnv; N_LIB_PRIVATE void PreMain(void) { #if 0 void (*volatile inner)(void); inner = PreMainInner; atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); (*inner)(); #else atmdotdotatsdotdotatsdotdotatsdotchoosenimatstoolchainsatsnimminusathdevelatslibatssystemdotnim_Init000(); PreMainInner(); #endif } N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { NimMainModule(); } N_CDECL(void, NimMain)(void) { #if 0 void (*volatile inner)(void); PreMain(); inner = NimMainInner; (*inner)(); #else PreMain(); NimMainInner(); #endif } int main(int argc, char** args, char** env) { cmdLine = args; cmdCount = argc; gEnv = env; NimMain(); return nim_program_result; } N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimTestErrorFlag(); } } ```

AST

```nim nnkStmtList.newTree( nnkImportStmt.newTree( nnkInfix.newTree( newIdentNode("/"), newIdentNode("std"), newIdentNode("macros") ) ), nnkMacroDef.newTree( newIdentNode("async2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("untyped"), nnkIdentDefs.newTree( newIdentNode("f"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("kind") ), newIdentNode("nnkProcDef") ) ), nnkCall.newTree( nnkDotExpr.newTree( newIdentNode("f"), newIdentNode("addPragma") ), nnkCall.newTree( newIdentNode("newColonExpr"), nnkCommand.newTree( newIdentNode("ident"), newLit("stackTrace") ), nnkCommand.newTree( newIdentNode("ident"), newLit("off") ) ) ), newIdentNode("f") ) ), nnkFuncDef.newTree( newIdentNode("recurse"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newIdentNode("NimNode"), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("NimNode"), newEmptyNode() ) ), nnkPragma.newTree( newIdentNode("compileTime") ), newEmptyNode(), nnkStmtList.newTree( nnkCommand.newTree( newIdentNode("doAssert"), nnkInfix.newTree( newIdentNode("in"), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), nnkCurly.newTree( newIdentNode("nnkProcDef"), newIdentNode("nnkIteratorDef"), newIdentNode("nnkStmtList") ) ) ), nnkIfStmt.newTree( nnkElifBranch.newTree( nnkInfix.newTree( newIdentNode("=="), nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("kind") ), newIdentNode("nnkStmtList") ), nnkStmtList.newTree( nnkForStmt.newTree( newIdentNode("i"), newIdentNode("child"), newIdentNode("tree"), nnkStmtList.newTree( nnkAsgn.newTree( nnkBracketExpr.newTree( newIdentNode("tree"), newIdentNode("i") ), nnkDotExpr.newTree( newIdentNode("child"), newIdentNode("recurse") ) ) ) ), newIdentNode("tree") ) ), nnkElse.newTree( nnkStmtList.newTree( nnkLetSection.newTree( nnkIdentDefs.newTree( newIdentNode("name"), newEmptyNode(), nnkBracketExpr.newTree( newIdentNode("tree"), newLit(0) ) ) ), nnkCall.newTree( newIdentNode("quote"), nnkStmtList.newTree( nnkProcDef.newTree( nnkAccQuoted.newTree( newIdentNode("name") ), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("async2") ), newEmptyNode(), nnkStmtList.newTree( nnkDiscardStmt.newTree( newEmptyNode() ) ) ) ) ) ) ) ) ) ), nnkMacroDef.newTree( newIdentNode("turnIntoProc"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode(), nnkIdentDefs.newTree( newIdentNode("tree"), newIdentNode("untyped"), newEmptyNode() ) ), newEmptyNode(), newEmptyNode(), nnkStmtList.newTree( nnkDotExpr.newTree( newIdentNode("tree"), newIdentNode("recurse") ) ) ), nnkProcDef.newTree( newIdentNode("test0"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ), nnkCall.newTree( newIdentNode("turnIntoProc"), nnkStmtList.newTree( nnkIteratorDef.newTree( newIdentNode("test2"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), newEmptyNode(), newEmptyNode(), newEmptyNode() ) ) ), nnkIteratorDef.newTree( newIdentNode("test1"), newEmptyNode(), newEmptyNode(), nnkFormalParams.newTree( newEmptyNode() ), nnkPragma.newTree( newIdentNode("turnIntoProc") ), newEmptyNode(), newEmptyNode() ) ) ```
??? :arrow_right: :bug:

Diagnostics

The commit that introduced the bug can not be found, but the bug is in the commits:

(Can not find the commit because Nim can not be re-built commit-by-commit to bisect).

:robot: Bug found in 38 minutes bisecting 460 commits at 12 commits per second.

juancarlospaco commented 1 year ago

@araq Yep fixed on devel.

arnetheduck commented 1 year ago

can the fix be found via the bisect tool, ie which commit fixed it so it can be backported?

arnetheduck commented 1 year ago

also, the bug is reported against 1.6.12 meaning it should not really be closed ideally

juancarlospaco commented 1 year ago

can the fix be found via the bisect tool

@arnetheduck DIY Need smallest as possible but assertive (no echo but doAssert) bug repro code sample:

temp

Ideally users can bisect their own bugs by themselves.

Sometimes the specific commit that has the bug can not be found, because Nim can not be re-built commit-by-commit on that specific commit to bisect, but then it gives you the "commits near" where the bug hides (and for context), likely the commit with the bug arrived in pack with other commits in a PR:

temp

arnetheduck commented 1 year ago

ping for reopening / backport