summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/check_unused.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_resolve/src/check_unused.rs
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_resolve/src/check_unused.rs')
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs44
1 files changed, 41 insertions, 3 deletions
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index b2578e4c4..ae3fd0ede 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);
@@ -355,7 +393,7 @@ impl Resolver<'_, '_> {
// If we are in the `--test` mode, suppress a help that adds the `#[cfg(test)]`
// attribute; however, if not, suggest adding the attribute. There is no way to
// retrieve attributes here because we do not have a `TyCtxt` yet.
- let test_module_span = if tcx.sess.opts.test {
+ let test_module_span = if tcx.sess.is_test_crate() {
None
} else {
let parent_module = visitor.r.get_nearest_non_block_module(