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

parsing variables/constants #1241

Closed
lauti7 opened this issue Nov 9, 2022 · 3 comments
Closed

parsing variables/constants #1241

lauti7 opened this issue Nov 9, 2022 · 3 comments

Comments

@lauti7
Copy link

lauti7 commented Nov 9, 2022

Hi! I'm trying to pass and parse a constant from my proc_macro in order to get the value of that constant. This constant may be declared in another module, so it wouldn't work to parse as a syn::ItemConst
What I'm trying to do is something like this:

    pub const MY_CONST: &str = "MYCONST";
    
    #[my_macro(MY_CONST)]
    pub fn test() {
    }
    

Is there any way to do this? I've been looking for a way but no luck. Thank u in advance!

@dtolnay
Copy link
Owner

dtolnay commented Dec 1, 2022

Closing as a duplicate of #963.

@dtolnay dtolnay closed this as completed Dec 1, 2022
@lauti7
Copy link
Author

lauti7 commented Dec 2, 2022

@dtolnay you closed the issue but there is no solution for this in the community. Could you provide a way to implement this?

@IcyTv
Copy link

IcyTv commented Dec 13, 2022

Hi, correct me if I'm wrong, but this is impossible to do.
The way a proc macro works, is that it gives you the Lexing output of rust. That means that you (just) get a stream of tokens. syn expands this a little by combining some tokens into a more usable form, but it does NOT do compile time evaluation (which is what this is). Meaning, none of your code actually runs and therefore the macro cannot know the value of the constant, because it might be a constant function result, it might be a result of another macro invocation, etc. none of which is evaluated at this point.
In order to work around this there are a couple of things you can do:

  1. Use a Lit... DataType (in this case a LitStr). This is just a literal value so there is no evaluation. The disadvantage is that it isn't reusable.
  2. Use a path reference. If you intend to only use the macro in some specific crate, etc. you might be able to resolve it by using a canonical path, something like my_crate::constants::MY_CONST and then it will be resolvable by all modules in your crate
  3. Use something like proc_macro_crate(?) to get a resolved reference to that constant. This way your macro would be usable from anywhere.
  4. Force the user of the macro to (re)-declare or import that constant

I am however having a hard time understanding what exactly you're trying to do. If you use the macro invocation when you have your constant in the module namespace, and you apply that macro to a function (like in your example), then wherever you import that function, the constant will stay resolved, since it's an implementation detail of that function and in that case only the function really cares about what the constant is or where it comes from and users don't...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants