+
+fn track_uses(
+ cx: &EarlyContext<'_>,
+ item: &Item,
+ imports_reused_with_self: &mut Vec<Symbol>,
+ single_use_usages: &mut Vec<(Symbol, Span, bool)>,
+ macros: &mut Vec<Symbol>,
+) {
+ if in_macro(item.span) || item.vis.kind.is_pub() {
+ return;
+ }
+
+ match &item.kind {
+ 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 name = segments[0].ident.name;
+ if should_report(&name) {
+ single_use_usages.push((name, item.span, true));
+ }
+ }
+ return;
+ }
+
+ if segments.is_empty() {
+ // keep track of `use {some_module, some_other_module};` usages
+ if let UseTreeKind::Nested(trees) = &use_tree.kind {
+ for tree in trees {
+ let segments = &tree.0.prefix.segments;
+ if segments.len() == 1 {
+ if let UseTreeKind::Simple(None, _, _) = tree.0.kind {
+ let name = segments[0].ident.name;
+ if should_report(&name) {
+ single_use_usages.push((name, tree.0.span, false));
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // keep track of `use self::some_module` usages
+ if segments[0].ident.name == kw::SelfLower {
+ // simple case such as `use self::module::SomeStruct`
+ if segments.len() > 1 {
+ imports_reused_with_self.push(segments[1].ident.name);
+ return;
+ }
+
+ // nested case such as `use self::{module1::Struct1, module2::Struct2}`
+ if let UseTreeKind::Nested(trees) = &use_tree.kind {
+ for tree in trees {
+ let segments = &tree.0.prefix.segments;
+ if !segments.is_empty() {
+ imports_reused_with_self.push(segments[0].ident.name);
+ }
+ }
+ }
+ }
+ }
+ },
+ _ => {},
+ }
+}