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

arguments of typed macro leak into outer scope #4547

Closed
krux02 opened this issue Jul 30, 2016 · 4 comments · Fixed by #22564
Closed

arguments of typed macro leak into outer scope #4547

krux02 opened this issue Jul 30, 2016 · 4 comments · Fixed by #22564

Comments

@krux02
Copy link
Contributor

krux02 commented Jul 30, 2016

I was trying to implement a macro that transforms a value declaration into a lazy initialized variable, and I realized, that the ast that was passed into the macro, is not properly replaced by the result of the macro.

import macros

# the macro itself is not really important
macro lazy(stmtList : typed) : untyped =
  let decl = stmtList[0]
  decl.expectKind nnkLetSection
  let name = $decl[0][0].symbol
  let call = decl[0][2].copy
  call.expectKind nnkCall
  let ident = newIdentNode("get" & name)

  result = quote do:
    var value : type(`call`)
    proc `ident`() : type(`call`) =
      if value.isNil:
        value = `call`
      value

  echo result.repr

type MyObject = object
  a,b: int    

# this part, the macro call and it's result (written in the comment below) is important
lazy:
  let y = new(MyObject)

#[
  var value: type(new(MyObject))
  proc gety(): type(new(MyObject)) =
    if value.isNil:
      value = new(MyObject)
    value    
]#

echo gety().a  # works and should work
echo gety().b  # works and should work
echo y.a       # identifier y should not exist anymore
echo y.b       # identifier y should not exist anymore

As you can see, the macro lazy has an argument with a let declaration let y =. But the let part is not part of the output of the macro anymore. Therefore the last two lines should refuse to compile, because there is no value y anymore. Instead the nim compiler accepts this without problems, but then generates invalid c code:

Error: execution of an external compiler program 'gcc -c  -w  -I/home/arne/proj/nim/Nim/lib -o /tmp/aporia/nimcache/a1.o /tmp/aporia/nimcache/a1.c' failed with exit code: 256

/tmp/aporia/nimcache/a1.c: In Funktion »a1Init000«:
/tmp/aporia/nimcache/a1.c:381:23: Fehler: »y_99211_899815572« nicht deklariert (erste Benutzung in dieser Funktion)
  LOC5 = nimIntToStr((*y_99211_899815572).a);
                       ^~~~~~~~~~~~~~~~~
/tmp/aporia/nimcache/a1.c:381:23: Anmerkung: jeder nicht deklarierte Bezeichner wird nur einmal für jede Funktion, in der er vorkommt, gemeldet

Another side effect is that an expression let y = 28 after the macro call yields Error: redefinition of 'y' and I can't call the procedure gety just y.

redefinition of 'y'

@Araq
Copy link
Member

Araq commented Aug 4, 2016

Yes, symbol table modifications are not undone after the type matching process, hence you need to use untyped for code blocks. Not sure if we can fix this for v1.

@krux02
Copy link
Contributor Author

krux02 commented Jul 24, 2017

just in case someone sees this one year later, it is still the same problem.

@krux02
Copy link
Contributor Author

krux02 commented Jul 7, 2019

If we can't fix it, maybe we should document this broken behavior.

@metagn
Copy link
Collaborator

metagn commented Aug 27, 2023

Error: undeclared identifier: 'y' is now given, likely since #15158

metagn added a commit to metagn/Nim that referenced this issue Aug 27, 2023
closes nim-lang#12582, closes nim-lang#19552, closes nim-lang#2465, closes nim-lang#4596, closes nim-lang#15246,
closes nim-lang#12683, closes nim-lang#7889, closes nim-lang#4547, closes nim-lang#12415, closes nim-lang#2002,
closes nim-lang#1771, closes nim-lang#5121

The test for nim-lang#5648 is also moved into its own test
from `types/tissues_types` due to not being joinable.
@Araq Araq closed this as completed in c19fd69 Aug 27, 2023
narimiran pushed a commit that referenced this issue Sep 18, 2023
* test case haul for old generic/template/macro issues

closes #12582, closes #19552, closes #2465, closes #4596, closes #15246,
closes #12683, closes #7889, closes #4547, closes #12415, closes #2002,
closes #1771, closes #5121

The test for #5648 is also moved into its own test
from `types/tissues_types` due to not being joinable.

* fix template gensym test

(cherry picked from commit c19fd69)
narimiran pushed a commit that referenced this issue Sep 18, 2023
* test case haul for old generic/template/macro issues

closes #12582, closes #19552, closes #2465, closes #4596, closes #15246,
closes #12683, closes #7889, closes #4547, closes #12415, closes #2002,
closes #1771, closes #5121

The test for #5648 is also moved into its own test
from `types/tissues_types` due to not being joinable.

* fix template gensym test

(cherry picked from commit c19fd69)
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.

3 participants