The following macro fails, and I don't understand why. here on the Nim playground
import macros
type MyModel[T] = object
discard
macro network*(): untyped =
let underlyingTypeSymbol = ident"WHAT"
var params = @[
newNimNode(nnkBracketExpr).add(
ident"MyModel",
underlyingTypeSymbol
),
newIdentDefs(
ident"a",
newNimNode(nnkBracketExpr).add(
ident"MyModel",
underlyingTypeSymbol
)
)
]
result = newProc(
name = ident"init",
params = params
)
# GenericParams
result[2] = newNimNode(nnkGenericParams).add(
newIdentDefs(
underlyingTypeSymbol,
newEmptyNode()
)
)
echo toStrLit(result)
network()
The macro is supposed to create a function like this:
proc init[WHAT](a: MyModel[WHAT]): MyModel[WHAT] = discard
But I get an error when compiling:
Hint: used config file '/home/tsoj/.choosenim/toolchains/nim-1.6.4/config/nim.cfg' [Conf]
Hint: used config file '/home/tsoj/.choosenim/toolchains/nim-1.6.4/config/config.nims' [Conf]
...........................................................
proc init[WHAT](a: MyModel[WHAT]): MyModel[WHAT] =
/tmp/testtest.nim(39, 8) template/generic instantiation of `network` from here
/tmp/testtest.nim(11, 19) Error: cannot instantiate MyModel [type declared in /tmp/testtest.nim(3, 6)]
got: <WHAT>
but expected: <T>
Did I mess something up or is this a compiler bug?
It might be a bug because this works:
import macros
type MyModel[T] = object
discard
macro network*(): untyped =
result = quote do:
proc init[WHAT](a: MyModel[WHAT]): MyModel[WHAT] =
discard
network()
echo init(MyModel[int]())
It works if you use copy too.
import macros
type MyModel[T] = object
discard
macro network*(): untyped =
let underlyingTypeSymbol = genSym(nskGenericParam, "WHAT")
var params = @[
newNimNode(nnkBracketExpr).add(
ident"MyModel",
copy underlyingTypeSymbol
),
newIdentDefs(
ident"a",
newNimNode(nnkBracketExpr).add(
ident"MyModel",
copy underlyingTypeSymbol
)
)
]
result = newProc(
name = ident"init",
params = params
)
# GenericParams
result[2] = newNimNode(nnkGenericParams).add(
newIdentDefs(
copy underlyingTypeSymbol,
newEmptyNode()
)
)
network()
discard MyModel[int]().init