about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-20 11:05:49 +0000
committerGitHub <noreply@github.com>2024-12-20 11:05:49 +0000
commit3309dfa090e4e5ff63c4eee16fa4d59cb237b13b (patch)
tree9a5f7650ec3fd557855a5ad537fda7a609f06b1c /src
parent4200da43cf2b95da3f5820816d29742c61f0b268 (diff)
parentcf32a6feccf17a22175833c0be3f566dadc81d86 (diff)
downloadrust-3309dfa090e4e5ff63c4eee16fa4d59cb237b13b.tar.gz
rust-3309dfa090e4e5ff63c4eee16fa4d59cb237b13b.zip
Merge pull request #18702 from ChayimFriedman2/prep
minor: Use a record struct instead of a tuple for each namespace in `PerNs`
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs124
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs56
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs77
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs24
6 files changed, 162 insertions, 133 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index e96e38eceeb..2c3eb5c8e5e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -16,7 +16,7 @@ use syntax::ast;
 
 use crate::{
     db::DefDatabase,
-    per_ns::PerNs,
+    per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem},
     visibility::{Visibility, VisibilityExplicitness},
     AdtId, BuiltinType, ConstId, ExternCrateId, FxIndexMap, HasModule, ImplId, LocalModuleId,
     Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId,
@@ -80,9 +80,9 @@ pub struct ItemScope {
     /// Defs visible in this scope. This includes `declarations`, but also
     /// imports. The imports belong to this module and can be resolved by using them on
     /// the `use_imports_*` fields.
-    types: FxIndexMap<Name, (ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
-    values: FxIndexMap<Name, (ModuleDefId, Visibility, Option<ImportId>)>,
-    macros: FxIndexMap<Name, (MacroId, Visibility, Option<ImportId>)>,
+    types: FxIndexMap<Name, TypesItem>,
+    values: FxIndexMap<Name, ValuesItem>,
+    macros: FxIndexMap<Name, MacrosItem>,
     unresolved: FxHashSet<Name>,
 
     /// The defs declared in this scope. Each def has a single scope where it is
@@ -92,7 +92,7 @@ pub struct ItemScope {
     impls: Vec<ImplId>,
     unnamed_consts: Vec<ConstId>,
     /// Traits imported via `use Trait as _;`.
-    unnamed_trait_imports: FxHashMap<TraitId, (Visibility, Option<ImportId>)>,
+    unnamed_trait_imports: FxHashMap<TraitId, Item<()>>,
 
     // the resolutions of the imports of this scope
     use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>,
@@ -187,7 +187,7 @@ impl ItemScope {
                     import = i;
                 }
                 ImportOrDef::Def(ModuleDefId::MacroId(def)) => {
-                    res.macros = Some((def, Visibility::Public, None));
+                    res.macros = Some(Item { def, vis: Visibility::Public, import: None });
                     break;
                 }
                 _ => break,
@@ -203,7 +203,7 @@ impl ItemScope {
                     import = i;
                 }
                 ImportOrDef::Def(def) => {
-                    res.types = Some((def, Visibility::Public, None));
+                    res.types = Some(Item { def, vis: Visibility::Public, import: None });
                     break;
                 }
                 _ => break,
@@ -219,7 +219,7 @@ impl ItemScope {
                     import = i;
                 }
                 ImportOrDef::Def(def) => {
-                    res.values = Some((def, Visibility::Public, None));
+                    res.values = Some(Item { def, vis: Visibility::Public, import: None });
                     break;
                 }
                 _ => break,
@@ -253,8 +253,8 @@ impl ItemScope {
     }
 
     pub(crate) fn modules_in_scope(&self) -> impl Iterator<Item = (ModuleId, Visibility)> + '_ {
-        self.types.values().copied().filter_map(|(def, vis, _)| match def {
-            ModuleDefId::ModuleId(module) => Some((module, vis)),
+        self.types.values().filter_map(|ns| match ns.def {
+            ModuleDefId::ModuleId(module) => Some((module, ns.vis)),
             _ => None,
         })
     }
@@ -283,20 +283,20 @@ impl ItemScope {
     }
 
     pub(crate) fn type_(&self, name: &Name) -> Option<(ModuleDefId, Visibility)> {
-        self.types.get(name).copied().map(|(a, b, _)| (a, b))
+        self.types.get(name).map(|item| (item.def, item.vis))
     }
 
     /// XXX: this is O(N) rather than O(1), try to not introduce new usages.
     pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility, /*declared*/ bool)> {
         match item {
-            ItemInNs::Macros(def) => self.macros.iter().find_map(|(name, &(other_def, vis, i))| {
-                (other_def == def).then_some((name, vis, i.is_none()))
+            ItemInNs::Macros(def) => self.macros.iter().find_map(|(name, other_def)| {
+                (other_def.def == def).then_some((name, other_def.vis, other_def.import.is_none()))
             }),
-            ItemInNs::Types(def) => self.types.iter().find_map(|(name, &(other_def, vis, i))| {
-                (other_def == def).then_some((name, vis, i.is_none()))
+            ItemInNs::Types(def) => self.types.iter().find_map(|(name, other_def)| {
+                (other_def.def == def).then_some((name, other_def.vis, other_def.import.is_none()))
             }),
-            ItemInNs::Values(def) => self.values.iter().find_map(|(name, &(other_def, vis, i))| {
-                (other_def == def).then_some((name, vis, i.is_none()))
+            ItemInNs::Values(def) => self.values.iter().find_map(|(name, other_def)| {
+                (other_def.def == def).then_some((name, other_def.vis, other_def.import.is_none()))
             }),
         }
     }
@@ -311,22 +311,34 @@ impl ItemScope {
             ItemInNs::Macros(def) => self
                 .macros
                 .iter()
-                .filter_map(|(name, &(other_def, vis, i))| {
-                    (other_def == def).then_some((name, vis, i.is_none()))
+                .filter_map(|(name, other_def)| {
+                    (other_def.def == def).then_some((
+                        name,
+                        other_def.vis,
+                        other_def.import.is_none(),
+                    ))
                 })
                 .find_map(|(a, b, c)| cb(a, b, c)),
             ItemInNs::Types(def) => self
                 .types
                 .iter()
-                .filter_map(|(name, &(other_def, vis, i))| {
-                    (other_def == def).then_some((name, vis, i.is_none()))
+                .filter_map(|(name, other_def)| {
+                    (other_def.def == def).then_some((
+                        name,
+                        other_def.vis,
+                        other_def.import.is_none(),
+                    ))
                 })
                 .find_map(|(a, b, c)| cb(a, b, c)),
             ItemInNs::Values(def) => self
                 .values
                 .iter()
-                .filter_map(|(name, &(other_def, vis, i))| {
-                    (other_def == def).then_some((name, vis, i.is_none()))
+                .filter_map(|(name, other_def)| {
+                    (other_def.def == def).then_some((
+                        name,
+                        other_def.vis,
+                        other_def.import.is_none(),
+                    ))
                 })
                 .find_map(|(a, b, c)| cb(a, b, c)),
         }
@@ -335,7 +347,7 @@ impl ItemScope {
     pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
         self.types
             .values()
-            .filter_map(|&(def, _, _)| match def {
+            .filter_map(|def| match def.def {
                 ModuleDefId::TraitId(t) => Some(t),
                 _ => None,
             })
@@ -344,13 +356,13 @@ impl ItemScope {
 
     pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
         self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
-            self.unnamed_trait_imports.iter().map(|(tr, (vis, i))| {
+            self.unnamed_trait_imports.iter().map(|(tr, trait_)| {
                 (
                     None,
                     PerNs::types(
                         ModuleDefId::TraitId(*tr),
-                        *vis,
-                        i.map(ImportOrExternCrate::Import),
+                        trait_.vis,
+                        trait_.import.map(ImportOrExternCrate::Import),
                     ),
                 )
             }),
@@ -464,12 +476,12 @@ impl ItemScope {
 
     // FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope
     pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
-        self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a)
+        self.unnamed_trait_imports.get(&tr).map(|trait_| trait_.vis)
     }
 
     pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
         // FIXME: import
-        self.unnamed_trait_imports.insert(tr, (vis, None));
+        self.unnamed_trait_imports.insert(tr, Item { def: (), vis, import: None });
     }
 
     pub(crate) fn push_res_with_import(
@@ -502,7 +514,7 @@ impl ItemScope {
                         }
                         None | Some(ImportType::Glob(_)) => None,
                     };
-                    let prev = std::mem::replace(&mut fld.2, import);
+                    let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
                         self.use_imports_types.insert(
                             import,
@@ -513,7 +525,7 @@ impl ItemScope {
                                 Some(ImportOrExternCrate::ExternCrate(import)) => {
                                     ImportOrDef::ExternCrate(import)
                                 }
-                                None => ImportOrDef::Def(fld.0),
+                                None => ImportOrDef::Def(fld.def),
                             },
                         );
                     }
@@ -540,7 +552,7 @@ impl ItemScope {
                                     }
                                     None | Some(ImportType::Glob(_)) => None,
                                 };
-                                let prev = std::mem::replace(&mut fld.2, import);
+                                let prev = std::mem::replace(&mut fld.import, import);
                                 if let Some(import) = import {
                                     self.use_imports_types.insert(
                                         import,
@@ -551,7 +563,7 @@ impl ItemScope {
                                             Some(ImportOrExternCrate::ExternCrate(import)) => {
                                                 ImportOrDef::ExternCrate(import)
                                             }
-                                            None => ImportOrDef::Def(fld.0),
+                                            None => ImportOrDef::Def(fld.def),
                                         },
                                     );
                                 }
@@ -579,13 +591,13 @@ impl ItemScope {
                         Some(ImportType::Import(import)) => Some(import),
                         _ => None,
                     };
-                    let prev = std::mem::replace(&mut fld.2, import);
+                    let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
                         self.use_imports_values.insert(
                             import,
                             match prev {
                                 Some(import) => ImportOrDef::Import(import),
-                                None => ImportOrDef::Def(fld.0),
+                                None => ImportOrDef::Def(fld.def),
                             },
                         );
                     }
@@ -599,13 +611,13 @@ impl ItemScope {
                             Some(ImportType::Import(import)) => Some(import),
                             _ => None,
                         };
-                        let prev = std::mem::replace(&mut fld.2, import);
+                        let prev = std::mem::replace(&mut fld.import, import);
                         if let Some(import) = import {
                             self.use_imports_values.insert(
                                 import,
                                 match prev {
                                     Some(import) => ImportOrDef::Import(import),
-                                    None => ImportOrDef::Def(fld.0),
+                                    None => ImportOrDef::Def(fld.def),
                                 },
                             );
                         }
@@ -631,13 +643,13 @@ impl ItemScope {
                         Some(ImportType::Import(import)) => Some(import),
                         _ => None,
                     };
-                    let prev = std::mem::replace(&mut fld.2, import);
+                    let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
                         self.use_imports_macros.insert(
                             import,
                             match prev {
                                 Some(import) => ImportOrDef::Import(import),
-                                None => ImportOrDef::Def(fld.0.into()),
+                                None => ImportOrDef::Def(fld.def.into()),
                             },
                         );
                     }
@@ -651,13 +663,13 @@ impl ItemScope {
                             Some(ImportType::Import(import)) => Some(import),
                             _ => None,
                         };
-                        let prev = std::mem::replace(&mut fld.2, import);
+                        let prev = std::mem::replace(&mut fld.import, import);
                         if let Some(import) = import {
                             self.use_imports_macros.insert(
                                 import,
                                 match prev {
                                     Some(import) => ImportOrDef::Import(import),
-                                    None => ImportOrDef::Def(fld.0.into()),
+                                    None => ImportOrDef::Def(fld.def.into()),
                                 },
                             );
                         }
@@ -680,19 +692,19 @@ impl ItemScope {
     pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
         self.types
             .values_mut()
-            .map(|(_, vis, _)| vis)
-            .chain(self.values.values_mut().map(|(_, vis, _)| vis))
-            .chain(self.unnamed_trait_imports.values_mut().map(|(vis, _)| vis))
+            .map(|def| &mut def.vis)
+            .chain(self.values.values_mut().map(|def| &mut def.vis))
+            .chain(self.unnamed_trait_imports.values_mut().map(|def| &mut def.vis))
             .for_each(|vis| {
                 *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit)
             });
 
-        for (mac, vis, import) in self.macros.values_mut() {
-            if matches!(mac, MacroId::ProcMacroId(_) if import.is_none()) {
+        for mac in self.macros.values_mut() {
+            if matches!(mac.def, MacroId::ProcMacroId(_) if mac.import.is_none()) {
                 continue;
             }
 
-            *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit);
+            mac.vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit);
         }
     }
 
@@ -707,23 +719,23 @@ impl ItemScope {
                 name.map_or("_".to_owned(), |name| name.display(db, Edition::LATEST).to_string())
             );
 
-            if let Some((.., i)) = def.types {
+            if let Some(Item { import, .. }) = def.types {
                 buf.push_str(" t");
-                match i {
+                match import {
                     Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
                     Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
                     None => (),
                 }
             }
-            if let Some((.., i)) = def.values {
+            if let Some(Item { import, .. }) = def.values {
                 buf.push_str(" v");
-                if i.is_some() {
+                if import.is_some() {
                     buf.push('i');
                 }
             }
-            if let Some((.., i)) = def.macros {
+            if let Some(Item { import, .. }) = def.macros {
                 buf.push_str(" m");
-                if i.is_some() {
+                if import.is_some() {
                     buf.push('i');
                 }
             }
@@ -781,19 +793,19 @@ impl ItemScope {
     pub(crate) fn update_visibility_types(&mut self, name: &Name, vis: Visibility) {
         let res =
             self.types.get_mut(name).expect("tried to update visibility of non-existent type");
-        res.1 = vis;
+        res.vis = vis;
     }
 
     pub(crate) fn update_visibility_values(&mut self, name: &Name, vis: Visibility) {
         let res =
             self.values.get_mut(name).expect("tried to update visibility of non-existent value");
-        res.1 = vis;
+        res.vis = vis;
     }
 
     pub(crate) fn update_visibility_macros(&mut self, name: &Name, vis: Visibility) {
         let res =
             self.macros.get_mut(name).expect("tried to update visibility of non-existent macro");
-        res.1 = vis;
+        res.vis = vis;
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 98b08bcf708..f391cc41c18 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -44,7 +44,7 @@ use crate::{
         ResolveMode,
     },
     path::{ImportAlias, ModPath, PathKind},
-    per_ns::PerNs,
+    per_ns::{Item, PerNs},
     tt,
     visibility::{RawVisibility, Visibility},
     AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantLoc,
@@ -523,7 +523,7 @@ impl DefCollector<'_> {
             self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
 
         match per_ns.types {
-            Some((ModuleDefId::ModuleId(m), _, import)) => {
+            Some(Item { def: ModuleDefId::ModuleId(m), import, .. }) => {
                 // FIXME: This should specifically look for a glob import somehow and record that here
                 self.def_map.prelude = Some((
                     m,
@@ -1069,9 +1069,9 @@ impl DefCollector<'_> {
         //
         // This has been historically allowed, but may be not allowed in future
         // https://github.com/rust-lang/rust/issues/127909
-        if let Some((_, v, it)) = defs.types.as_mut() {
+        if let Some(def) = defs.types.as_mut() {
             let is_extern_crate_reimport_without_prefix = || {
-                let Some(ImportOrExternCrate::ExternCrate(_)) = it else {
+                let Some(ImportOrExternCrate::ExternCrate(_)) = def.import else {
                     return false;
                 };
                 let Some(ImportType::Import(id)) = def_import_type else {
@@ -1086,16 +1086,16 @@ impl DefCollector<'_> {
                 path.segments().len() < 2
             };
             if is_extern_crate_reimport_without_prefix() {
-                *v = vis;
+                def.vis = vis;
             } else {
-                *v = v.min(vis, &self.def_map).unwrap_or(vis);
+                def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis);
             }
         }
-        if let Some((_, v, _)) = defs.values.as_mut() {
-            *v = v.min(vis, &self.def_map).unwrap_or(vis);
+        if let Some(def) = defs.values.as_mut() {
+            def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis);
         }
-        if let Some((_, v, _)) = defs.macros.as_mut() {
-            *v = v.min(vis, &self.def_map).unwrap_or(vis);
+        if let Some(def) = defs.macros.as_mut() {
+            def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis);
         }
 
         let mut changed = false;
@@ -1106,12 +1106,12 @@ impl DefCollector<'_> {
             // Multiple globs may import the same item and they may override visibility from
             // previously resolved globs. Handle overrides here and leave the rest to
             // `ItemScope::push_res_with_import()`.
-            if let Some((def, def_vis, _)) = defs.types {
-                if let Some((prev_def, prev_vis, _)) = prev_defs.types {
-                    if def == prev_def
+            if let Some(def) = defs.types {
+                if let Some(prev_def) = prev_defs.types {
+                    if def.def == prev_def.def
                         && self.from_glob_import.contains_type(module_id, name.clone())
-                        && def_vis != prev_vis
-                        && def_vis.max(prev_vis, &self.def_map) == Some(def_vis)
+                        && def.vis != prev_def.vis
+                        && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
                     {
                         changed = true;
                         // This import is being handled here, don't pass it down to
@@ -1119,41 +1119,41 @@ impl DefCollector<'_> {
                         defs.types = None;
                         self.def_map.modules[module_id]
                             .scope
-                            .update_visibility_types(name, def_vis);
+                            .update_visibility_types(name, def.vis);
                     }
                 }
             }
 
-            if let Some((def, def_vis, _)) = defs.values {
-                if let Some((prev_def, prev_vis, _)) = prev_defs.values {
-                    if def == prev_def
+            if let Some(def) = defs.values {
+                if let Some(prev_def) = prev_defs.values {
+                    if def.def == prev_def.def
                         && self.from_glob_import.contains_value(module_id, name.clone())
-                        && def_vis != prev_vis
-                        && def_vis.max(prev_vis, &self.def_map) == Some(def_vis)
+                        && def.vis != prev_def.vis
+                        && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
                     {
                         changed = true;
                         // See comment above.
                         defs.values = None;
                         self.def_map.modules[module_id]
                             .scope
-                            .update_visibility_values(name, def_vis);
+                            .update_visibility_values(name, def.vis);
                     }
                 }
             }
 
-            if let Some((def, def_vis, _)) = defs.macros {
-                if let Some((prev_def, prev_vis, _)) = prev_defs.macros {
-                    if def == prev_def
+            if let Some(def) = defs.macros {
+                if let Some(prev_def) = prev_defs.macros {
+                    if def.def == prev_def.def
                         && self.from_glob_import.contains_macro(module_id, name.clone())
-                        && def_vis != prev_vis
-                        && def_vis.max(prev_vis, &self.def_map) == Some(def_vis)
+                        && def.vis != prev_def.vis
+                        && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis)
                     {
                         changed = true;
                         // See comment above.
                         defs.macros = None;
                         self.def_map.modules[module_id]
                             .scope
-                            .update_visibility_macros(name, def_vis);
+                            .update_visibility_macros(name, def.vis);
                     }
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
index 29379d00749..8eb195680d1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
@@ -67,8 +67,8 @@ impl PerNs {
         db: &dyn DefDatabase,
         expected: Option<MacroSubNs>,
     ) -> Self {
-        self.macros = self.macros.filter(|&(id, _, _)| {
-            let this = MacroSubNs::from_id(db, id);
+        self.macros = self.macros.filter(|def| {
+            let this = MacroSubNs::from_id(db, def.def);
             sub_namespace_match(Some(this), expected)
         });
 
@@ -411,7 +411,7 @@ impl DefMap {
         original_module: LocalModuleId,
     ) -> ResolvePathResult {
         for (i, segment) in segments {
-            let (curr, vis, imp) = match curr_per_ns.take_types_full() {
+            let curr = match curr_per_ns.take_types_full() {
                 Some(r) => r,
                 None => {
                     // we still have path segments left, but the path so far
@@ -424,7 +424,7 @@ impl DefMap {
             };
             // resolve segment in curr
 
-            curr_per_ns = match curr {
+            curr_per_ns = match curr.def {
                 ModuleDefId::ModuleId(module) => {
                     if module.krate != self.krate {
                         let path = ModPath::from_segments(
@@ -492,7 +492,7 @@ impl DefMap {
                         Some(res) => res,
                         None => {
                             return ResolvePathResult::new(
-                                PerNs::types(e.into(), vis, imp),
+                                PerNs::types(e.into(), curr.vis, curr.import),
                                 ReachedFixedPoint::Yes,
                                 Some(i),
                                 false,
@@ -510,7 +510,7 @@ impl DefMap {
                     );
 
                     return ResolvePathResult::new(
-                        PerNs::types(s, vis, imp),
+                        PerNs::types(s, curr.vis, curr.import),
                         ReachedFixedPoint::Yes,
                         Some(i),
                         false,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
index 1cfbabca28c..c8b7ec463a0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
@@ -331,7 +331,7 @@ pub type Ty = ();
             }
 
             for (_, res) in module_data.scope.resolutions() {
-                match res.values.map(|(a, _, _)| a).or(res.types.map(|(a, _, _)| a)).unwrap() {
+                match res.values.map(|it| it.def).or(res.types.map(|it| it.def)).unwrap() {
                     ModuleDefId::FunctionId(f) => _ = db.function_data(f),
                     ModuleDefId::AdtId(adt) => match adt {
                         AdtId::StructId(it) => _ = db.struct_data(it),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
index 3f3b98c6b5b..899dd4afffe 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
@@ -28,11 +28,22 @@ bitflags! {
     }
 }
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct Item<Def, Import = ImportId> {
+    pub def: Def,
+    pub vis: Visibility,
+    pub import: Option<Import>,
+}
+
+pub type TypesItem = Item<ModuleDefId, ImportOrExternCrate>;
+pub type ValuesItem = Item<ModuleDefId>;
+pub type MacrosItem = Item<MacroId>;
+
 #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
 pub struct PerNs {
-    pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
-    pub values: Option<(ModuleDefId, Visibility, Option<ImportId>)>,
-    pub macros: Option<(MacroId, Visibility, Option<ImportId>)>,
+    pub types: Option<TypesItem>,
+    pub values: Option<ValuesItem>,
+    pub macros: Option<MacrosItem>,
 }
 
 impl PerNs {
@@ -48,29 +59,33 @@ impl PerNs {
         PerNs { types: None, values: None, macros: None }
     }
 
-    pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs {
-        PerNs { types: None, values: Some((t, v, i)), macros: None }
+    pub fn values(def: ModuleDefId, vis: Visibility, import: Option<ImportId>) -> PerNs {
+        PerNs { types: None, values: Some(Item { def, vis, import }), macros: None }
     }
 
-    pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs {
-        PerNs { types: Some((t, v, i)), values: None, macros: None }
+    pub fn types(def: ModuleDefId, vis: Visibility, import: Option<ImportOrExternCrate>) -> PerNs {
+        PerNs { types: Some(Item { def, vis, import }), values: None, macros: None }
     }
 
     pub fn both(
         types: ModuleDefId,
         values: ModuleDefId,
-        v: Visibility,
-        i: Option<ImportOrExternCrate>,
+        vis: Visibility,
+        import: Option<ImportOrExternCrate>,
     ) -> PerNs {
         PerNs {
-            types: Some((types, v, i)),
-            values: Some((values, v, i.and_then(ImportOrExternCrate::into_import))),
+            types: Some(Item { def: types, vis, import }),
+            values: Some(Item {
+                def: values,
+                vis,
+                import: import.and_then(ImportOrExternCrate::into_import),
+            }),
             macros: None,
         }
     }
 
-    pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs {
-        PerNs { types: None, values: None, macros: Some((macro_, v, i)) }
+    pub fn macros(def: MacroId, vis: Visibility, import: Option<ImportId>) -> PerNs {
+        PerNs { types: None, values: None, macros: Some(Item { def, vis, import }) }
     }
 
     pub fn is_none(&self) -> bool {
@@ -82,43 +97,43 @@ impl PerNs {
     }
 
     pub fn take_types(self) -> Option<ModuleDefId> {
-        self.types.map(|it| it.0)
+        self.types.map(|it| it.def)
     }
 
-    pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> {
+    pub fn take_types_full(self) -> Option<TypesItem> {
         self.types
     }
 
     pub fn take_values(self) -> Option<ModuleDefId> {
-        self.values.map(|it| it.0)
+        self.values.map(|it| it.def)
     }
 
     pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> {
-        self.values.map(|it| (it.0, it.2))
+        self.values.map(|it| (it.def, it.import))
     }
 
     pub fn take_macros(self) -> Option<MacroId> {
-        self.macros.map(|it| it.0)
+        self.macros.map(|it| it.def)
     }
 
     pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> {
-        self.macros.map(|it| (it.0, it.2))
+        self.macros.map(|it| (it.def, it.import))
     }
 
     pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
         let _p = tracing::info_span!("PerNs::filter_visibility").entered();
         PerNs {
-            types: self.types.filter(|&(_, v, _)| f(v)),
-            values: self.values.filter(|&(_, v, _)| f(v)),
-            macros: self.macros.filter(|&(_, v, _)| f(v)),
+            types: self.types.filter(|def| f(def.vis)),
+            values: self.values.filter(|def| f(def.vis)),
+            macros: self.macros.filter(|def| f(def.vis)),
         }
     }
 
     pub fn with_visibility(self, vis: Visibility) -> PerNs {
         PerNs {
-            types: self.types.map(|(it, _, c)| (it, vis, c)),
-            values: self.values.map(|(it, _, c)| (it, vis, c)),
-            macros: self.macros.map(|(it, _, import)| (it, vis, import)),
+            types: self.types.map(|def| Item { vis, ..def }),
+            values: self.values.map(|def| Item { vis, ..def }),
+            macros: self.macros.map(|def| Item { vis, ..def }),
         }
     }
 
@@ -141,15 +156,17 @@ impl PerNs {
     pub fn iter_items(self) -> impl Iterator<Item = (ItemInNs, Option<ImportOrExternCrate>)> {
         let _p = tracing::info_span!("PerNs::iter_items").entered();
         self.types
-            .map(|it| (ItemInNs::Types(it.0), it.2))
+            .map(|it| (ItemInNs::Types(it.def), it.import))
             .into_iter()
             .chain(
-                self.values
-                    .map(|it| (ItemInNs::Values(it.0), it.2.map(ImportOrExternCrate::Import))),
+                self.values.map(|it| {
+                    (ItemInNs::Values(it.def), it.import.map(ImportOrExternCrate::Import))
+                }),
             )
             .chain(
-                self.macros
-                    .map(|it| (ItemInNs::Macros(it.0), it.2.map(ImportOrExternCrate::Import))),
+                self.macros.map(|it| {
+                    (ItemInNs::Macros(it.def), it.import.map(ImportOrExternCrate::Import))
+                }),
             )
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 316406c151f..f4dfd42a30e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -933,8 +933,8 @@ impl ModuleItemMap {
                 Some(ResolveValueResult::ValueNs(value, import))
             }
             Some(idx) => {
-                let (def, _, import) = module_def.take_types_full()?;
-                let ty = match def {
+                let def = module_def.take_types_full()?;
+                let ty = match def.def {
                     ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
                     ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
                     ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
@@ -948,7 +948,7 @@ impl ModuleItemMap {
                     | ModuleDefId::MacroId(_)
                     | ModuleDefId::StaticId(_) => return None,
                 };
-                Some(ResolveValueResult::Partial(ty, idx, import))
+                Some(ResolveValueResult::Partial(ty, idx, def.import))
             }
         }
     }
@@ -986,8 +986,8 @@ fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
 }
 
 fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
-    let (def, _, import) = per_ns.take_types_full()?;
-    let res = match def {
+    let def = per_ns.take_types_full()?;
+    let res = match def.def {
         ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
         ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
 
@@ -1003,7 +1003,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
         | ModuleDefId::StaticId(_)
         | ModuleDefId::ModuleId(_) => return None,
     };
-    Some((res, import))
+    Some((res, def.import))
 }
 
 #[derive(Default)]
@@ -1019,14 +1019,14 @@ impl ScopeNames {
         }
     }
     fn add_per_ns(&mut self, name: &Name, def: PerNs) {
-        if let &Some((ty, _, _)) = &def.types {
-            self.add(name, ScopeDef::ModuleDef(ty))
+        if let Some(ty) = &def.types {
+            self.add(name, ScopeDef::ModuleDef(ty.def))
         }
-        if let &Some((def, _, _)) = &def.values {
-            self.add(name, ScopeDef::ModuleDef(def))
+        if let Some(def) = &def.values {
+            self.add(name, ScopeDef::ModuleDef(def.def))
         }
-        if let &Some((mac, _, _)) = &def.macros {
-            self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)))
+        if let Some(mac) = &def.macros {
+            self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac.def)))
         }
         if def.is_none() {
             self.add(name, ScopeDef::Unknown)