rustc_hir_analysis/
check_unused.rs1use rustc_data_structures::unord::{ExtendUnord, UnordSet};
2use rustc_hir::def::DefKind;
3use rustc_hir::def_id::LocalDefId;
4use rustc_middle::ty::TyCtxt;
5use rustc_session::lint;
6use tracing::debug;
7
8pub(super) fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
9 let mut used_trait_imports = UnordSet::<LocalDefId>::default();
10
11 for item_def_id in tcx.hir_body_owners() {
16 let imports = tcx.used_trait_imports(item_def_id);
17 debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
18 used_trait_imports.extend_unord(imports.items().copied());
19 }
20
21 for &id in tcx.maybe_unused_trait_imports(()) {
22 debug_assert_eq!(tcx.def_kind(id), DefKind::Use);
23 if tcx.visibility(id).is_public() {
24 continue;
25 }
26 if used_trait_imports.contains(&id) {
27 continue;
28 }
29 let item = tcx.hir_expect_item(id);
30 if item.span.is_dummy() {
31 continue;
32 }
33 let (path, _) = item.expect_use();
34 tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
35 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
36 lint.primary_message(format!("unused import: `{snippet}`"));
37 } else {
38 lint.primary_message("unused import");
39 }
40 });
41 }
42}