Skip to content

Commit dcd5177

Browse files
committed
Add visitors for PatField and ExprField.
This helps simplify the code. It also fixes it to use the correct parent when lowering. One consequence is the `non_snake_case` lint needed to change the way it looked for parent nodes in a struct pattern. This also includes a small fix to use the correct `Target` for expression field attribute validation.
1 parent 6c7cb2b commit dcd5177

File tree

6 files changed

+55
-73
lines changed

6 files changed

+55
-73
lines changed

compiler/rustc_ast_lowering/src/index.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,19 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
193193

194194
fn visit_pat(&mut self, pat: &'hir Pat<'hir>) {
195195
self.insert(pat.span, pat.hir_id, Node::Pat(pat));
196-
if let PatKind::Struct(_, fields, _) = pat.kind {
197-
for field in fields {
198-
self.insert(field.span, field.hir_id, Node::PatField(field));
199-
}
200-
}
201196

202197
self.with_parent(pat.hir_id, |this| {
203198
intravisit::walk_pat(this, pat);
204199
});
205200
}
206201

202+
fn visit_pat_field(&mut self, field: &'hir PatField<'hir>) {
203+
self.insert(field.span, field.hir_id, Node::PatField(field));
204+
self.with_parent(field.hir_id, |this| {
205+
intravisit::walk_pat_field(this, field);
206+
});
207+
}
208+
207209
fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
208210
let node = Node::Arm(arm);
209211

compiler/rustc_hir/src/intravisit.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ pub trait Visitor<'v>: Sized {
325325
fn visit_pat(&mut self, p: &'v Pat<'v>) {
326326
walk_pat(self, p)
327327
}
328+
fn visit_pat_field(&mut self, f: &'v PatField<'v>) {
329+
walk_pat_field(self, f)
330+
}
328331
fn visit_array_length(&mut self, len: &'v ArrayLen) {
329332
walk_array_len(self, len)
330333
}
@@ -337,6 +340,9 @@ pub trait Visitor<'v>: Sized {
337340
fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
338341
walk_let_expr(self, lex)
339342
}
343+
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
344+
walk_expr_field(self, field)
345+
}
340346
fn visit_ty(&mut self, t: &'v Ty<'v>) {
341347
walk_ty(self, t)
342348
}
@@ -761,11 +767,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
761767
}
762768
PatKind::Struct(ref qpath, fields, _) => {
763769
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
764-
for field in fields {
765-
visitor.visit_id(field.hir_id);
766-
visitor.visit_ident(field.ident);
767-
visitor.visit_pat(&field.pat)
768-
}
770+
walk_list!(visitor, visit_pat_field, fields);
769771
}
770772
PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats),
771773
PatKind::Tuple(tuple_elements, _) => {
@@ -792,6 +794,12 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
792794
}
793795
}
794796

797+
pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
798+
visitor.visit_id(field.hir_id);
799+
visitor.visit_ident(field.ident);
800+
visitor.visit_pat(&field.pat)
801+
}
802+
795803
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
796804
visitor.visit_id(foreign_item.hir_id());
797805
visitor.visit_ident(foreign_item.ident);
@@ -1059,6 +1067,12 @@ pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>)
10591067
walk_list!(visitor, visit_ty, let_expr.ty);
10601068
}
10611069

1070+
pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
1071+
visitor.visit_id(field.hir_id);
1072+
visitor.visit_ident(field.ident);
1073+
visitor.visit_expr(&field.expr)
1074+
}
1075+
10621076
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
10631077
visitor.visit_id(expression.hir_id);
10641078
match expression.kind {
@@ -1073,11 +1087,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
10731087
}
10741088
ExprKind::Struct(ref qpath, fields, ref optional_base) => {
10751089
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
1076-
for field in fields {
1077-
visitor.visit_id(field.hir_id);
1078-
visitor.visit_ident(field.ident);
1079-
visitor.visit_expr(&field.expr)
1080-
}
1090+
walk_list!(visitor, visit_expr_field, fields);
10811091
walk_list!(visitor, visit_expr, optional_base);
10821092
}
10831093
ExprKind::Tup(subexpressions) => {

compiler/rustc_lint/src/levels.rs

+13-34
Original file line numberDiff line numberDiff line change
@@ -761,26 +761,15 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
761761
}
762762

763763
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
764-
match e.kind {
765-
hir::ExprKind::Struct(qpath, fields, base_expr) => {
766-
self.with_lint_attrs(e.hir_id, |builder| {
767-
builder.visit_qpath(qpath, e.hir_id, e.span);
768-
for field in fields {
769-
builder.with_lint_attrs(field.hir_id, |field_builder| {
770-
field_builder.visit_id(field.hir_id);
771-
field_builder.visit_ident(field.ident);
772-
field_builder.visit_expr(field.expr);
773-
});
774-
}
775-
if let Some(base_expr) = base_expr {
776-
builder.visit_expr(base_expr);
777-
}
778-
});
779-
}
780-
_ => self.with_lint_attrs(e.hir_id, |builder| {
781-
intravisit::walk_expr(builder, e);
782-
}),
783-
}
764+
self.with_lint_attrs(e.hir_id, |builder| {
765+
intravisit::walk_expr(builder, e);
766+
})
767+
}
768+
769+
fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
770+
self.with_lint_attrs(field.hir_id, |builder| {
771+
intravisit::walk_expr_field(builder, field);
772+
})
784773
}
785774

786775
fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
@@ -819,20 +808,10 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
819808
});
820809
}
821810

822-
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
823-
match &p.kind {
824-
hir::PatKind::Struct(qpath, fields, _) => {
825-
self.visit_qpath(&qpath, p.hir_id, p.span);
826-
for field in *fields {
827-
self.with_lint_attrs(field.hir_id, |builder| {
828-
builder.visit_id(field.hir_id);
829-
builder.visit_ident(field.ident);
830-
builder.visit_pat(field.pat);
831-
})
832-
}
833-
}
834-
_ => intravisit::walk_pat(self, p),
835-
}
811+
fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
812+
self.with_lint_attrs(field.hir_id, |builder| {
813+
intravisit::walk_pat_field(builder, field);
814+
})
836815
}
837816

838817
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {

compiler/rustc_lint/src/nonstandard_style.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -437,19 +437,14 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
437437

438438
fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
439439
if let PatKind::Binding(_, hid, ident, _) = p.kind {
440-
if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
440+
if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
441441
{
442-
if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind {
443-
if field_pats
444-
.iter()
445-
.any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id)
446-
{
447-
// Only check if a new name has been introduced, to avoid warning
448-
// on both the struct definition and this pattern.
449-
self.check_snake_case(cx, "variable", &ident);
450-
}
451-
return;
442+
if !field.is_shorthand {
443+
// Only check if a new name has been introduced, to avoid warning
444+
// on both the struct definition and this pattern.
445+
self.check_snake_case(cx, "variable", &ident);
452446
}
447+
return;
453448
}
454449
self.check_snake_case(cx, "variable", &ident);
455450
}

compiler/rustc_passes/src/check_attr.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -2065,14 +2065,14 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
20652065
};
20662066

20672067
self.check_attributes(expr.hir_id, expr.span, target, None);
2068-
if let hir::ExprKind::Struct(_, fields, _) = expr.kind {
2069-
for field in fields {
2070-
self.check_attributes(field.hir_id, field.span, Target::PatField, None);
2071-
}
2072-
}
20732068
intravisit::walk_expr(self, expr)
20742069
}
20752070

2071+
fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
2072+
self.check_attributes(field.hir_id, field.span, Target::ExprField, None);
2073+
intravisit::walk_expr_field(self, field)
2074+
}
2075+
20762076
fn visit_variant(&mut self, variant: &'tcx hir::Variant<'tcx>) {
20772077
self.check_attributes(variant.id, variant.span, Target::Variant, None);
20782078
intravisit::walk_variant(self, variant)
@@ -2084,13 +2084,9 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
20842084
intravisit::walk_param(self, param);
20852085
}
20862086

2087-
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
2088-
if let hir::PatKind::Struct(_, fields, _) = p.kind {
2089-
for field in fields {
2090-
self.check_attributes(field.hir_id, field.span, Target::PatField, None);
2091-
}
2092-
}
2093-
intravisit::walk_pat(self, p);
2087+
fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
2088+
self.check_attributes(field.hir_id, field.span, Target::PatField, None);
2089+
intravisit::walk_pat_field(self, field);
20942090
}
20952091
}
20962092

src/test/ui/lint/unused/unused_attributes-must_use.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ error: `#[must_use]` has no effect when applied to an match arm
105105
LL | #[must_use]
106106
| ^^^^^^^^^^^
107107

108-
error: `#[must_use]` has no effect when applied to a pattern field
108+
error: `#[must_use]` has no effect when applied to a struct field
109109
--> $DIR/unused_attributes-must_use.rs:129:28
110110
|
111111
LL | let s = PatternField { #[must_use] foo: 123 };

0 commit comments

Comments
 (0)