From 0b5c683b06bba30cce4eb8528132a15bb1aa8edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sat, 17 Jun 2023 15:06:48 +0800 Subject: [PATCH] Add machine-applicable suggestion for `unused_qualifications` lint --- compiler/rustc_lint/src/context.rs | 8 +++++ compiler/rustc_lint_defs/src/lib.rs | 6 ++++ compiler/rustc_resolve/src/late.rs | 6 +++- tests/ui/lint/lint-qualification.stderr | 4 +++ .../unused-qualifications-suggestion.fixed | 23 +++++++++++++++ .../unused-qualifications-suggestion.rs | 23 +++++++++++++++ .../unused-qualifications-suggestion.stderr | 29 +++++++++++++++++++ 7 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 tests/ui/resolve/unused-qualifications-suggestion.fixed create mode 100644 tests/ui/resolve/unused-qualifications-suggestion.rs create mode 100644 tests/ui/resolve/unused-qualifications-suggestion.stderr diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 3761754f3aea4..4770ed6639312 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -956,6 +956,14 @@ pub trait LintContext: Sized { db.span_note(glob_reexport_span, format!("the name `{}` in the {} namespace is supposed to be publicly re-exported here", name, namespace)); db.span_note(private_item_span, "but the private item here shadows it".to_owned()); } + BuiltinLintDiagnostics::UnusedQualifications { path_span, unqualified_path } => { + db.span_suggestion_verbose( + path_span, + "replace it with the unqualified path", + unqualified_path, + Applicability::MachineApplicable + ); + } } // Rewrap `db`, and pass control to the user. decorate(db) diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 5a5031b791964..f6ffd46b1fe08 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -550,6 +550,12 @@ pub enum BuiltinLintDiagnostics { /// The local binding that shadows the glob reexport. private_item_span: Span, }, + UnusedQualifications { + /// The span of the unnecessarily-qualified path. + path_span: Span, + /// The replacement unqualified path. + unqualified_path: Ident, + }, } /// Lints that are buffered up early on in the `Session` before the diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f6c7aecf8b0bb..d3647663824a5 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3917,11 +3917,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }; if res == unqualified_result { let lint = lint::builtin::UNUSED_QUALIFICATIONS; - self.r.lint_buffer.buffer_lint( + self.r.lint_buffer.buffer_lint_with_diagnostic( lint, finalize.node_id, finalize.path_span, "unnecessary qualification", + lint::BuiltinLintDiagnostics::UnusedQualifications { + path_span: finalize.path_span, + unqualified_path: path.last().unwrap().ident + } ) } } diff --git a/tests/ui/lint/lint-qualification.stderr b/tests/ui/lint/lint-qualification.stderr index 149a782d97c2e..d09cb78c4f013 100644 --- a/tests/ui/lint/lint-qualification.stderr +++ b/tests/ui/lint/lint-qualification.stderr @@ -9,6 +9,10 @@ note: the lint level is defined here | LL | #![deny(unused_qualifications)] | ^^^^^^^^^^^^^^^^^^^^^ +help: replace it with the unqualified path + | +LL | bar(); + | ~~~ error: aborting due to previous error diff --git a/tests/ui/resolve/unused-qualifications-suggestion.fixed b/tests/ui/resolve/unused-qualifications-suggestion.fixed new file mode 100644 index 0000000000000..0d4b9007c7b5e --- /dev/null +++ b/tests/ui/resolve/unused-qualifications-suggestion.fixed @@ -0,0 +1,23 @@ +// run-rustfix + +#![deny(unused_qualifications)] + +mod foo { + pub fn bar() {} +} + +mod baz { + pub mod qux { + pub fn quux() {} + } +} + +fn main() { + use foo::bar; + bar(); + //~^ ERROR unnecessary qualification + + use baz::qux::quux; + quux(); + //~^ ERROR unnecessary qualification +} diff --git a/tests/ui/resolve/unused-qualifications-suggestion.rs b/tests/ui/resolve/unused-qualifications-suggestion.rs new file mode 100644 index 0000000000000..f6722e96537c9 --- /dev/null +++ b/tests/ui/resolve/unused-qualifications-suggestion.rs @@ -0,0 +1,23 @@ +// run-rustfix + +#![deny(unused_qualifications)] + +mod foo { + pub fn bar() {} +} + +mod baz { + pub mod qux { + pub fn quux() {} + } +} + +fn main() { + use foo::bar; + foo::bar(); + //~^ ERROR unnecessary qualification + + use baz::qux::quux; + baz::qux::quux(); + //~^ ERROR unnecessary qualification +} diff --git a/tests/ui/resolve/unused-qualifications-suggestion.stderr b/tests/ui/resolve/unused-qualifications-suggestion.stderr new file mode 100644 index 0000000000000..c8e91e07295b6 --- /dev/null +++ b/tests/ui/resolve/unused-qualifications-suggestion.stderr @@ -0,0 +1,29 @@ +error: unnecessary qualification + --> $DIR/unused-qualifications-suggestion.rs:17:5 + | +LL | foo::bar(); + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-qualifications-suggestion.rs:3:9 + | +LL | #![deny(unused_qualifications)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: replace it with the unqualified path + | +LL | bar(); + | ~~~ + +error: unnecessary qualification + --> $DIR/unused-qualifications-suggestion.rs:21:5 + | +LL | baz::qux::quux(); + | ^^^^^^^^^^^^^^ + | +help: replace it with the unqualified path + | +LL | quux(); + | ~~~~ + +error: aborting due to 2 previous errors +