Hello, I have a proc macro that is very sensitive to the way how you run it and I need to know is it used by rust-analyzer or not. Is there some env variable or something else I can use to know this?
You can configure it to ignore your proc macro (something I'd like RustRover to implement, too).
I think you can just check the host process executable name. rust-analyzer-proc-macro-srv
is the one used by rust-analyzer
.
but why do you do this? I don't think it's a good idea to create such macros.
Rust-analyzer is rerunning proc-macros with the same global variables on the same code, while compiler calls every macro only once, because source code is not changing while you are compiling.
Ah, I thought it was a problem during the development of the proc macro, but from what you said, it will also be a problem for its users?
Are you absolutely sure you need to change global variables? And if so, couldn't you simply detect if the particular instance you're processing has already updated those variables?
Perhaps that giving a few more details would help.
I need to bail on duplicates, but there is no way for me to know is it a duplicate or user edited it or moved to another module. Only If I would reread the whole source code and parse it myself every time, but I will not do this. Thus I will disable that duplicate checking in rust-analyzer, thus user will see this error when compiling with the compiller.
It's very hard for me to understand what you're doing without more information. All I can say is that rust-analyzer isn't the only way to expand macros. I mentioned RustRover earlier, which has its own macro expander, and so if you rely on something very specific to rust-analyzer, it won't solve the problem for the users of that IDE (or potentially future ones).
Also, using global variables can be very tricky. Why do you need that? I guess to pass information from one proc macro instance to another, but it's all very vague, and you might also be able to pass that information in the code you're generating.
Global Registration (a kind of pre-rfc) - language design - Rust Internals Would have solved it
generally, macros should be side effect free, idempotent. why are you using global variables in macros?
although there's no technical limitation what proc macros can do, but does it mean you should do crazy things? (such as this demo)
Maybe there is another way around? To know that this is just rustc, not r-a/rust rover etc? I guess it should not bind on cargo too
Can you use the span information?
If you need to know whether it's in the same file or not, you'll have to wait for this to be solved, though Chances are, if it's in a different file, it shouldn't be a problem (though, again, without knowing what your proc macro does, it's just guessing in the dark).
Not really. Spans can shift, user can move it across modules, rename stuff, I can't use it.
Why don't you give more information on what you're doing? Making us guess isn't very productive...
I'm not sure that you should guess . I agree that detecting rust-analyzer is not as great because there is Rust Rover, as well as possibly something else. Instead, maybe there is a way to detect that the crate is compiled as normal?
There is absolutely no guarantee that rustc will run proc-macros exactly once either. It is free to expand multiple crates inside a skngle process (sharing global state for proc macros) or to cache the expansion of a proc macro for the next compilation session for better performance.