From b48699e4cfd8af15669227049f3c6056d4084aba Mon Sep 17 00:00:00 2001 From: cherryblossom <31467609+cherryblossom000@users.noreply.github.com> Date: Thu, 22 Apr 2021 19:34:36 +1000 Subject: [PATCH] `single_component_path_imports`: ignore `pub(crate) use some_macro;` (fixes #7106) --- .../src/single_component_path_imports.rs | 36 +++++++++++++++---- .../single_component_path_imports_macro.fixed | 21 +++++++++++ .../ui/single_component_path_imports_macro.rs | 21 +++++++++++ ...single_component_path_imports_macro.stderr | 10 ++++++ 4 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 tests/ui/single_component_path_imports_macro.fixed create mode 100644 tests/ui/single_component_path_imports_macro.rs create mode 100644 tests/ui/single_component_path_imports_macro.stderr diff --git a/clippy_lints/src/single_component_path_imports.rs b/clippy_lints/src/single_component_path_imports.rs index 6104103580e..a45bb102389 100644 --- a/clippy_lints/src/single_component_path_imports.rs +++ b/clippy_lints/src/single_component_path_imports.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::in_macro; -use rustc_ast::{ptr::P, Crate, Item, ItemKind, ModKind, UseTreeKind}; +use rustc_ast::{ptr::P, Crate, Item, ItemKind, MacroDef, ModKind, UseTreeKind, VisibilityKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -60,8 +60,21 @@ fn check_mod(cx: &EarlyContext<'_>, items: &[P]) { // ``` let mut single_use_usages = Vec::new(); + // keep track of macros defined in the module as we don't want it to trigger on this (#7106) + // ```rust,ignore + // macro_rules! foo { () => {} }; + // pub(crate) use foo; + // ``` + let mut macros = Vec::new(); + for item in items { - track_uses(cx, &item, &mut imports_reused_with_self, &mut single_use_usages); + track_uses( + cx, + &item, + &mut imports_reused_with_self, + &mut single_use_usages, + &mut macros, + ); } for single_use in &single_use_usages { @@ -96,6 +109,7 @@ fn track_uses( item: &Item, imports_reused_with_self: &mut Vec, single_use_usages: &mut Vec<(Symbol, Span, bool)>, + macros: &mut Vec, ) { if in_macro(item.span) || item.vis.kind.is_pub() { return; @@ -105,14 +119,22 @@ fn track_uses( ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) => { check_mod(cx, &items); }, + ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => { + macros.push(item.ident.name); + }, ItemKind::Use(use_tree) => { let segments = &use_tree.prefix.segments; + let should_report = + |name: &Symbol| !macros.contains(name) || matches!(item.vis.kind, VisibilityKind::Inherited); + // keep track of `use some_module;` usages if segments.len() == 1 { if let UseTreeKind::Simple(None, _, _) = use_tree.kind { - let ident = &segments[0].ident; - single_use_usages.push((ident.name, item.span, true)); + let name = segments[0].ident.name; + if should_report(&name) { + single_use_usages.push((name, item.span, true)); + } } return; } @@ -124,8 +146,10 @@ fn track_uses( let segments = &tree.0.prefix.segments; if segments.len() == 1 { if let UseTreeKind::Simple(None, _, _) = tree.0.kind { - let ident = &segments[0].ident; - single_use_usages.push((ident.name, tree.0.span, false)); + let name = segments[0].ident.name; + if should_report(&name) { + single_use_usages.push((name, tree.0.span, false)); + } } } } diff --git a/tests/ui/single_component_path_imports_macro.fixed b/tests/ui/single_component_path_imports_macro.fixed new file mode 100644 index 00000000000..05863f9a2bf --- /dev/null +++ b/tests/ui/single_component_path_imports_macro.fixed @@ -0,0 +1,21 @@ +// run-rustfix +// edition:2018 +#![warn(clippy::single_component_path_imports)] +#![allow(unused_imports)] + +// #7106: use statements exporting a macro within a crate should not trigger lint + +macro_rules! m1 { + () => {}; +} +pub(crate) use m1; // ok + +macro_rules! m2 { + () => {}; +} + // fail + +fn main() { + m1!(); + m2!(); +} diff --git a/tests/ui/single_component_path_imports_macro.rs b/tests/ui/single_component_path_imports_macro.rs new file mode 100644 index 00000000000..633deea348b --- /dev/null +++ b/tests/ui/single_component_path_imports_macro.rs @@ -0,0 +1,21 @@ +// run-rustfix +// edition:2018 +#![warn(clippy::single_component_path_imports)] +#![allow(unused_imports)] + +// #7106: use statements exporting a macro within a crate should not trigger lint + +macro_rules! m1 { + () => {}; +} +pub(crate) use m1; // ok + +macro_rules! m2 { + () => {}; +} +use m2; // fail + +fn main() { + m1!(); + m2!(); +} diff --git a/tests/ui/single_component_path_imports_macro.stderr b/tests/ui/single_component_path_imports_macro.stderr new file mode 100644 index 00000000000..239efb393b1 --- /dev/null +++ b/tests/ui/single_component_path_imports_macro.stderr @@ -0,0 +1,10 @@ +error: this import is redundant + --> $DIR/single_component_path_imports_macro.rs:16:1 + | +LL | use m2; // fail + | ^^^^^^^ help: remove it entirely + | + = note: `-D clippy::single-component-path-imports` implied by `-D warnings` + +error: aborting due to previous error + -- 2.44.0