-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add new disallowed_fields lint
#16218
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
48e76b6 to
73d1c63
Compare
| // Very round-about way to get the field `DefId` from the expr: first we get its | ||
| // parent `Ty`. Then we go through all its fields to find the one with the expected | ||
| // name and get the `DefId` from it. | ||
| if let Some(parent_ty) = cx.typeck_results().expr_ty_opt(e) |
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'm really not sure this is the best way to get the DefId from Expr::Field but couldn't find another way. I'd love to know if there is one!
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 needs to use the adjusted type.
clippy_utils/src/paths.rs
Outdated
| .filter_by_name_unhygienic(name) | ||
| .find(|assoc_item| ns.matches(Some(assoc_item.namespace()))) | ||
| .map(|assoc_item| assoc_item.def_id), | ||
| ItemKind::Struct(_, _, rustc_hir::VariantData::Struct { fields, .. }) => fields.iter().find_map(|field| { |
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.
Basically added support to look for fields in lookup_path (above in this file). it's used to check if the paths are valid in the config file.
So to link to a field (for example with struct X { y: u8 }: X::y.
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 is going to cause a problem. Fields and associated items can have the same name. You can add a Field variant to PathNS and constrain matches to that.
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.
Fair enough, added it as well.
eacd758 to
d017b2c
Compare
|
Finally updated all things that needed to be updated. :') |
|
This doesn't prevent reading via destructuring. e.g. |
|
r? @Jarcho |
|
Thanks for the review @Jarcho! Just a heads-up: gonna try to come back to this PR in the next days. |
| use rustc_hir::def_id::DefIdMap; | ||
| use rustc_hir::{Expr, ExprKind}; | ||
| use rustc_lint::{LateContext, LateLintPass}; | ||
| use rustc_middle::ty::{Adt, TyCtxt}; |
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.
nit: We don't normally import TyKind variants and use ty::Adt instead.
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.
Noted, removed the Adt import.
| // Very round-about way to get the field `DefId` from the expr: first we get its | ||
| // parent `Ty`. Then we go through all its fields to find the one with the expected | ||
| // name and get the `DefId` from it. | ||
| if let Some(parent_ty) = cx.typeck_results().expr_ty_opt(e) | ||
| && let Adt(adt_def, ..) = parent_ty.kind() | ||
| && let Some(field_def_id) = adt_def.all_fields().find_map(|field| { | ||
| if field.name == ident.name { | ||
| Some(field.did) | ||
| } else { | ||
| None | ||
| } | ||
| }) |
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.
There's get_field_by_name in clippy_utils for this.
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.
It returns a Ty and I need a DefId so sadly it doesn't work in this case.
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 extract this into it's own util function then. Something like get_field_def_by_name. It can join the other field resolving functions.
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.
Sure, done!
d017b2c to
ad311dc
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
It now checks patterns as well. I added UI tests to ensure it. Ready for a new review round. :) |
ad311dc to
50526ba
Compare
|
Forgot to check it was |
|
CI passed! \o/ |
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.
How are fields in a variant handled, especially homonyms?
| adt_def | ||
| .all_fields() | ||
| .find_map(|field| if field.name == name { Some(field.did) } else { None }) |
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 shares some code with the code in
check_pat(), maybe this could be factored further.
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.
Function is 4 lines so not sure if it's really worth it. I can add a fixme comment if someone wants to make this improvement later on though if you want?
Easy: they're not. :) |
Fixes #9278.
This is something that we need for
cg_gcc(cc @antoyo). It's almost the same as #6674 (which I used as base).changelog: Add new
disallowed_fieldslintr? @samueltardieu