diff options
| author | bors <bors@rust-lang.org> | 2022-08-15 05:50:54 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-15 05:50:54 +0000 |
| commit | 6ce76091c7cef21692a15dce1f0a4c415d245be4 (patch) | |
| tree | c41de2e296638ec3db9cb8db375fd857da3a8737 /compiler/rustc_lint | |
| parent | 80ed61fbd64936ed676c2050e7e660b5ad78c9f2 (diff) | |
| parent | 900a9d3f4e80315b1fccd909336febede92503ed (diff) | |
| download | rust-6ce76091c7cef21692a15dce1f0a4c415d245be4.tar.gz rust-6ce76091c7cef21692a15dce1f0a4c415d245be4.zip | |
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`.
Diffstat (limited to 'compiler/rustc_lint')
| -rw-r--r-- | compiler/rustc_lint/src/early.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/nonstandard_style.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/types.rs | 98 |
4 files changed, 81 insertions, 65 deletions
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index cbf1a677555..580a4566869 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -101,6 +101,12 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> run_early_pass!(self, check_pat_post, p); } + fn visit_pat_field(&mut self, field: &'a ast::PatField) { + self.with_lint_attrs(field.id, &field.attrs, |cx| { + ast_visit::walk_pat_field(cx, field); + }); + } + fn visit_anon_const(&mut self, c: &'a ast::AnonConst) { self.check_id(c.id); ast_visit::walk_anon_const(self, c); @@ -219,9 +225,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_generic_param(&mut self, param: &'a ast::GenericParam) { - run_early_pass!(self, check_generic_param, param); - self.check_id(param.id); - ast_visit::walk_generic_param(self, param); + self.with_lint_attrs(param.id, ¶m.attrs, |cx| { + run_early_pass!(cx, check_generic_param, param); + ast_visit::walk_generic_param(cx, param); + }); } fn visit_generics(&mut self, g: &'a ast::Generics) { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 7ab9302d835..1cabb58bbeb 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -766,6 +766,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { }) } + fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) { + self.with_lint_attrs(field.hir_id, |builder| { + intravisit::walk_expr_field(builder, field); + }) + } + fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { self.with_lint_attrs(s.hir_id, |builder| { intravisit::walk_field_def(builder, s); @@ -801,6 +807,18 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { intravisit::walk_impl_item(builder, impl_item); }); } + + fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) { + self.with_lint_attrs(field.hir_id, |builder| { + intravisit::walk_pat_field(builder, field); + }) + } + + fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { + self.with_lint_attrs(p.hir_id, |builder| { + intravisit::walk_generic_param(builder, p); + }); + } } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 8d04d68bf1c..2868aabfa07 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -437,19 +437,14 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) { if let PatKind::Binding(_, hid, ident, _) = p.kind { - if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) + if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) { - if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind { - if field_pats - .iter() - .any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id) - { - // Only check if a new name has been introduced, to avoid warning - // on both the struct definition and this pattern. - self.check_snake_case(cx, "variable", &ident); - } - return; + if !field.is_shorthand { + // Only check if a new name has been introduced, to avoid warning + // on both the struct definition and this pattern. + self.check_snake_case(cx, "variable", &ident); } + return; } self.check_snake_case(cx, "variable", &ident); } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 5c07afeb7aa..cafd2c6e679 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -125,45 +125,51 @@ fn lint_overflowing_range_endpoint<'tcx>( lit_val: u128, max: u128, expr: &'tcx hir::Expr<'tcx>, - parent_expr: &'tcx hir::Expr<'tcx>, ty: &str, ) -> bool { // We only want to handle exclusive (`..`) ranges, // which are represented as `ExprKind::Struct`. + let par_id = cx.tcx.hir().get_parent_node(expr.hir_id); + let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false }; + let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id); + let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false }; + if !is_range_literal(struct_expr) { + return false; + }; + let ExprKind::Struct(_, eps, _) = &struct_expr.kind else { return false }; + if eps.len() != 2 { + return false; + } + let mut overwritten = false; - if let ExprKind::Struct(_, eps, _) = &parent_expr.kind { - if eps.len() != 2 { - return false; - } - // We can suggest using an inclusive range - // (`..=`) instead only if it is the `end` that is - // overflowing and only by 1. - if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max { - cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| { - let mut err = lint.build(fluent::lint::range_endpoint_out_of_range); - err.set_arg("ty", ty); - if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) { - use ast::{LitIntType, LitKind}; - // We need to preserve the literal's suffix, - // as it may determine typing information. - let suffix = match lit.node { - LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(), - LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(), - LitKind::Int(_, LitIntType::Unsuffixed) => "", - _ => bug!(), - }; - let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix); - err.span_suggestion( - parent_expr.span, - fluent::lint::suggestion, - suggestion, - Applicability::MachineApplicable, - ); - err.emit(); - overwritten = true; - } - }); - } + // We can suggest using an inclusive range + // (`..=`) instead only if it is the `end` that is + // overflowing and only by 1. + if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max { + cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| { + let mut err = lint.build(fluent::lint::range_endpoint_out_of_range); + err.set_arg("ty", ty); + if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) { + use ast::{LitIntType, LitKind}; + // We need to preserve the literal's suffix, + // as it may determine typing information. + let suffix = match lit.node { + LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(), + LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(), + LitKind::Int(_, LitIntType::Unsuffixed) => "", + _ => bug!(), + }; + let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix); + err.span_suggestion( + struct_expr.span, + fluent::lint::suggestion, + suggestion, + Applicability::MachineApplicable, + ); + err.emit(); + overwritten = true; + } + }); } overwritten } @@ -339,16 +345,9 @@ fn lint_int_literal<'tcx>( return; } - let par_id = cx.tcx.hir().get_parent_node(e.hir_id); - if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) { - if let hir::ExprKind::Struct(..) = par_e.kind { - if is_range_literal(par_e) - && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str()) - { - // The overflowing literal lint was overridden. - return; - } - } + if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) { + // The overflowing literal lint was overridden. + return; } cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { @@ -408,16 +407,13 @@ fn lint_uint_literal<'tcx>( return; } } - hir::ExprKind::Struct(..) if is_range_literal(par_e) => { - let t = t.name_str(); - if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) { - // The overflowing literal lint was overridden. - return; - } - } _ => {} } } + if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) { + // The overflowing literal lint was overridden. + return; + } if let Some(repr_str) = get_bin_hex_repr(cx, lit) { report_bin_hex_error( cx, |
