about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_def/src/per_ns.rs2
-rw-r--r--crates/hir_def/src/resolver.rs9
-rw-r--r--crates/hir_def/src/visibility.rs2
3 files changed, 9 insertions, 4 deletions
diff --git a/crates/hir_def/src/per_ns.rs b/crates/hir_def/src/per_ns.rs
index 74665c58851..a594afce668 100644
--- a/crates/hir_def/src/per_ns.rs
+++ b/crates/hir_def/src/per_ns.rs
@@ -7,7 +7,7 @@ use hir_expand::MacroDefId;
 
 use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct PerNs {
     pub types: Option<(ModuleDefId, Visibility)>,
     pub values: Option<(ModuleDefId, Visibility)>,
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index f8cc5e075ed..cc66dcf3196 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -483,6 +483,7 @@ pub enum ScopeDef {
 
 impl Scope {
     fn process_names(&self, db: &dyn DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
+        let mut seen = FxHashSet::default();
         match self {
             Scope::ModuleScope(m) => {
                 // FIXME: should we provide `self` here?
@@ -496,7 +497,9 @@ impl Scope {
                     f(name.clone(), ScopeDef::PerNs(def));
                 });
                 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
-                    f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_, Visibility::Public)));
+                    let scope = PerNs::macros(macro_, Visibility::Public);
+                    seen.insert((name.clone(), scope));
+                    f(name.clone(), ScopeDef::PerNs(scope));
                 });
                 m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| {
                     f(name.clone(), ScopeDef::PerNs(PerNs::types(def, Visibility::Public)));
@@ -507,7 +510,9 @@ impl Scope {
                 if let Some(prelude) = m.crate_def_map.prelude {
                     let prelude_def_map = db.crate_def_map(prelude.krate);
                     prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| {
-                        f(name.clone(), ScopeDef::PerNs(def));
+                        if !seen.contains(&(name.clone(), def)) {
+                            f(name.clone(), ScopeDef::PerNs(def));
+                        }
                     });
                 }
             }
diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs
index e6e0853a30a..f3bc9d68003 100644
--- a/crates/hir_def/src/visibility.rs
+++ b/crates/hir_def/src/visibility.rs
@@ -85,7 +85,7 @@ impl RawVisibility {
 }
 
 /// Visibility of an item, with the path resolved.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum Visibility {
     /// Visibility is restricted to a certain module.
     Module(ModuleId),