From 7208498d54b9f3d386b58f901c911a35170057ce Mon Sep 17 00:00:00 2001 From: Josh Mcguigan Date: Tue, 10 Mar 2020 19:58:17 -0700 Subject: fix issue 3444 --- crates/ra_hir/src/code_model.rs | 48 ++++++++++++++++++++++++++++++++--------- crates/ra_hir/src/semantics.rs | 8 ++++++- 2 files changed, 45 insertions(+), 11 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 41d4e2ed3..9e2fa03f8 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -1,6 +1,7 @@ //! FIXME: write short doc here use std::sync::Arc; +use arrayvec::ArrayVec; use either::Either; use hir_def::{ adt::StructKind, @@ -226,7 +227,11 @@ impl Module { Some((name, def)) } }) - .map(|(name, def)| (name.clone(), def.into())) + .flat_map(|(name, def)| + ScopeDef::all_items(def) + .into_iter() + .map(move |item| (name.clone(), item)) + ) .collect() } @@ -1288,15 +1293,38 @@ pub enum ScopeDef { Unknown, } -impl From for ScopeDef { - fn from(def: PerNs) -> Self { - def.take_types() - .or_else(|| def.take_values()) - .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) - .or_else(|| { - def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) - }) - .unwrap_or(ScopeDef::Unknown) +impl ScopeDef { + pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> { + let mut items = ArrayVec::new(); + + match (def.take_types(), def.take_values()) { + (Some(m1), None) => + items.push(ScopeDef::ModuleDef(m1.into())), + (None, Some(m2)) => + items.push(ScopeDef::ModuleDef(m2.into())), + (Some(m1), Some(m2)) => { + // Some items, like unit structs and enum variants, are + // returned as both a type and a value. Here we want + // to de-duplicate them. + if m1 != m2 { + items.push(ScopeDef::ModuleDef(m1.into())); + items.push(ScopeDef::ModuleDef(m2.into())); + } else { + items.push(ScopeDef::ModuleDef(m1.into())); + } + }, + (None, None) => {}, + }; + + if let Some(macro_def_id) = def.take_macros() { + items.push(ScopeDef::MacroDef(macro_def_id.into())); + } + + if items.is_empty() { + items.push(ScopeDef::Unknown); + } + + items } } diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 3782a9984..e83eb1fdc 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -344,7 +344,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> { resolver.process_all_names(self.db, &mut |name, def| { let def = match def { - resolver::ScopeDef::PerNs(it) => it.into(), + resolver::ScopeDef::PerNs(it) => { + let items = ScopeDef::all_items(it); + for item in items { + f(name.clone(), item); + } + return + }, resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }), -- cgit v1.2.3