-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Fix malformed suggestion for E0061 when method is a macro token in macro context #140591
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
base: master
Are you sure you want to change the base?
Conversation
r? @davidtwco rustbot has assigned @davidtwco. Use |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just checking if it starts with "<Self>::"
will not work for the general case. Imagine something like
macro_rules! delegate {
($from:ident, $method:ident) => {
<$from>::$method(8)
}
}
struct Bar;
impl Bar {
fn foo(a: u8, b: u8) {
}
fn bar() {
delegate!(Bar, foo);
}
}
help: provide the argument
|
3 - <$from>::$method(8)
3 + <$from>::<$from>::$method(8, /* u8 */)
|
It would be better to just find the arg span (i.e. (8)
in this example). Most likely you will need to find a better way to do what
let (mut suggestion, suggestion_span) = if let Some(call_span) =
full_call_span.find_ancestor_inside_same_ctxt(error_span)
{
("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
}
does.
@mejrs |
7fba25a
to
e383b6f
Compare
This comment has been minimized.
This comment has been minimized.
Okay, I've checked this out and I think the best solution is to just simplify this entire construct. For some reason this diagnostic insists on getting the span of the function/method and then writing down the name again. We really need the span of the arguments, so let's do just that: Let's delete this conditional: let (mut suggestion, suggestion_span) = if let Some(call_span) =
full_call_span.find_ancestor_inside_same_ctxt(error_span)
{
//...
} else {
// ...
}; And instead write: let suggestion_span = if let Some(args_span) = error_span.trim_start(full_call_span) {
// Span of the braces, e.g. `(a, b, c)`.
args_span
} else {
// The arg span of a function call that wasn't even given braces
// like what might happen with delegation reuse.
// e.g. `reuse HasSelf::method;` should suggest `reuse HasSelf::method($args);`.
full_call_span.shrink_to_hi()
};
let mut suggestion = String::from("("); |
@mejrs yep, your solution runs like perfect, so I will leave it like this with comments because I found them informative for rust developers in future, and yeah, really wondering why this was overcomplicated initially |
I'm not sure. It feels like the difference between "this is the code you need to write" and "this is the change you need to make". So perhaps that has changed in the diagnostics machinery since the original code was written? Can you update the test with a case where the |
@mejrs should be fine now |
This is not what I meant. The original test (with the macro defined in the same file) is fine. You should add a test where the macro is defined in another crate. And in this case the compiler should not give the suggestion (but it currently does). Most likely you'll need to check https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro |
@mejrs let me check if get you correctly, so if macro is located in foreign crate, we should skip this suggestion, right? |
Right, we should avoid suggestions that would involve modifying a dependency. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test like #140591 (review) where it isn't explicitly <Self>
too?
@davidtwco mind if i add only one test case with |
fixes #140512
before
now