Skip to content

Commit 5aafa84

Browse files
Auto merge of #142645 - Urgau:usage-non_upper_case_globals, r=<try>
Also emit suggestions for usages in the `non_upper_case_globals` lint This PR adds suggestions for all the usages of the renamed item in the warning of the `non_upper_case_globals` lint. Fixes #124061
2 parents df4ad9e + 3939316 commit 5aafa84

File tree

5 files changed

+220
-11
lines changed

5 files changed

+220
-11
lines changed

compiler/rustc_lint/src/lints.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,8 @@ pub(crate) struct NonUpperCaseGlobal<'a> {
13531353
pub name: &'a str,
13541354
#[subdiagnostic]
13551355
pub sub: NonUpperCaseGlobalSub,
1356+
#[subdiagnostic]
1357+
pub usages: NonUpperCaseGlobalSubToolsLazy<'a>,
13561358
}
13571359

13581360
#[derive(Subdiagnostic)]
@@ -1362,14 +1364,40 @@ pub(crate) enum NonUpperCaseGlobalSub {
13621364
#[primary_span]
13631365
span: Span,
13641366
},
1365-
#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1367+
#[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
13661368
Suggestion {
13671369
#[primary_span]
13681370
span: Span,
13691371
replace: String,
13701372
},
13711373
}
13721374

1375+
pub(crate) struct NonUpperCaseGlobalSubToolsLazy<'a> {
1376+
pub usages: &'a dyn Fn() -> Vec<NonUpperCaseGlobalSubTool>,
1377+
}
1378+
1379+
impl<'a> Subdiagnostic for NonUpperCaseGlobalSubToolsLazy<'a> {
1380+
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1381+
let usages = (&self.usages)();
1382+
for usage in usages {
1383+
diag.subdiagnostic(usage);
1384+
}
1385+
}
1386+
}
1387+
1388+
#[derive(Subdiagnostic)]
1389+
#[suggestion(
1390+
lint_suggestion,
1391+
code = "{replace}",
1392+
applicability = "machine-applicable",
1393+
style = "tool-only"
1394+
)]
1395+
pub(crate) struct NonUpperCaseGlobalSubTool {
1396+
#[primary_span]
1397+
pub(crate) span: Span,
1398+
pub(crate) replace: String,
1399+
}
1400+
13731401
// noop_method_call.rs
13741402
#[derive(LintDiagnostic)]
13751403
#[diag(lint_noop_method_call)]

compiler/rustc_lint/src/nonstandard_style.rs

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use rustc_abi::ExternAbi;
22
use rustc_attr_data_structures::{AttributeKind, ReprAttr};
33
use rustc_attr_parsing::AttributeParser;
44
use rustc_hir::def::{DefKind, Res};
5-
use rustc_hir::intravisit::FnKind;
5+
use rustc_hir::intravisit::{FnKind, Visitor};
66
use rustc_hir::{AttrArgs, AttrItem, Attribute, GenericParamKind, PatExprKind, PatKind};
7+
use rustc_middle::hir::nested_filter::All;
78
use rustc_middle::ty;
89
use rustc_session::config::CrateType;
910
use rustc_session::{declare_lint, declare_lint_pass};
@@ -13,7 +14,8 @@ use {rustc_ast as ast, rustc_hir as hir};
1314

1415
use crate::lints::{
1516
NonCamelCaseType, NonCamelCaseTypeSub, NonSnakeCaseDiag, NonSnakeCaseDiagSub,
16-
NonUpperCaseGlobal, NonUpperCaseGlobalSub,
17+
NonUpperCaseGlobal, NonUpperCaseGlobalSub, NonUpperCaseGlobalSubTool,
18+
NonUpperCaseGlobalSubToolsLazy,
1719
};
1820
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
1921

@@ -489,21 +491,67 @@ declare_lint! {
489491
declare_lint_pass!(NonUpperCaseGlobals => [NON_UPPER_CASE_GLOBALS]);
490492

491493
impl NonUpperCaseGlobals {
492-
fn check_upper_case(cx: &LateContext<'_>, sort: &str, ident: &Ident) {
494+
fn check_upper_case(cx: &LateContext<'_>, sort: &str, did: Option<LocalDefId>, ident: &Ident) {
493495
let name = ident.name.as_str();
494496
if name.chars().any(|c| c.is_lowercase()) {
495497
let uc = NonSnakeCase::to_snake_case(name).to_uppercase();
498+
496499
// We cannot provide meaningful suggestions
497500
// if the characters are in the category of "Lowercase Letter".
498501
let sub = if *name != uc {
499-
NonUpperCaseGlobalSub::Suggestion { span: ident.span, replace: uc }
502+
NonUpperCaseGlobalSub::Suggestion { span: ident.span, replace: uc.clone() }
500503
} else {
501504
NonUpperCaseGlobalSub::Label { span: ident.span }
502505
};
506+
507+
struct UsageCollector<'a, 'tcx> {
508+
cx: &'tcx LateContext<'a>,
509+
did: LocalDefId,
510+
collected: Vec<Span>,
511+
}
512+
513+
impl<'v, 'tcx> Visitor<'v> for UsageCollector<'v, 'tcx> {
514+
type NestedFilter = All;
515+
516+
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
517+
self.cx.tcx
518+
}
519+
520+
fn visit_path(
521+
&mut self,
522+
path: &rustc_hir::Path<'v>,
523+
_id: rustc_hir::HirId,
524+
) -> Self::Result {
525+
for seg in path.segments {
526+
if seg.res.opt_def_id() == Some(self.did.to_def_id()) {
527+
self.collected.push(seg.ident.span);
528+
}
529+
}
530+
}
531+
}
532+
533+
let usages = NonUpperCaseGlobalSubToolsLazy {
534+
usages: &|| {
535+
if let Some(did) = did
536+
&& *name != uc
537+
{
538+
let mut usage_collector = UsageCollector { cx, did, collected: Vec::new() };
539+
cx.tcx.hir_walk_toplevel_module(&mut usage_collector);
540+
usage_collector
541+
.collected
542+
.into_iter()
543+
.map(|span| NonUpperCaseGlobalSubTool { span, replace: uc.clone() })
544+
.collect()
545+
} else {
546+
vec![]
547+
}
548+
},
549+
};
550+
503551
cx.emit_span_lint(
504552
NON_UPPER_CASE_GLOBALS,
505553
ident.span,
506-
NonUpperCaseGlobal { sort, name, sub },
554+
NonUpperCaseGlobal { sort, name, sub, usages },
507555
);
508556
}
509557
}
@@ -516,26 +564,36 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
516564
hir::ItemKind::Static(_, ident, ..)
517565
if !ast::attr::contains_name(attrs, sym::no_mangle) =>
518566
{
519-
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident);
567+
NonUpperCaseGlobals::check_upper_case(
568+
cx,
569+
"static variable",
570+
Some(it.owner_id.def_id),
571+
&ident,
572+
);
520573
}
521574
hir::ItemKind::Const(ident, ..) => {
522-
NonUpperCaseGlobals::check_upper_case(cx, "constant", &ident);
575+
NonUpperCaseGlobals::check_upper_case(
576+
cx,
577+
"constant",
578+
Some(it.owner_id.def_id),
579+
&ident,
580+
);
523581
}
524582
_ => {}
525583
}
526584
}
527585

528586
fn check_trait_item(&mut self, cx: &LateContext<'_>, ti: &hir::TraitItem<'_>) {
529587
if let hir::TraitItemKind::Const(..) = ti.kind {
530-
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ti.ident);
588+
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ti.ident);
531589
}
532590
}
533591

534592
fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
535593
if let hir::ImplItemKind::Const(..) = ii.kind
536594
&& !assoc_item_in_trait_impl(cx, ii)
537595
{
538-
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident);
596+
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ii.ident);
539597
}
540598
}
541599

@@ -551,6 +609,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
551609
NonUpperCaseGlobals::check_upper_case(
552610
cx,
553611
"constant in pattern",
612+
None,
554613
&segment.ident,
555614
);
556615
}
@@ -560,7 +619,12 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
560619

561620
fn check_generic_param(&mut self, cx: &LateContext<'_>, param: &hir::GenericParam<'_>) {
562621
if let GenericParamKind::Const { .. } = param.kind {
563-
NonUpperCaseGlobals::check_upper_case(cx, "const parameter", &param.name.ident());
622+
NonUpperCaseGlobals::check_upper_case(
623+
cx,
624+
"const parameter",
625+
Some(param.def_id),
626+
&param.name.ident(),
627+
);
564628
}
565629
}
566630
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Checks that the `non_upper_case_globals` emits suggestions for usages as well
2+
// <https://github.com/rust-lang/rust/issues/124061>
3+
4+
//@ check-pass
5+
//@ run-rustfix
6+
7+
#![allow(dead_code)]
8+
9+
use std::cell::Cell;
10+
11+
const MY_STATIC: u32 = 0;
12+
//~^ WARN constant `my_static` should have an upper case name
13+
//~| SUGGESTION MY_STATIC
14+
15+
const LOL: u32 = MY_STATIC + 0;
16+
//~^ SUGGESTION MY_STATIC
17+
18+
thread_local! {
19+
static FOO_FOO: Cell<usize> = unreachable!();
20+
//~^ WARN constant `fooFOO` should have an upper case name
21+
//~| SUGGESTION FOO_FOO
22+
}
23+
24+
fn foo<const FOO: u32>() {
25+
//~^ WARN const parameter `foo` should have an upper case name
26+
//~| SUGGESTION FOO
27+
let _a = FOO + 1;
28+
//~^ SUGGESTION FOO
29+
}
30+
31+
fn main() {
32+
let _a = crate::MY_STATIC;
33+
//~^ SUGGESTION MY_STATIC
34+
35+
FOO_FOO.set(9);
36+
//~^ SUGGESTION FOO_FOO
37+
println!("{}", FOO_FOO.get());
38+
//~^ SUGGESTION FOO_FOO
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Checks that the `non_upper_case_globals` emits suggestions for usages as well
2+
// <https://github.com/rust-lang/rust/issues/124061>
3+
4+
//@ check-pass
5+
//@ run-rustfix
6+
7+
#![allow(dead_code)]
8+
9+
use std::cell::Cell;
10+
11+
const my_static: u32 = 0;
12+
//~^ WARN constant `my_static` should have an upper case name
13+
//~| SUGGESTION MY_STATIC
14+
15+
const LOL: u32 = my_static + 0;
16+
//~^ SUGGESTION MY_STATIC
17+
18+
thread_local! {
19+
static fooFOO: Cell<usize> = unreachable!();
20+
//~^ WARN constant `fooFOO` should have an upper case name
21+
//~| SUGGESTION FOO_FOO
22+
}
23+
24+
fn foo<const foo: u32>() {
25+
//~^ WARN const parameter `foo` should have an upper case name
26+
//~| SUGGESTION FOO
27+
let _a = foo + 1;
28+
//~^ SUGGESTION FOO
29+
}
30+
31+
fn main() {
32+
let _a = crate::my_static;
33+
//~^ SUGGESTION MY_STATIC
34+
35+
fooFOO.set(9);
36+
//~^ SUGGESTION FOO_FOO
37+
println!("{}", fooFOO.get());
38+
//~^ SUGGESTION FOO_FOO
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
warning: constant `my_static` should have an upper case name
2+
--> $DIR/lint-non-uppercase-usages.rs:11:7
3+
|
4+
LL | const my_static: u32 = 0;
5+
| ^^^^^^^^^
6+
|
7+
= note: `#[warn(non_upper_case_globals)]` on by default
8+
help: convert the identifier to upper case
9+
|
10+
LL - const my_static: u32 = 0;
11+
LL + const MY_STATIC: u32 = 0;
12+
|
13+
14+
warning: constant `fooFOO` should have an upper case name
15+
--> $DIR/lint-non-uppercase-usages.rs:19:12
16+
|
17+
LL | static fooFOO: Cell<usize> = unreachable!();
18+
| ^^^^^^
19+
|
20+
help: convert the identifier to upper case
21+
|
22+
LL - static fooFOO: Cell<usize> = unreachable!();
23+
LL + static FOO_FOO: Cell<usize> = unreachable!();
24+
|
25+
26+
warning: const parameter `foo` should have an upper case name
27+
--> $DIR/lint-non-uppercase-usages.rs:24:14
28+
|
29+
LL | fn foo<const foo: u32>() {
30+
| ^^^
31+
|
32+
help: convert the identifier to upper case (notice the capitalization difference)
33+
|
34+
LL - fn foo<const foo: u32>() {
35+
LL + fn foo<const FOO: u32>() {
36+
|
37+
38+
warning: 3 warnings emitted
39+

0 commit comments

Comments
 (0)