prevent checking redundant_field_names lint on Derived code - #17555
prevent checking redundant_field_names lint on Derived code#17555azdle wants to merge 2 commits into
redundant_field_names lint on Derived code#17555Conversation
|
Thanks for the pull request, and welcome! You should hear from one of our reviewers after this PR gets at least 2 reviews from the community. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
|
Also, I should say, I didn't add a test for this because I would need a proc macro crate to generate code that would always, itself, fail the lint. As far as I can tell there isn't one for that yet and adding a dedicated crate for that to the test suite would dwarf this change and I wasn't sure if I should or not. I'm happy to add that if it's wanted. |
There was a problem hiding this comment.
This doesn't fix all the ways proc-macros can mess up when generating code. In thiserror it's generating $field: $field as though it were in the callers context even though the colon should have the macro's context. It happens to generate the expression as a whole in the correct context, but nothing stops macros from messing that up as well.
After the current in_external_macro check you can add:
field.span.check_text(cx, |src| {
let field_name = field.ident.as_str();
src.strip_prefix(name)
.and_then(|src| src.strip_suffix(name))
.is_some_and(|src| src.trim() == ":")
})|
Reminder, once the PR becomes ready for a review, use |
|
To add a test you can use use proc_macros::with_span;
with_span! {
field_name
Struct { field_name: field_name }
}The macro skips the first token and outputs the rest with the span of each set to the first token. This emulates the problematic code gen of other proc-macros. |
I'm not quite sure I understand this suggestion. In playing with it in a test, the lint produces warnings for code on the second line with or without the fix I'm suggesting. The expression as a whole still has a span that is Though, I did also discover tests/ui/auxiliary/proc_macro_derive.rs, which I assume would be built as 'external macros' for the tests (that's the only way proc macros work, right?), so using a macro from there would end up with an expression that is I haven't had the time to fully understand your first comment yet, so apologies if I'm completely speaking past any context from that. |
|
|
3e13057 to
2425efc
Compare
This comment has been minimized.
This comment has been minimized.
2425efc to
c814fdd
Compare
Assuming this is also true about the The bug is specifically when only the fields' idents are not from a macro, but the outer construction/format of the struct expression is. Which I think is how these macros are generally intended to be built, so I don't think this is a case of 'all the ways proc-macros can mess up when generating code'. I threw a separate commit in with a test on a super simple derive proc macro (with no span overrides at all) that fails before the existing fix commit that I hope shows what I mean. @rustbot ready |
|
The bug is entirely that the field span is being marked incorrectly because all three tokens are given the same span. When the macro outputs |
They don't all have the same span. In the returned |
|
Looking further it looks like rustc actually ignores the colon token, which is just wrong since it loses the context the expression field was written in. |
| if expr.span.in_external_macro(cx.sess().source_map()) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
usually, there is an is_from_proc_macro check right next to this I think.
Is it purposely ommitted?
This check was removed in #17294 and replaced with a later per-field check, however the
field'sspans can (maybe always do?) point back to the fields in the original struct declaration for struct expressions in derived code. This was causing this lint to warn on derive-generated code.I wrote a more complete explanation here: #17525 (comment)
changelog: [
redundant_field_names]: don't check derived expressionsFixes: #17525