-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Go-to-definition and auto-completion inside a macro_rules invocation #14999
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
Comments
The problem here is that In your case it looks like the input is effectively an import path, in which case you might have look with just doing the following macro_rules! f {
($($p:tt)*) => {{
+ use $($p)* as _;
$crate::reflection::RawCallable {
import_path: stringify!($($p)*),
registered_at: ::std::env!("CARGO_PKG_NAME")
}
}};
} (Note the order will be important, if the use comes after stringify some features will bail out after seeing the use in stringify) |
Ideally we'd offer a tool attribute that allows macro authors to instruct r-a to handle specific macro inputs in a special way, but that hasn't happened yet and probably needs to wait for some other architecture work first. |
I see, thanks for the explanation! Unfortunately the path here is an expression path rather than an import path. f!(crate::my_function)
f!(crate::MyType::method)
f!(crate::my_g_function::<Type>)
f!(<crate:: MyType as MyTrait>::trait_method) I don't think macro rules are necessarily powerful enough for me to craft the "right" usage example in each case. I could probably do it with a procedural macro, but I don't know if RA would be able to see through that. |
I think |
That's what I used to have at the very beginning, but it breaks down (i.e. inference errors) if the function/method has any generic parameter without a default value 😔 |
A thing that I could do, without any negative side-effect, is changing the matcher from macro_rules! f {
($($p:tt)*) => {{ /* */ }};
} to macro_rules! f {
($p:expr) => {{ /* */ }};
} but I'm not seeing any difference in the behaviour of rust-analyzer. I'm assuming that it doesn't use the matcher type as hint 🤔 |
It does not currently, that's something on our wishlist as well still for some other things, but it wouldn't be a goal for this either (#11183). What you really want here is the tool attribute approach I was talking about earlier. #11556 macro_rules! f {
($($p:tt)*) => {{
+ #[rust_analyzer::treat_path(expr, $($p:)*)]
+ use crate as _;
$crate::reflection::RawCallable {
import_path: stringify!($($p)*),
registered_at: ::std::env!("CARGO_PKG_NAME")
}
}};
} to instruct r-a. But for that we'd first need either stable tool attributes or special case rust-analyzer like rustfmt and clippy are as implicit tools already (technically possible now that r-a is an official rust lang tool). And then obviously figure out nice naming conventions for these attributes as we kind of need to promise a stable api for them... |
I see. Is there any movement on special-casing r-a or is the feature blocked on a "general" tool annotation feature in the language? |
I don't think anyone really tried asking whether we can make r-a a special cased tool as well, the general tool attribute feature is not really being worked on to my knowledge. |
vlad on the IntellijRust repository suggested a fix that ended up working for r-a but not for IntellijRust: add a perma-disabled #[cfg(always_disabled)]
let _ = $p; (see intellij-rust/intellij-rust#10543 (comment)) This circumvents the inference issues but it seems to be enough to tip r-a into doing the right thing 🎉 |
That will only partially work in r-a as well though. As that is effectively disabled, most analysis will not work with it and we fall back to some heuristics or nothing depending on the feature. And in the future I personally want to get rid of those heuristics because they re-derive facts that were already done in our semantics layer for paths 😅, but that is still some time in the future so until then this trick is better than nothing I guess :) |
I can totally see this not being a long-term solution, but it seems to enable the two analyses I care about (completion and go-to-definition) so it's a decent stopgap solution :) |
In Pavex, there is a
f!
macro. It desugars toThe expectation is that the argument passed to
f!
is a path to a Rust type (either a method or a function).In RA, as soon as you are writing inside the
f!
context (e.g.f!(crate::...)
), you don't get any autocompletion.Once the path is full spelled out (e.g.
f!(crate::get_articles)
), you also don't get the "go to definition" assist.Is there a way to improve the experience here? Is there something that I can do, as the macro author, to help RA in dealing with this case?
The text was updated successfully, but these errors were encountered: