You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import macros
macrofoo(x: static[int], n: typed): untyped=result= n
ifresult.kind inRoutineNodes:
echo"foo on ", result.name, ", x: ", x
else:
echo"foo on ", result.kind, ", x: ", x
macroaddFooToBody(x: static[int], n: typed): untyped=result=copyNimTree n
result.body = newStmtList:
newCall(bindSym"foo", newLit x):
result.body
echo"added foo(", x, ") to body"macroaddFoo(n: typed): untyped=result=copyNimTree n
# This is also the wrong order to add the macros, see nim-lang/Nim#18348result.addPragma:
nnkExprColonExpr.newTree(bindSym"addFooToBody", newLit1)
result.addPragma:
nnkExprColonExpr.newTree(bindSym"foo", newLit2)
proctest() {.used, addFoo.} =discard
Current Output
added foo(1) to body
foo on test, x: 2
foo on nnkDiscardStmt, x: 1
Expected Output
added foo(1) to body
foo on nnkDiscardStmt, x: 1
foo on test, x: 2
Additional Information
$ nim -v
Nim Compiler Version 1.5.1 [Linux: amd64]
Compiled at 2021-06-24
Copyright (c) 2006-2021 by Andreas Rumpf
git hash: 0f91b67f5c15328330f74a8769aed9961940aab2
active boot switches: -d:release -d:nimUseLinenoise
The text was updated successfully, but these errors were encountered:
import macros
macroc(n: typed): untyped=result= n
echo"c"echoresult.repr
macrob(n: typed): untyped=result=copyNimTree n
result.body =newStmtList(ident"abc") # this is supposed to errorecho"b"echoresult.repr
macroa(n: typed): untyped=result=copyNimTree n
result.addPragma(bindSym"b")
result.addPragma(bindSym"c")
echo"a"echoresult.repr
proctest() {.a.} =discard
a
proc test() {.b, c.} =
discard
b
proc test() {.c.} =
abc
c
proc test() =
abc
a.nim(24, 15) template/generic instantiation of `a` from here
a.nim(18, 12) template/generic instantiation of `b` from here
a.nim(20, 12) template/generic instantiation of `c` from here
a.nim(10, 34) Error: undeclared identifier: 'abc'
My guess is when c is getting called, the proc test() = abc argument is considered typed since it has type tyVoid, and so not rechecked by prepareOperand. Using calls instead of pragmas works, because the next macro receives a different node than the proc node, a call node, always having a nil type.
We can fix this case (checking for formal.kind == tyTyped and a.typ.kind == tyVoid in prepareOperand as well as a.typ == nil), but I don't know about the general case, when the typed argument has non-void type. We could automatically set the type to nil for every macro output with type untyped, but this could break stuff, and there's the question of it being applied recursively. Another option is maybe exposing something like eraseType(node) which sets the type of the node to nil. but maybe this makes users depend on an implementation detail.
There's also the question of "should prepareOperand check for nil type at all", when it could just sem everything given to it. I don't know if this is feasible but as seen in #16867 other things like nkHiddenCallConv have similar problems.
Example
Current Output
Expected Output
Additional Information
The text was updated successfully, but these errors were encountered: