Hi ALL,
I am trying to understand how inject pragma works and the following behavior is very surprising
https://play.nim-lang.org/#ix=2AtC
let xx = "global xx"
template tt_outer(code: untyped): untyped =
block:
let xx {.inject.} = "(tt_outer) xx"
let yy {.inject.} = "(tt_outer) yy"
code
template tt_inner(): untyped =
echo "tt_inner: xx = ", xx
echo "tt_inner: yy = ", yy
tt_outer:
tt_inner()
When run, the tt_inner template binds global xx symbol and local yy (as defined in tt_outer) as seen in the output
tt_inner: xx = global xx
tt_inner: yy = (tt_outer) yy
I was expecting both xx and yy bound in the innermost scope. Also, adding mixin xx into tt_inner template definition does not even compile. What am I doing wrong?
Hi! I encountered this recently myself too, you can find some discussion and workarounds here:
#15314 Injected symbols aren't resolved properly in expression passed to inner template
The most general fix seems to be using the {.dirty.} pragma:
import macros
let xx = "global xx"
template tt_outer(code: untyped) =
block:
let xx {.inject.} = "(tt_outer) xx"
let yy {.inject.} = "(tt_outer) yy"
code
template tt_inner() {.dirty.} =
echo "tt_inner: xx = ", xx
echo "tt_inner: yy = ", yy
tt_outer:
tt_inner()
@exelotl: Thanks a lot!
{.dirty.} solved the problem, indeed. Moreover, when I make both templates "dirty", I do not need {.inject.} any longer.