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