]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/resolver.rs
Rename `CrateDefMap` to `DefMap`
[rust.git] / crates / hir_def / src / resolver.rs
index f8cc5e075ed8dc62df74eaa832f23220a26b9366..e7e92c72dec784056eba7d428c7b297dd99d8c2c 100644 (file)
     expr::{ExprId, PatId},
     generics::GenericParams,
     item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
-    nameres::CrateDefMap,
+    nameres::DefMap,
     path::{ModPath, PathKind},
     per_ns::PerNs,
     visibility::{RawVisibility, Visibility},
-    AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
-    FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
-    StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
+    AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId,
+    EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId,
+    ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
 };
 
 #[derive(Debug, Clone, Default)]
 pub struct Resolver {
-    // FIXME: all usages generally call `.rev`, so maybe reverse once in consturciton?
+    // FIXME: all usages generally call `.rev`, so maybe reverse once in construction?
     scopes: Vec<Scope>,
 }
 
 // FIXME how to store these best
 #[derive(Debug, Clone)]
 struct ModuleItemMap {
-    crate_def_map: Arc<CrateDefMap>,
+    crate_def_map: Arc<DefMap>,
     module_id: LocalModuleId,
 }
 
@@ -93,6 +93,7 @@ pub enum ValueNs {
     StaticId(StaticId),
     StructId(StructId),
     EnumVariantId(EnumVariantId),
+    GenericParam(ConstParamId),
 }
 
 impl Resolver {
@@ -163,7 +164,7 @@ pub fn resolve_path_in_type_ns(
                 }
 
                 Scope::GenericParams { params, def } => {
-                    if let Some(local_id) = params.find_by_name(first_name) {
+                    if let Some(local_id) = params.find_type_by_name(first_name) {
                         let idx = if path.segments.len() == 1 { None } else { Some(1) };
                         return Some((
                             TypeNs::GenericParam(TypeParamId { local_id, parent: *def }),
@@ -257,7 +258,7 @@ pub fn resolve_path_in_value_ns(
     ) -> Option<ResolveValueResult> {
         let n_segments = path.segments.len();
         let tmp = name![self];
-        let first_name = if path.is_self() { &tmp } else { &path.segments.first()? };
+        let first_name = if path.is_self() { &tmp } else { path.segments.first()? };
         let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
         for scope in self.scopes.iter().rev() {
             match scope {
@@ -285,11 +286,17 @@ pub fn resolve_path_in_value_ns(
                 Scope::ExprScope(_) => continue,
 
                 Scope::GenericParams { params, def } if n_segments > 1 => {
-                    if let Some(local_id) = params.find_by_name(first_name) {
+                    if let Some(local_id) = params.find_type_by_name(first_name) {
                         let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def });
                         return Some(ResolveValueResult::Partial(ty, 1));
                     }
                 }
+                Scope::GenericParams { params, def } if n_segments == 1 => {
+                    if let Some(local_id) = params.find_const_by_name(first_name) {
+                        let val = ValueNs::GenericParam(ConstParamId { local_id, parent: *def });
+                        return Some(ResolveValueResult::ValueNs(val));
+                    }
+                }
                 Scope::GenericParams { .. } => continue,
 
                 Scope::ImplDefScope(impl_) => {
@@ -418,7 +425,7 @@ pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
         traits
     }
 
-    fn module_scope(&self) -> Option<(&CrateDefMap, LocalModuleId)> {
+    fn module_scope(&self) -> Option<(&DefMap, LocalModuleId)> {
         self.scopes.iter().rev().find_map(|scope| match scope {
             Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
 
@@ -483,6 +490,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 +504,9 @@ fn process_names(&self, db: &dyn DefDatabase, f: &mut dyn FnMut(Name, ScopeDef))
                     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 +517,10 @@ fn process_names(&self, db: &dyn DefDatabase, f: &mut dyn FnMut(Name, ScopeDef))
                 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));
+                        let seen_tuple = (name.clone(), def);
+                        if !seen.contains(&seen_tuple) {
+                            f(seen_tuple.0, ScopeDef::PerNs(def));
+                        }
                     });
                 }
             }
@@ -575,11 +588,7 @@ fn push_impl_def_scope(self, impl_def: ImplId) -> Resolver {
         self.push_scope(Scope::ImplDefScope(impl_def))
     }
 
-    fn push_module_scope(
-        self,
-        crate_def_map: Arc<CrateDefMap>,
-        module_id: LocalModuleId,
-    ) -> Resolver {
+    fn push_module_scope(self, crate_def_map: Arc<DefMap>, module_id: LocalModuleId) -> Resolver {
         self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
     }