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

Generic function does not look for macro definition in the scope of the module where it is defined #18649

Closed
deech opened this issue Aug 5, 2021 · 0 comments · Fixed by #24254

Comments

@deech
Copy link
Contributor

deech commented Aug 5, 2021

Say we have the following modules.

mymacro.nim (which defines a macro):

macro aMacro*(u:untyped):untyped =
  echo "in macro"
  result = u

myproc.nim (which uses the macro as a pragma):

import mymacro
proc p*[T]() =
  proc inner() {.aMacro.} =
    discard
  inner()
  discard

main.nim (which uses the proc):

import myproc
p[string]()

I get the error:

nim cpp -r --verbosity\:0 --hint\[Processing\]\:off --excessiveStackTrace\:on /home/deech/Nim/procmacro/main.nim
/home/deech/Nim/procmacro/myproc.nim(1, 8) Warning: imported and not used: 'mymacro' [UnusedImport]
/home/deech/Nim/procmacro/main.nim(3, 2) template/generic instantiation of `p` from here
/home/deech/Nim/procmacro/myproc.nim(3, 18) Error: invalid pragma: aMacro

but if I remove the generic T and redefine p as proc p*() ... the macro is called.

It seems like p is expanded in place and evaluated in the scope of main.nim which doesn't import myMacro and causes the error.

This at least seems like surprising behavior, I would expect the expansion of p[T] to look for aMacro in its own import scope and not the scope where it's called.

The workaround is to import mymacro in main which isn't ideal because main shouldn't have to know about p's implementation details.

@deech deech changed the title Generic function does not look for macro definition in the scope of it's module Generic function does not look for macro definition in the scope of the module where it is defined Aug 5, 2021
Araq pushed a commit that referenced this issue Oct 7, 2024
fixes #24186 

When encountering pragma nodes in templates, if it's a language pragma,
we don't process the name, and only any values if they exist. If it's
not a language pragma, we process the full node. Previously only the
values of colon expressions were processed.

To make this simpler, `whichPragma` is patched to consider bracketed
hint/warning etc pragmas like `{.hint[HintName]: off.}` as being a
pragma of kind `wHint` rather than an invalid pragma which would have to
be checked separately. From looking at the uses of `whichPragma` this
doesn't seem like it would cause problems.

Generics have [the same
problem](https://github.com/nim-lang/Nim/blob/a27542195c9ba760d58e9d1e977313bc322a1ede/compiler/semgnrc.nim#L619)
(causing #18649), but to make it work we need to make sure the
templates/macros don't get evaluated or get evaluated correctly (i.e.
passing the proc node as the final argument), either with #23094 or by
completely disabling template/macro evaluation when processing the
pragma node, which would also cover `{.pragma.}` templates.
metagn added a commit to metagn/Nim that referenced this issue Oct 7, 2024
@Araq Araq closed this as completed in d72b848 Oct 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants