diff options
| author | Urgau <urgau@numericable.fr> | 2025-06-17 23:27:06 +0200 |
|---|---|---|
| committer | Urgau <urgau@numericable.fr> | 2025-06-18 00:06:37 +0200 |
| commit | 42bb66add31d196bb8d0f0bfb79a00dfd2cad55b (patch) | |
| tree | 3e9ed8a4221ed03888393ac9b2448acf5c2eeb34 /compiler/rustc_lint/src | |
| parent | 994794a50bd4adfd7f0351872206e170c1bc8d58 (diff) | |
| download | rust-42bb66add31d196bb8d0f0bfb79a00dfd2cad55b.tar.gz rust-42bb66add31d196bb8d0f0bfb79a00dfd2cad55b.zip | |
Also emit suggestions for usages in the `non_upper_case_globals` lint
Diffstat (limited to 'compiler/rustc_lint/src')
| -rw-r--r-- | compiler/rustc_lint/src/lints.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/nonstandard_style.rs | 77 |
2 files changed, 68 insertions, 11 deletions
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 3d17dfbc451..d157bf6986c 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1348,6 +1348,8 @@ pub(crate) struct NonUpperCaseGlobal<'a> { pub name: &'a str, #[subdiagnostic] pub sub: NonUpperCaseGlobalSub, + #[subdiagnostic] + pub usages: Vec<NonUpperCaseGlobalSub>, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 1b60466a589..a5b3eb3f0ff 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -2,8 +2,9 @@ use rustc_abi::ExternAbi; use rustc_attr_data_structures::{AttributeKind, ReprAttr}; use rustc_attr_parsing::AttributeParser; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::intravisit::FnKind; +use rustc_hir::intravisit::{FnKind, Visitor}; use rustc_hir::{AttrArgs, AttrItem, Attribute, GenericParamKind, PatExprKind, PatKind}; +use rustc_middle::hir::nested_filter::All; use rustc_middle::ty; use rustc_session::config::CrateType; use rustc_session::{declare_lint, declare_lint_pass}; @@ -489,21 +490,59 @@ declare_lint! { declare_lint_pass!(NonUpperCaseGlobals => [NON_UPPER_CASE_GLOBALS]); impl NonUpperCaseGlobals { - fn check_upper_case(cx: &LateContext<'_>, sort: &str, ident: &Ident) { + fn check_upper_case(cx: &LateContext<'_>, sort: &str, did: Option<LocalDefId>, ident: &Ident) { let name = ident.name.as_str(); if name.chars().any(|c| c.is_lowercase()) { let uc = NonSnakeCase::to_snake_case(name).to_uppercase(); + // We cannot provide meaningful suggestions // if the characters are in the category of "Lowercase Letter". - let sub = if *name != uc { - NonUpperCaseGlobalSub::Suggestion { span: ident.span, replace: uc } + let sub = |span| { + if *name != uc { + NonUpperCaseGlobalSub::Suggestion { span, replace: uc.clone() } + } else { + NonUpperCaseGlobalSub::Label { span } + } + }; + + struct UsageCollector<'a, 'tcx> { + cx: &'tcx LateContext<'a>, + did: LocalDefId, + collected: Vec<Span>, + } + + impl<'v, 'tcx> Visitor<'v> for UsageCollector<'v, 'tcx> { + type NestedFilter = All; + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx + } + + fn visit_path( + &mut self, + path: &rustc_hir::Path<'v>, + _id: rustc_hir::HirId, + ) -> Self::Result { + for seg in path.segments { + if seg.res.opt_def_id() == Some(self.did.to_def_id()) { + self.collected.push(seg.ident.span); + } + } + } + } + + let usages = if let Some(did) = did { + let mut usage_collector = UsageCollector { cx, did, collected: Vec::new() }; + cx.tcx.hir_walk_toplevel_module(&mut usage_collector); + usage_collector.collected.into_iter().map(|span| sub(span)).collect() } else { - NonUpperCaseGlobalSub::Label { span: ident.span } + vec![] }; + cx.emit_span_lint( NON_UPPER_CASE_GLOBALS, ident.span, - NonUpperCaseGlobal { sort, name, sub }, + NonUpperCaseGlobal { sort, name, sub: sub(ident.span), usages }, ); } } @@ -516,10 +555,20 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { hir::ItemKind::Static(_, ident, ..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { - NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident); + NonUpperCaseGlobals::check_upper_case( + cx, + "static variable", + Some(it.owner_id.def_id), + &ident, + ); } hir::ItemKind::Const(ident, ..) => { - NonUpperCaseGlobals::check_upper_case(cx, "constant", &ident); + NonUpperCaseGlobals::check_upper_case( + cx, + "constant", + Some(it.owner_id.def_id), + &ident, + ); } _ => {} } @@ -527,7 +576,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_trait_item(&mut self, cx: &LateContext<'_>, ti: &hir::TraitItem<'_>) { if let hir::TraitItemKind::Const(..) = ti.kind { - NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ti.ident); + NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ti.ident); } } @@ -535,7 +584,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { if let hir::ImplItemKind::Const(..) = ii.kind && !assoc_item_in_trait_impl(cx, ii) { - NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident); + NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ii.ident); } } @@ -551,6 +600,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { NonUpperCaseGlobals::check_upper_case( cx, "constant in pattern", + None, &segment.ident, ); } @@ -560,7 +610,12 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_generic_param(&mut self, cx: &LateContext<'_>, param: &hir::GenericParam<'_>) { if let GenericParamKind::Const { .. } = param.kind { - NonUpperCaseGlobals::check_upper_case(cx, "const parameter", ¶m.name.ident()); + NonUpperCaseGlobals::check_upper_case( + cx, + "const parameter", + Some(param.def_id), + ¶m.name.ident(), + ); } } } |
