templatesmacrosnim-lang

Nim: Analog of .dirty. pragma for macros


I am trying to write a macro which, among other things, gives a forward definition to a procedure which will be defined outside of the macro. However, I am getting a error. (This is similar to the issue I had in Why is my call of a nim template not simply expanding the template code? but with macros instead of templates).

Specifically I have the following code

import macros

macro General_Macro*(vType: untyped) =   
    quote do:
        proc Value*(self:var `vType`): float 

template General_Template*(vType: untyped) {.dirty.} =   
    proc Value*(self:var vType): float 

type
    Test_Type = ref object of RootObj


General_Macro(Test_Type)
#General_Template(Test_Type)


proc Value(self: var Test_Type): float =
    return 0.0

var Element = new(Test_Type)

echo $Element.Value

and I get the error

Test/test3x.nim(42, 14) Error: ambiguous call; both test3x.Value(self`gensym0: var Test_Type) [proc declared in Test/test3x.nim(25, 14)] and test3x.Value(self: var Test_Type) [proc declared in Test/test3x.nim(37, 6)] match for: (Test_Type)

However, if I uncomment out General_Template(Test_Type) and comment out General_Macro(Test_Type) the program compiles and runs without any issues.

I am not sure why the forward definition in the macro isn't being recognized by the later definition. Can someone help explain what I am missing?


Solution

  • Much like templates quote is a hygenic quasi quote macro. As such self {.inject.} is required inside the quote procedure definition.