From 825f0888cc168c767e3f6c071831963ddebbb78a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 22 Mar 2023 15:38:58 +0100 Subject: [PATCH 1/2] Move useless_anynous_reexport lint into unused_imports --- compiler/rustc_lint/messages.ftl | 3 - compiler/rustc_lint/src/lib.rs | 3 - compiler/rustc_lint/src/lints.rs | 8 --- compiler/rustc_lint/src/reexports.rs | 82 ---------------------- compiler/rustc_resolve/src/check_unused.rs | 42 ++++++++++- tests/ui/imports/issue-99695-b.fixed | 2 +- tests/ui/imports/issue-99695-b.rs | 2 +- tests/ui/imports/issue-99695.fixed | 2 +- tests/ui/imports/issue-99695.rs | 2 +- 9 files changed, 44 insertions(+), 102 deletions(-) delete mode 100644 compiler/rustc_lint/src/reexports.rs diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index c822237413c70..68e62c9789aed 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -508,6 +508,3 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass .specifically = this associated type bound is unsatisfied for `{$proj_ty}` lint_opaque_hidden_inferred_bound_sugg = add this bound - -lint_useless_anonymous_reexport = useless anonymous re-export - .note = only anonymous re-exports of traits are useful, this is {$article} `{$desc}` diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c2cc2fcdf551a..b3578540516d0 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -74,7 +74,6 @@ mod opaque_hidden_inferred_bound; mod pass_by_value; mod passes; mod redundant_semicolon; -mod reexports; mod traits; mod types; mod unused; @@ -112,7 +111,6 @@ use noop_method_call::*; use opaque_hidden_inferred_bound::*; use pass_by_value::*; use redundant_semicolon::*; -use reexports::*; use traits::*; use types::*; use unused::*; @@ -244,7 +242,6 @@ late_lint_methods!( OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, MultipleSupertraitUpcastable: MultipleSupertraitUpcastable, MapUnitFn: MapUnitFn, - UselessAnonymousReexport: UselessAnonymousReexport, ] ] ); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 46a025f41e04a..308c02929ca42 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1528,11 +1528,3 @@ pub struct UnusedAllocationDiag; #[derive(LintDiagnostic)] #[diag(lint_unused_allocation_mut)] pub struct UnusedAllocationMutDiag; - -#[derive(LintDiagnostic)] -#[diag(lint_useless_anonymous_reexport)] -#[note] -pub struct UselessAnonymousReexportDiag { - pub article: &'static str, - pub desc: &'static str, -} diff --git a/compiler/rustc_lint/src/reexports.rs b/compiler/rustc_lint/src/reexports.rs deleted file mode 100644 index 8737a57ea0264..0000000000000 --- a/compiler/rustc_lint/src/reexports.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::lints::UselessAnonymousReexportDiag; -use crate::{LateContext, LateLintPass, LintContext}; -use rustc_hir::def::DefKind; -use rustc_hir::def_id::DefId; -use rustc_hir::{Item, ItemKind, UseKind}; -use rustc_middle::ty::Visibility; -use rustc_span::symbol::kw; -use rustc_span::Span; - -declare_lint! { - /// The `useless_anonymous_reexport` lint checks if anonymous re-exports - /// are re-exports of traits. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(useless_anonymous_reexport)] - /// - /// mod sub { - /// pub struct Bar; - /// } - /// - /// pub use self::sub::Bar as _; - /// # fn main() {} - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Anonymous re-exports are only useful if it's a re-export of a trait - /// in case you want to give access to it. If you re-export any other kind, - /// you won't be able to use it since its name won't be accessible. - pub USELESS_ANONYMOUS_REEXPORT, - Warn, - "useless anonymous re-export" -} - -declare_lint_pass!(UselessAnonymousReexport => [USELESS_ANONYMOUS_REEXPORT]); - -fn emit_err(cx: &LateContext<'_>, span: Span, def_id: DefId) { - let article = cx.tcx.def_descr_article(def_id); - let desc = cx.tcx.def_descr(def_id); - cx.emit_spanned_lint( - USELESS_ANONYMOUS_REEXPORT, - span, - UselessAnonymousReexportDiag { article, desc }, - ); -} - -impl<'tcx> LateLintPass<'tcx> for UselessAnonymousReexport { - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let ItemKind::Use(path, kind) = item.kind && - !matches!(kind, UseKind::Glob) && - item.ident.name == kw::Underscore && - // We only want re-exports. If it's just a `use X;`, then we ignore it. - match cx.tcx.local_visibility(item.owner_id.def_id) { - Visibility::Public => true, - Visibility::Restricted(level) => { - level != cx.tcx.parent_module_from_def_id(item.owner_id.def_id) - } - } - { - for def_id in path.res.iter().filter_map(|r| r.opt_def_id()) { - match cx.tcx.def_kind(def_id) { - DefKind::Trait | DefKind::TraitAlias => {} - DefKind::TyAlias => { - let ty = cx.tcx.type_of(def_id); - if !ty.0.is_trait() { - emit_err(cx, item.span, def_id); - break; - } - } - _ => { - emit_err(cx, item.span, def_id); - break; - } - } - } - } - } -} diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index b2578e4c4b446..dbf6cec788b5a 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -32,9 +32,10 @@ use rustc_ast::visit::{self, Visitor}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_errors::{pluralize, MultiSpan}; +use rustc_hir::def::{DefKind, Res}; use rustc_session::lint::builtin::{MACRO_USE_EXTERN_CRATE, UNUSED_EXTERN_CRATES, UNUSED_IMPORTS}; use rustc_session::lint::BuiltinLintDiagnostics; -use rustc_span::symbol::Ident; +use rustc_span::symbol::{kw, Ident}; use rustc_span::{Span, DUMMY_SP}; struct UnusedImport<'a> { @@ -58,6 +59,7 @@ struct UnusedImportCheckVisitor<'a, 'b, 'tcx> { base_use_tree: Option<&'a ast::UseTree>, base_id: ast::NodeId, item_span: Span, + base_use_is_pub: bool, } struct ExternCrateToLint { @@ -110,6 +112,35 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { unused: Default::default(), }) } + + fn check_import_as_underscore(&mut self, item: &ast::UseTree, id: ast::NodeId) { + match item.kind { + ast::UseTreeKind::Simple(Some(ident)) => { + if ident.name == kw::Underscore + && !self + .r + .import_res_map + .get(&id) + .map(|per_ns| { + per_ns.iter().filter_map(|res| res.as_ref()).any(|res| { + matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) + }) + }) + .unwrap_or(false) + { + self.unused_import(self.base_id).add(id); + } + } + ast::UseTreeKind::Nested(ref items) => self.check_imports_as_underscore(items), + _ => {} + } + } + + fn check_imports_as_underscore(&mut self, items: &[(ast::UseTree, ast::NodeId)]) { + for (item, id) in items { + self.check_import_as_underscore(item, *id); + } + } } impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { @@ -119,7 +150,8 @@ impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. - ast::ItemKind::Use(..) if item.vis.kind.is_pub() || item.span.is_dummy() => return, + ast::ItemKind::Use(..) if item.span.is_dummy() => return, + ast::ItemKind::Use(..) => self.base_use_is_pub = item.vis.kind.is_pub(), ast::ItemKind::ExternCrate(orig_name) => { self.extern_crate_items.push(ExternCrateToLint { id: item.id, @@ -146,6 +178,11 @@ impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { self.base_use_tree = Some(use_tree); } + if self.base_use_is_pub { + self.check_import_as_underscore(use_tree, id); + return; + } + if let ast::UseTreeKind::Nested(ref items) = use_tree.kind { if items.is_empty() { self.unused_import(self.base_id).add(id); @@ -300,6 +337,7 @@ impl Resolver<'_, '_> { base_use_tree: None, base_id: ast::DUMMY_NODE_ID, item_span: DUMMY_SP, + base_use_is_pub: false, }; visit::walk_crate(&mut visitor, krate); diff --git a/tests/ui/imports/issue-99695-b.fixed b/tests/ui/imports/issue-99695-b.fixed index 0f688fa282356..0e60c73b67a44 100644 --- a/tests/ui/imports/issue-99695-b.fixed +++ b/tests/ui/imports/issue-99695-b.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![allow(unused, nonstandard_style, useless_anonymous_reexport)] +#![allow(unused, nonstandard_style)] mod m { mod p { diff --git a/tests/ui/imports/issue-99695-b.rs b/tests/ui/imports/issue-99695-b.rs index b433997e53f6a..031443a1f5df8 100644 --- a/tests/ui/imports/issue-99695-b.rs +++ b/tests/ui/imports/issue-99695-b.rs @@ -1,5 +1,5 @@ // run-rustfix -#![allow(unused, nonstandard_style, useless_anonymous_reexport)] +#![allow(unused, nonstandard_style)] mod m { mod p { diff --git a/tests/ui/imports/issue-99695.fixed b/tests/ui/imports/issue-99695.fixed index 17ff409324e34..6bf228b23aad2 100644 --- a/tests/ui/imports/issue-99695.fixed +++ b/tests/ui/imports/issue-99695.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![allow(unused, nonstandard_style, useless_anonymous_reexport)] +#![allow(unused, nonstandard_style)] mod m { #[macro_export] macro_rules! nu { diff --git a/tests/ui/imports/issue-99695.rs b/tests/ui/imports/issue-99695.rs index b8979bcb7345c..f7199f1497ab0 100644 --- a/tests/ui/imports/issue-99695.rs +++ b/tests/ui/imports/issue-99695.rs @@ -1,5 +1,5 @@ // run-rustfix -#![allow(unused, nonstandard_style, useless_anonymous_reexport)] +#![allow(unused, nonstandard_style)] mod m { #[macro_export] macro_rules! nu { From e03b13ccb7726005a49c5a9c6a3b47c8ba6804e6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 22 Mar 2023 15:39:16 +0100 Subject: [PATCH 2/2] Update anonymous-reexport UI test --- tests/ui/lint/anonymous-reexport.rs | 16 ++++---- tests/ui/lint/anonymous-reexport.stderr | 49 ++++++++++--------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/tests/ui/lint/anonymous-reexport.rs b/tests/ui/lint/anonymous-reexport.rs index 5d56ae6f969b5..11ac5d07140ba 100644 --- a/tests/ui/lint/anonymous-reexport.rs +++ b/tests/ui/lint/anonymous-reexport.rs @@ -1,4 +1,4 @@ -#![deny(useless_anonymous_reexport)] +#![deny(unused_imports)] #![crate_type = "rlib"] mod my_mod { @@ -9,13 +9,11 @@ mod my_mod { } pub use self::my_mod::Foo as _; -pub use self::my_mod::TyFoo as _; -pub use self::my_mod::Bar as _; //~ ERROR -pub use self::my_mod::TyBar as _; //~ ERROR -pub use self::my_mod::{Bar as _}; //~ ERROR -pub use self::my_mod::{Bar as _, Foo as _}; //~ ERROR -pub use self::my_mod::{Bar as _, TyBar as _}; -//~^ ERROR -//~| ERROR +pub use self::my_mod::TyFoo as _; //~ ERROR unused import +pub use self::my_mod::Bar as _; //~ ERROR unused import +pub use self::my_mod::TyBar as _; //~ ERROR unused import +pub use self::my_mod::{Bar as _}; //~ ERROR unused import +pub use self::my_mod::{Bar as _, Foo as _}; //~ ERROR unused import +pub use self::my_mod::{Bar as _, TyBar as _}; //~ ERROR unused imports #[allow(unused_imports)] use self::my_mod::TyBar as _; diff --git a/tests/ui/lint/anonymous-reexport.stderr b/tests/ui/lint/anonymous-reexport.stderr index f4f8b41c417a4..e3854a5459ec0 100644 --- a/tests/ui/lint/anonymous-reexport.stderr +++ b/tests/ui/lint/anonymous-reexport.stderr @@ -1,55 +1,44 @@ -error: useless anonymous re-export - --> $DIR/anonymous-reexport.rs:13:1 +error: unused import: `self::my_mod::TyFoo as _` + --> $DIR/anonymous-reexport.rs:12:9 | -LL | pub use self::my_mod::Bar as _; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub use self::my_mod::TyFoo as _; + | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: only anonymous re-exports of traits are useful, this is a `struct` note: the lint level is defined here --> $DIR/anonymous-reexport.rs:1:9 | -LL | #![deny(useless_anonymous_reexport)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ -error: useless anonymous re-export - --> $DIR/anonymous-reexport.rs:14:1 +error: unused import: `self::my_mod::Bar as _` + --> $DIR/anonymous-reexport.rs:13:9 | -LL | pub use self::my_mod::TyBar as _; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub use self::my_mod::Bar as _; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unused import: `self::my_mod::TyBar as _` + --> $DIR/anonymous-reexport.rs:14:9 | - = note: only anonymous re-exports of traits are useful, this is a `type alias` +LL | pub use self::my_mod::TyBar as _; + | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: useless anonymous re-export +error: unused import: `Bar as _` --> $DIR/anonymous-reexport.rs:15:24 | LL | pub use self::my_mod::{Bar as _}; | ^^^^^^^^ - | - = note: only anonymous re-exports of traits are useful, this is a `struct` -error: useless anonymous re-export +error: unused import: `Bar as _` --> $DIR/anonymous-reexport.rs:16:24 | LL | pub use self::my_mod::{Bar as _, Foo as _}; | ^^^^^^^^ - | - = note: only anonymous re-exports of traits are useful, this is a `struct` -error: useless anonymous re-export +error: unused imports: `Bar as _`, `TyBar as _` --> $DIR/anonymous-reexport.rs:17:24 | LL | pub use self::my_mod::{Bar as _, TyBar as _}; - | ^^^^^^^^ - | - = note: only anonymous re-exports of traits are useful, this is a `struct` - -error: useless anonymous re-export - --> $DIR/anonymous-reexport.rs:17:34 - | -LL | pub use self::my_mod::{Bar as _, TyBar as _}; - | ^^^^^^^^^^ - | - = note: only anonymous re-exports of traits are useful, this is a `type alias` + | ^^^^^^^^ ^^^^^^^^^^ error: aborting due to 6 previous errors