Skip to content

Commit 6ce7609

Browse files
committed
Auto merge of #96745 - ehuss:even-more-attribute-validation, r=cjgillot
Visit attributes in more places. This adds 3 loosely related changes (I can split PRs if desired): - Attribute checking on pattern struct fields. - Attribute checking on struct expression fields. - Lint level visiting on pattern struct fields, struct expression fields, and generic parameters. There are still some lints which ignore lint levels in various positions. This is a consequence of how the lints themselves are implemented. For example, lint levels on associated consts don't work with `unused_braces`.
2 parents 80ed61f + 900a9d3 commit 6ce7609

File tree

23 files changed

+1520
-141
lines changed

23 files changed

+1520
-141
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1406,8 +1406,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
14061406
}
14071407

14081408
fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
1409+
let hir_id = self.lower_node_id(f.id);
1410+
self.lower_attrs(hir_id, &f.attrs);
14091411
hir::ExprField {
1410-
hir_id: self.next_id(),
1412+
hir_id,
14111413
ident: self.lower_ident(f.ident),
14121414
expr: self.lower_expr(&f.expr),
14131415
span: self.lower_span(f.span),

compiler/rustc_ast_lowering/src/index.rs

+14
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
199199
});
200200
}
201201

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+
202209
fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
203210
let node = Node::Arm(arm);
204211

@@ -225,6 +232,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
225232
});
226233
}
227234

235+
fn visit_expr_field(&mut self, field: &'hir ExprField<'hir>) {
236+
self.insert(field.span, field.hir_id, Node::ExprField(field));
237+
self.with_parent(field.hir_id, |this| {
238+
intravisit::walk_expr_field(this, field);
239+
});
240+
}
241+
228242
fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
229243
self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
230244

compiler/rustc_ast_lowering/src/pat.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6464
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
6565
);
6666

67-
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::PatField {
68-
hir_id: self.next_id(),
69-
ident: self.lower_ident(f.ident),
70-
pat: self.lower_pat(&f.pat),
71-
is_shorthand: f.is_shorthand,
72-
span: self.lower_span(f.span),
67+
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
68+
let hir_id = self.lower_node_id(f.id);
69+
self.lower_attrs(hir_id, &f.attrs);
70+
71+
hir::PatField {
72+
hir_id,
73+
ident: self.lower_ident(f.ident),
74+
pat: self.lower_pat(&f.pat),
75+
is_shorthand: f.is_shorthand,
76+
span: self.lower_span(f.span),
77+
}
7378
}));
7479
break hir::PatKind::Struct(qpath, fs, etc);
7580
}

compiler/rustc_hir/src/hir.rs

+4
Original file line numberDiff line numberDiff line change
@@ -3332,12 +3332,14 @@ pub enum Node<'hir> {
33323332
Field(&'hir FieldDef<'hir>),
33333333
AnonConst(&'hir AnonConst),
33343334
Expr(&'hir Expr<'hir>),
3335+
ExprField(&'hir ExprField<'hir>),
33353336
Stmt(&'hir Stmt<'hir>),
33363337
PathSegment(&'hir PathSegment<'hir>),
33373338
Ty(&'hir Ty<'hir>),
33383339
TypeBinding(&'hir TypeBinding<'hir>),
33393340
TraitRef(&'hir TraitRef<'hir>),
33403341
Pat(&'hir Pat<'hir>),
3342+
PatField(&'hir PatField<'hir>),
33413343
Arm(&'hir Arm<'hir>),
33423344
Block(&'hir Block<'hir>),
33433345
Local(&'hir Local<'hir>),
@@ -3388,6 +3390,8 @@ impl<'hir> Node<'hir> {
33883390
| Node::Block(..)
33893391
| Node::Ctor(..)
33903392
| Node::Pat(..)
3393+
| Node::PatField(..)
3394+
| Node::ExprField(..)
33913395
| Node::Arm(..)
33923396
| Node::Local(..)
33933397
| Node::Crate(..)

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_hir/src/target.rs

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ pub enum Target {
5656
GenericParam(GenericParamKind),
5757
MacroDef,
5858
Param,
59+
PatField,
60+
ExprField,
5961
}
6062

6163
impl Display for Target {
@@ -183,6 +185,8 @@ impl Target {
183185
},
184186
Target::MacroDef => "macro def",
185187
Target::Param => "function param",
188+
Target::PatField => "pattern field",
189+
Target::ExprField => "struct field",
186190
}
187191
}
188192
}

compiler/rustc_hir_pretty/src/lib.rs

+32-28
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,14 @@ impl<'a> State<'a> {
8383
Node::Variant(a) => self.print_variant(a),
8484
Node::AnonConst(a) => self.print_anon_const(a),
8585
Node::Expr(a) => self.print_expr(a),
86+
Node::ExprField(a) => self.print_expr_field(&a),
8687
Node::Stmt(a) => self.print_stmt(a),
8788
Node::PathSegment(a) => self.print_path_segment(a),
8889
Node::Ty(a) => self.print_type(a),
8990
Node::TypeBinding(a) => self.print_type_binding(a),
9091
Node::TraitRef(a) => self.print_trait_ref(a),
9192
Node::Pat(a) => self.print_pat(a),
93+
Node::PatField(a) => self.print_patfield(&a),
9294
Node::Arm(a) => self.print_arm(a),
9395
Node::Infer(_) => self.word("_"),
9496
Node::Block(a) => {
@@ -1127,20 +1129,7 @@ impl<'a> State<'a> {
11271129
) {
11281130
self.print_qpath(qpath, true);
11291131
self.word("{");
1130-
self.commasep_cmnt(
1131-
Consistent,
1132-
fields,
1133-
|s, field| {
1134-
s.ibox(INDENT_UNIT);
1135-
if !field.is_shorthand {
1136-
s.print_ident(field.ident);
1137-
s.word_space(":");
1138-
}
1139-
s.print_expr(field.expr);
1140-
s.end()
1141-
},
1142-
|f| f.span,
1143-
);
1132+
self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span);
11441133
if let Some(expr) = wth {
11451134
self.ibox(INDENT_UNIT);
11461135
if !fields.is_empty() {
@@ -1157,6 +1146,20 @@ impl<'a> State<'a> {
11571146
self.word("}");
11581147
}
11591148

1149+
fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
1150+
if self.attrs(field.hir_id).is_empty() {
1151+
self.space();
1152+
}
1153+
self.cbox(INDENT_UNIT);
1154+
self.print_outer_attributes(&self.attrs(field.hir_id));
1155+
if !field.is_shorthand {
1156+
self.print_ident(field.ident);
1157+
self.word_space(":");
1158+
}
1159+
self.print_expr(&field.expr);
1160+
self.end()
1161+
}
1162+
11601163
fn print_expr_tup(&mut self, exprs: &[hir::Expr<'_>]) {
11611164
self.popen();
11621165
self.commasep_exprs(Inconsistent, exprs);
@@ -1803,20 +1806,7 @@ impl<'a> State<'a> {
18031806
if !empty {
18041807
self.space();
18051808
}
1806-
self.commasep_cmnt(
1807-
Consistent,
1808-
fields,
1809-
|s, f| {
1810-
s.cbox(INDENT_UNIT);
1811-
if !f.is_shorthand {
1812-
s.print_ident(f.ident);
1813-
s.word_nbsp(":");
1814-
}
1815-
s.print_pat(f.pat);
1816-
s.end()
1817-
},
1818-
|f| f.pat.span,
1819-
);
1809+
self.commasep_cmnt(Consistent, &fields, |s, f| s.print_patfield(f), |f| f.pat.span);
18201810
if etc {
18211811
if !fields.is_empty() {
18221812
self.word_space(",");
@@ -1911,6 +1901,20 @@ impl<'a> State<'a> {
19111901
self.ann.post(self, AnnNode::Pat(pat))
19121902
}
19131903

1904+
pub fn print_patfield(&mut self, field: &hir::PatField<'_>) {
1905+
if self.attrs(field.hir_id).is_empty() {
1906+
self.space();
1907+
}
1908+
self.cbox(INDENT_UNIT);
1909+
self.print_outer_attributes(&self.attrs(field.hir_id));
1910+
if !field.is_shorthand {
1911+
self.print_ident(field.ident);
1912+
self.word_nbsp(":");
1913+
}
1914+
self.print_pat(field.pat);
1915+
self.end();
1916+
}
1917+
19141918
pub fn print_param(&mut self, arg: &hir::Param<'_>) {
19151919
self.print_outer_attributes(self.attrs(arg.hir_id));
19161920
self.print_pat(arg.pat);

compiler/rustc_lint/src/early.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
101101
run_early_pass!(self, check_pat_post, p);
102102
}
103103

104+
fn visit_pat_field(&mut self, field: &'a ast::PatField) {
105+
self.with_lint_attrs(field.id, &field.attrs, |cx| {
106+
ast_visit::walk_pat_field(cx, field);
107+
});
108+
}
109+
104110
fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
105111
self.check_id(c.id);
106112
ast_visit::walk_anon_const(self, c);
@@ -219,9 +225,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
219225
}
220226

221227
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
222-
run_early_pass!(self, check_generic_param, param);
223-
self.check_id(param.id);
224-
ast_visit::walk_generic_param(self, param);
228+
self.with_lint_attrs(param.id, &param.attrs, |cx| {
229+
run_early_pass!(cx, check_generic_param, param);
230+
ast_visit::walk_generic_param(cx, param);
231+
});
225232
}
226233

227234
fn visit_generics(&mut self, g: &'a ast::Generics) {

compiler/rustc_lint/src/levels.rs

+18
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
766766
})
767767
}
768768

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+
})
773+
}
774+
769775
fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
770776
self.with_lint_attrs(s.hir_id, |builder| {
771777
intravisit::walk_field_def(builder, s);
@@ -801,6 +807,18 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
801807
intravisit::walk_impl_item(builder, impl_item);
802808
});
803809
}
810+
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+
})
815+
}
816+
817+
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
818+
self.with_lint_attrs(p.hir_id, |builder| {
819+
intravisit::walk_generic_param(builder, p);
820+
});
821+
}
804822
}
805823

806824
pub fn provide(providers: &mut Providers) {

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
}

0 commit comments

Comments
 (0)