-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
use_self: Fix false positive in macro expansion #6954
Conversation
r? @phansch (rust-highfive has picked a reviewer for you, use r? to override) |
} | ||
|
||
false | ||
} |
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.
This looks expensive and doesn't seem like the right solution to me. We probably need to check in_macro
somewhere while descending into the HIR rather than the other way around.
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.
I agree, we shouldn't have to traverse the HIR to determine if something comes from a macro expansion. Is this maybe a bug in rustc, not tracking the origin of this span correctly?
After doing some debugging I'm pretty sure this is a bug in the span lowering in rustc. Playground (You can expand the code under "Tools"). Expanded code – relevant snippet: if let _serde::__private::Ok(__ok) =
match _serde::Deserializer::deserialize_any(_serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content),
_serde::__private::de::UntaggedUnitVisitor::new("Direction",
"North"))
{
_serde::__private::Ok(()) =>
_serde::__private::Ok(Direction::North),
_serde::__private::Err(__err) =>
_serde::__private::Err(__err),
} {
return _serde::__private::Ok(__ok);
} The error is emitted for _serde::__private::Ok(Direction::North)
TL;DR: It doesn't come from an expansion at all. Since this code is obviously generated and clearly not written by the user the compiler should track that it is expanded. As a really wild guess, I would say, that this is because in the first case the expression is in the condition of an |
So after trying to reproduce this for a few hours, I give up. I have this proc_macro that produces really similar code to the serde expansion: #[proc_macro_derive(EnumUsedInIfLet)]
pub fn use_self(input: TokenStream) -> proc_macro::TokenStream {
let item: syn::ItemEnum = parse_macro_input!(input);
let _ident = item.ident;
TokenStream::from(quote! {
const _: () =
{
#[automatically_derived]
impl Foo for #_ident {
fn foo() -> Result<Self, &'static str> {
if let Ok(ok) = match bar() {
Ok(()) => Ok(#_ident::A),
Err(err) => Err(err),
} {
return Ok(ok);
}
Err("Ohoh")
}
}
};
})
} Expanded: trait Foo {
fn foo() -> Result<S, &'static str>;
}
fn bar() -> Result<(), &'static str> { Ok(()) }
#[derive(EnumUsedInIfLet)]
enum S { A } enum S { A, }
const _: () =
{
#[automatically_derived]
impl Foo for S {
fn foo() -> Result<Self, &'static str> {
if let Ok(ok) =
match bar() {
Ok(()) => Ok(S::A),
Err(err) => Err(err),
} {
return Ok(ok);
}
Err("Ohoh")
}
}
}; But it doesn't trigger the lint. So my guess is, that serde does som string manipulation in the proc macro and therefore rustc is unable to tell that the expanded span comes from a macro. So what I get from this: This fix doesn't work generally. It just randomly works here, because rustc is able to figure out the spans of the parent expressions. |
Same root issue as #6514? |
Seems like it |
Sorry for the late response, I took a vacation. In https://github.com/Y-Nak/clippy-6902-repro, I succeeded to find a minimal reproducer for #6902 and it seems not relevant to
No, this is not weird because the |
Ah thanks for doing some more investigation! Looking at your reproducer, I think the only thing I missed was that also the variant in the Do you want to open an issue in rust-lang/rust about this with your reproducer?
Ah right, makes sense. |
Yes, I'll open an issue. |
Opened rust-lang/rust#84122. |
fixes #6902
changelog:
use_self
: Fix false positive related to macro expansion.