Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VM: cannot use generated proc with split declaration / definition #5030

Open
flyx opened this issue Nov 15, 2016 · 0 comments
Open

VM: cannot use generated proc with split declaration / definition #5030

flyx opened this issue Nov 15, 2016 · 0 comments

Comments

@flyx
Copy link
Contributor

flyx commented Nov 15, 2016

import macros

proc genProcDeclAndDef(name: var NimNode): NimNode {.compileTime.} =
  result = newStmtList()
  name = genSym(nskProc, "myProc")

  # generate proc declaration without implementation and add {.noconv.} pragma
  result.add(newProc(name, [newIdentNode("int")], newEmptyNode()))
  result[0][4] = newTree(nnkPragma, newIdentNode("noconv"))

  # generate proc implementation, remove {.noconv.} pragma
  result.add(copyNimTree(result[0]))
  result[1][4] = newEmptyNode()

  # proc implementation
  result[1][6] = newStmtList(newLit(42))

type MyProcType = proc(): int {.noconv.}

macro setProcVar(varName: MyProcType): typed =
  var procName: NimNode
  result = genProcDeclAndDef(procName)
  result.add(newAssignment(varName, procName))

var myProcVar: MyProcType
setProcVar(myProcVar)

This yields:

test1.nim(26, 11) template/generic instantiation from here                                                                                                                            
test1.nim(5, 16) Error: type mismatch: got (proc (): int) but expected 'MyProcType = proc (): int{.noconv.}'

Apparently, Nim fails to fetch the pragma from the declaration when doing this check. Also interesting what happens if I remove result[1][4] = newEmptyNode() (which deletes the pragma from the definition):

test1.nim(5, 16) Error: internal error: still forwarded: myProc                                                                                                                       
Traceback (most recent call last)                                                                                                                                                     
nim.nim(120)             nim                                                                                                                                                          
nim.nim(76)              handleCmdLine                                                                                                                                                
main.nim(252)            mainCommand                                                                                                                                                  
main.nim(66)             commandCompileToC                                                                                                                                            
cgen.nim(1328)           cgenWriteModules                                                                                                                                             
cgen.nim(1232)           finishModule                                                                                                                                                 
msgs.nim(994)            internalError                                                                                                                                                
msgs.nim(968)            liMessage                                                                                                                                                    
msgs.nim(840)            handleError                                                                                                                                                  
msgs.nim(824)            quit                                                                                                                                                         
FAILURE

It compiles if I do not split declaration and implementation:

  result.add(newProc(name, [newIdentNode("int")], newStmtList(newLit(42))))
  result[0][4] = newTree(nnkPragma, newIdentNode("noconv"))

The problem also vanishes if I do not genSym the proc:

  name = newIdentNode("myProc")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants