mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Extend disallowed_fields lint on variant fields
This commit is contained in:
@@ -106,28 +106,55 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
|
||||
if let PatKind::Struct(struct_path, pat_fields, _) = pat.kind
|
||||
&& let Res::Def(DefKind::Struct, struct_def_id) = cx.typeck_results().qpath_res(&struct_path, pat.hir_id)
|
||||
{
|
||||
let adt_def = cx.tcx.adt_def(struct_def_id);
|
||||
for field in pat_fields {
|
||||
if let Some(def_id) = adt_def.all_fields().find_map(|adt_field| {
|
||||
if field.ident.name == adt_field.name {
|
||||
Some(adt_field.did)
|
||||
} else {
|
||||
None
|
||||
let PatKind::Struct(struct_path, pat_fields, _) = pat.kind else {
|
||||
return;
|
||||
};
|
||||
match cx.typeck_results().qpath_res(&struct_path, pat.hir_id) {
|
||||
Res::Def(DefKind::Struct, struct_def_id) => {
|
||||
let adt_def = cx.tcx.adt_def(struct_def_id);
|
||||
for field in pat_fields {
|
||||
if let Some(def_id) = adt_def.all_fields().find_map(|adt_field| {
|
||||
if field.ident.name == adt_field.name {
|
||||
Some(adt_field.did)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) && let Some(&(path, disallowed_path)) = self.disallowed.get(&def_id)
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
DISALLOWED_FIELDS,
|
||||
field.span,
|
||||
format!("use of a disallowed field `{path}`"),
|
||||
disallowed_path.diag_amendment(field.span),
|
||||
);
|
||||
}
|
||||
}) && let Some(&(path, disallowed_path)) = self.disallowed.get(&def_id)
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
DISALLOWED_FIELDS,
|
||||
field.span,
|
||||
format!("use of a disallowed field `{path}`"),
|
||||
disallowed_path.diag_amendment(field.span),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
Res::Def(DefKind::Variant, variant_def_id) => {
|
||||
let enum_def_id = cx.tcx.parent(variant_def_id);
|
||||
let variant = cx.tcx.adt_def(enum_def_id).variant_with_id(variant_def_id);
|
||||
|
||||
for field in pat_fields {
|
||||
if let Some(def_id) = variant.fields.iter().find_map(|adt_field| {
|
||||
if field.ident.name == adt_field.name {
|
||||
Some(adt_field.did)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) && let Some(&(path, disallowed_path)) = self.disallowed.get(&def_id)
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
DISALLOWED_FIELDS,
|
||||
field.span,
|
||||
format!("use of a disallowed field `{path}`"),
|
||||
disallowed_path.diag_amendment(field.span),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +288,20 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
|
||||
&root_mod
|
||||
},
|
||||
Node::Item(item) => &item.kind,
|
||||
Node::Variant(variant) if ns == PathNS::Field => {
|
||||
return if let rustc_hir::VariantData::Struct { fields, .. } = variant.data
|
||||
&& let Some(field_def_id) = fields.iter().find_map(|field| {
|
||||
if field.ident.name == name {
|
||||
Some(field.def_id.to_def_id())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
Some(field_def_id)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
@@ -330,6 +344,15 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
|
||||
}
|
||||
})
|
||||
},
|
||||
ItemKind::Enum(_, _, rustc_hir::EnumDef { variants }) if ns == PathNS::Type => {
|
||||
variants.iter().find_map(|variant| {
|
||||
if variant.ident.name == name {
|
||||
Some(variant.def_id.to_def_id())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,4 +9,6 @@ disallowed-fields = [
|
||||
"conf_disallowed_fields::X::y",
|
||||
# re-exports
|
||||
"conf_disallowed_fields::Y::y",
|
||||
# field of a variant
|
||||
"conf_disallowed_fields::Z::B::x",
|
||||
]
|
||||
|
||||
@@ -7,6 +7,11 @@ struct X {
|
||||
y: u32,
|
||||
}
|
||||
|
||||
enum Z {
|
||||
A { x: u32 },
|
||||
B { x: u32 },
|
||||
}
|
||||
|
||||
use crate::X as Y;
|
||||
|
||||
fn b(X { y }: X) {}
|
||||
@@ -36,4 +41,10 @@ fn main() {
|
||||
match x {
|
||||
RangeTo { end } => {}, //~ disallowed_fields
|
||||
}
|
||||
|
||||
let x = Z::B { x: 0 };
|
||||
match x {
|
||||
Z::A { x } => {},
|
||||
Z::B { x } => {}, //~ disallowed_fields
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error: use of a disallowed field `conf_disallowed_fields::Y::y`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:12:10
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:17:10
|
||||
|
|
||||
LL | fn b(X { y }: X) {}
|
||||
| ^
|
||||
@@ -8,25 +8,25 @@ LL | fn b(X { y }: X) {}
|
||||
= help: to override `-D warnings` add `#[allow(clippy::disallowed_fields)]`
|
||||
|
||||
error: use of a disallowed field `conf_disallowed_fields::Y::y`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:17:15
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:22:15
|
||||
|
|
||||
LL | let _ = x.y;
|
||||
| ^
|
||||
|
||||
error: use of a disallowed field `conf_disallowed_fields::Y::y`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:21:15
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:26:15
|
||||
|
|
||||
LL | let _ = x.y;
|
||||
| ^
|
||||
|
||||
error: use of a disallowed field `std::ops::Range::start`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:25:15
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:30:15
|
||||
|
|
||||
LL | let _ = x.start;
|
||||
| ^^^^^
|
||||
|
||||
error: use of a disallowed field `std::ops::Range::end`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:27:15
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:32:15
|
||||
|
|
||||
LL | let _ = x.end;
|
||||
| ^^^
|
||||
@@ -34,22 +34,28 @@ LL | let _ = x.end;
|
||||
= note: no end allowed
|
||||
|
||||
error: use of a disallowed field `std::ops::Range::start`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:29:17
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:34:17
|
||||
|
|
||||
LL | let Range { start, .. } = x;
|
||||
| ^^^^^
|
||||
|
||||
error: use of a disallowed field `std::ops::RangeTo::end`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:33:15
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:38:15
|
||||
|
|
||||
LL | let _ = x.end;
|
||||
| ^^^
|
||||
|
||||
error: use of a disallowed field `std::ops::RangeTo::end`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:37:19
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:42:19
|
||||
|
|
||||
LL | RangeTo { end } => {},
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: use of a disallowed field `conf_disallowed_fields::Z::B::x`
|
||||
--> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:48:16
|
||||
|
|
||||
LL | Z::B { x } => {},
|
||||
| ^
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user