| //! Name resolution façade. | 
 | use std::{fmt, mem}; | 
 |  | 
 | use base_db::Crate; | 
 | use hir_expand::{ | 
 |     MacroDefId, | 
 |     mod_path::{ModPath, PathKind}, | 
 |     name::{AsName, Name}, | 
 | }; | 
 | use intern::{Symbol, sym}; | 
 | use itertools::Itertools as _; | 
 | use rustc_hash::FxHashSet; | 
 | use smallvec::{SmallVec, smallvec}; | 
 | use span::SyntaxContext; | 
 | use syntax::ast::HasName; | 
 | use triomphe::Arc; | 
 |  | 
 | use crate::{ | 
 |     AdtId, AstIdLoc, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, | 
 |     EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, | 
 |     GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, | 
 |     Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, | 
 |     TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UseId, VariantId, | 
 |     builtin_type::BuiltinType, | 
 |     db::DefDatabase, | 
 |     expr_store::{ | 
 |         HygieneId, | 
 |         path::Path, | 
 |         scope::{ExprScopes, ScopeId}, | 
 |     }, | 
 |     hir::{ | 
 |         BindingId, ExprId, LabelId, | 
 |         generics::{GenericParams, TypeOrConstParamData}, | 
 |     }, | 
 |     item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, ItemScope}, | 
 |     lang_item::LangItemTarget, | 
 |     nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map}, | 
 |     per_ns::PerNs, | 
 |     src::HasSource, | 
 |     type_ref::LifetimeRef, | 
 |     visibility::{RawVisibility, Visibility}, | 
 | }; | 
 |  | 
 | #[derive(Debug, Clone)] | 
 | pub struct Resolver<'db> { | 
 |     /// The stack of scopes, where the inner-most scope is the last item. | 
 |     /// | 
 |     /// When using, you generally want to process the scopes in reverse order, | 
 |     /// there's `scopes` *method* for that. | 
 |     scopes: Vec<Scope<'db>>, | 
 |     module_scope: ModuleItemMap<'db>, | 
 | } | 
 |  | 
 | #[derive(Clone)] | 
 | struct ModuleItemMap<'db> { | 
 |     def_map: &'db DefMap, | 
 |     local_def_map: &'db LocalDefMap, | 
 |     module_id: LocalModuleId, | 
 | } | 
 |  | 
 | impl fmt::Debug for ModuleItemMap<'_> { | 
 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
 |         f.debug_struct("ModuleItemMap").field("module_id", &self.module_id).finish() | 
 |     } | 
 | } | 
 |  | 
 | #[derive(Clone)] | 
 | struct ExprScope { | 
 |     owner: DefWithBodyId, | 
 |     expr_scopes: Arc<ExprScopes>, | 
 |     scope_id: ScopeId, | 
 | } | 
 |  | 
 | impl fmt::Debug for ExprScope { | 
 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
 |         f.debug_struct("ExprScope") | 
 |             .field("owner", &self.owner) | 
 |             .field("scope_id", &self.scope_id) | 
 |             .finish() | 
 |     } | 
 | } | 
 |  | 
 | #[derive(Debug, Clone)] | 
 | enum Scope<'db> { | 
 |     /// All the items and imported names of a module | 
 |     BlockScope(ModuleItemMap<'db>), | 
 |     /// Brings the generic parameters of an item into scope as well as the `Self` type alias / | 
 |     /// generic for ADTs and impls. | 
 |     GenericParams { def: GenericDefId, params: Arc<GenericParams> }, | 
 |     /// Local bindings | 
 |     ExprScope(ExprScope), | 
 |     /// Macro definition inside bodies that affects all paths after it in the same block. | 
 |     MacroDefScope(MacroDefId), | 
 | } | 
 |  | 
 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 
 | pub enum TypeNs { | 
 |     SelfType(ImplId), | 
 |     GenericParam(TypeParamId), | 
 |     AdtId(AdtId), | 
 |     AdtSelfType(AdtId), | 
 |     // Yup, enum variants are added to the types ns, but any usage of variant as | 
 |     // type is an error. | 
 |     EnumVariantId(EnumVariantId), | 
 |     TypeAliasId(TypeAliasId), | 
 |     BuiltinType(BuiltinType), | 
 |     TraitId(TraitId), | 
 |     TraitAliasId(TraitAliasId), | 
 |  | 
 |     ModuleId(ModuleId), | 
 | } | 
 |  | 
 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 
 | pub enum ResolveValueResult { | 
 |     ValueNs(ValueNs, Option<ImportOrGlob>), | 
 |     Partial(TypeNs, usize, Option<ImportOrExternCrate>), | 
 | } | 
 |  | 
 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 
 | pub enum ValueNs { | 
 |     ImplSelf(ImplId), | 
 |     LocalBinding(BindingId), | 
 |     FunctionId(FunctionId), | 
 |     ConstId(ConstId), | 
 |     StaticId(StaticId), | 
 |     StructId(StructId), | 
 |     EnumVariantId(EnumVariantId), | 
 |     GenericParam(ConstParamId), | 
 | } | 
 |  | 
 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 
 | pub enum LifetimeNs { | 
 |     Static, | 
 |     LifetimeParam(LifetimeParamId), | 
 | } | 
 |  | 
 | impl<'db> Resolver<'db> { | 
 |     /// Resolve known trait from std, like `std::futures::Future` | 
 |     pub fn resolve_known_trait(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<TraitId> { | 
 |         let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; | 
 |         match res { | 
 |             ModuleDefId::TraitId(it) => Some(it), | 
 |             _ => None, | 
 |         } | 
 |     } | 
 |  | 
 |     /// Resolve known struct from std, like `std::boxed::Box` | 
 |     pub fn resolve_known_struct(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<StructId> { | 
 |         let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; | 
 |         match res { | 
 |             ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), | 
 |             _ => None, | 
 |         } | 
 |     } | 
 |  | 
 |     /// Resolve known enum from std, like `std::result::Result` | 
 |     pub fn resolve_known_enum(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<EnumId> { | 
 |         let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; | 
 |         match res { | 
 |             ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), | 
 |             _ => None, | 
 |         } | 
 |     } | 
 |  | 
 |     pub fn resolve_module_path_in_items(&self, db: &dyn DefDatabase, path: &ModPath) -> PerNs { | 
 |         self.resolve_module_path(db, path, BuiltinShadowMode::Module) | 
 |     } | 
 |  | 
 |     pub fn resolve_path_in_type_ns( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &Path, | 
 |     ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> { | 
 |         self.resolve_path_in_type_ns_with_prefix_info(db, path).map( | 
 |             |(resolution, remaining_segments, import, _)| (resolution, remaining_segments, import), | 
 |         ) | 
 |     } | 
 |  | 
 |     pub fn resolve_path_in_type_ns_with_prefix_info( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &Path, | 
 |     ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)> | 
 |     { | 
 |         let path = match path { | 
 |             Path::BarePath(mod_path) => mod_path, | 
 |             Path::Normal(it) => &it.mod_path, | 
 |             Path::LangItem(l, seg) => { | 
 |                 let type_ns = match *l { | 
 |                     LangItemTarget::Union(it) => TypeNs::AdtId(it.into()), | 
 |                     LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it), | 
 |                     LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()), | 
 |                     LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it), | 
 |                     LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()), | 
 |                     LangItemTarget::Trait(it) => TypeNs::TraitId(it), | 
 |                     LangItemTarget::Function(_) | 
 |                     | LangItemTarget::ImplDef(_) | 
 |                     | LangItemTarget::Static(_) => return None, | 
 |                 }; | 
 |                 return Some(( | 
 |                     type_ns, | 
 |                     seg.as_ref().map(|_| 1), | 
 |                     None, | 
 |                     ResolvePathResultPrefixInfo::default(), | 
 |                 )); | 
 |             } | 
 |         }; | 
 |         let first_name = path.segments().first()?; | 
 |         let skip_to_mod = path.kind != PathKind::Plain; | 
 |         if skip_to_mod { | 
 |             return self.module_scope.resolve_path_in_type_ns(db, path); | 
 |         } | 
 |  | 
 |         let remaining_idx = || { | 
 |             if path.segments().len() == 1 { None } else { Some(1) } | 
 |         }; | 
 |  | 
 |         for scope in self.scopes() { | 
 |             match scope { | 
 |                 Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue, | 
 |                 Scope::GenericParams { params, def } => { | 
 |                     if let &GenericDefId::ImplId(impl_) = def { | 
 |                         if *first_name == sym::Self_ { | 
 |                             return Some(( | 
 |                                 TypeNs::SelfType(impl_), | 
 |                                 remaining_idx(), | 
 |                                 None, | 
 |                                 ResolvePathResultPrefixInfo::default(), | 
 |                             )); | 
 |                         } | 
 |                     } else if let &GenericDefId::AdtId(adt) = def | 
 |                         && *first_name == sym::Self_ | 
 |                     { | 
 |                         return Some(( | 
 |                             TypeNs::AdtSelfType(adt), | 
 |                             remaining_idx(), | 
 |                             None, | 
 |                             ResolvePathResultPrefixInfo::default(), | 
 |                         )); | 
 |                     } | 
 |                     if let Some(id) = params.find_type_by_name(first_name, *def) { | 
 |                         return Some(( | 
 |                             TypeNs::GenericParam(id), | 
 |                             remaining_idx(), | 
 |                             None, | 
 |                             ResolvePathResultPrefixInfo::default(), | 
 |                         )); | 
 |                     } | 
 |                 } | 
 |                 Scope::BlockScope(m) => { | 
 |                     if let Some(res) = m.resolve_path_in_type_ns(db, path) { | 
 |                         let res = match res.0 { | 
 |                             TypeNs::ModuleId(_) if res.1.is_none() => { | 
 |                                 if let Some(ModuleDefId::BuiltinType(builtin)) = BUILTIN_SCOPE | 
 |                                     .get(first_name) | 
 |                                     .and_then(|builtin| builtin.take_types()) | 
 |                                 { | 
 |                                     ( | 
 |                                         TypeNs::BuiltinType(builtin), | 
 |                                         remaining_idx(), | 
 |                                         None, | 
 |                                         ResolvePathResultPrefixInfo::default(), | 
 |                                     ) | 
 |                                 } else { | 
 |                                     res | 
 |                                 } | 
 |                             } | 
 |                             _ => res, | 
 |                         }; | 
 |                         return Some(res); | 
 |                     } | 
 |                 } | 
 |             } | 
 |         } | 
 |         self.module_scope.resolve_path_in_type_ns(db, path) | 
 |     } | 
 |  | 
 |     pub fn resolve_path_in_type_ns_fully( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &Path, | 
 |     ) -> Option<TypeNs> { | 
 |         let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?; | 
 |         if unresolved.is_some() { | 
 |             return None; | 
 |         } | 
 |         Some(res) | 
 |     } | 
 |  | 
 |     pub fn resolve_visibility( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         visibility: &RawVisibility, | 
 |     ) -> Option<Visibility> { | 
 |         match visibility { | 
 |             RawVisibility::Module(_, _) => { | 
 |                 let (item_map, item_local_map, module) = self.item_scope_(); | 
 |                 item_map.resolve_visibility( | 
 |                     item_local_map, | 
 |                     db, | 
 |                     module, | 
 |                     visibility, | 
 |                     self.scopes().any(|scope| { | 
 |                         matches!(scope, Scope::GenericParams { def: GenericDefId::ImplId(_), .. }) | 
 |                     }), | 
 |                 ) | 
 |             } | 
 |             RawVisibility::PubSelf(explicitness) => { | 
 |                 Some(Visibility::Module(self.module(), *explicitness)) | 
 |             } | 
 |             RawVisibility::PubCrate => Some(Visibility::PubCrate(self.krate())), | 
 |             RawVisibility::Public => Some(Visibility::Public), | 
 |         } | 
 |     } | 
 |  | 
 |     pub fn resolve_path_in_value_ns( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &Path, | 
 |         hygiene_id: HygieneId, | 
 |     ) -> Option<ResolveValueResult> { | 
 |         self.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene_id).map(|(it, _)| it) | 
 |     } | 
 |  | 
 |     pub fn resolve_path_in_value_ns_with_prefix_info( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &Path, | 
 |         mut hygiene_id: HygieneId, | 
 |     ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> { | 
 |         let path = match path { | 
 |             Path::BarePath(mod_path) => mod_path, | 
 |             Path::Normal(it) => &it.mod_path, | 
 |             Path::LangItem(l, None) => { | 
 |                 return Some(( | 
 |                     ResolveValueResult::ValueNs( | 
 |                         match *l { | 
 |                             LangItemTarget::Function(it) => ValueNs::FunctionId(it), | 
 |                             LangItemTarget::Static(it) => ValueNs::StaticId(it), | 
 |                             LangItemTarget::Struct(it) => ValueNs::StructId(it), | 
 |                             LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it), | 
 |                             LangItemTarget::Union(_) | 
 |                             | LangItemTarget::ImplDef(_) | 
 |                             | LangItemTarget::TypeAlias(_) | 
 |                             | LangItemTarget::Trait(_) | 
 |                             | LangItemTarget::EnumId(_) => return None, | 
 |                         }, | 
 |                         None, | 
 |                     ), | 
 |                     ResolvePathResultPrefixInfo::default(), | 
 |                 )); | 
 |             } | 
 |             Path::LangItem(l, Some(_)) => { | 
 |                 let type_ns = match *l { | 
 |                     LangItemTarget::Union(it) => TypeNs::AdtId(it.into()), | 
 |                     LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it), | 
 |                     LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()), | 
 |                     LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it), | 
 |                     LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()), | 
 |                     LangItemTarget::Trait(it) => TypeNs::TraitId(it), | 
 |                     LangItemTarget::Function(_) | 
 |                     | LangItemTarget::ImplDef(_) | 
 |                     | LangItemTarget::Static(_) => return None, | 
 |                 }; | 
 |                 // Remaining segments start from 0 because lang paths have no segments other than the remaining. | 
 |                 return Some(( | 
 |                     ResolveValueResult::Partial(type_ns, 0, None), | 
 |                     ResolvePathResultPrefixInfo::default(), | 
 |                 )); | 
 |             } | 
 |         }; | 
 |         let n_segments = path.segments().len(); | 
 |         let tmp = Name::new_symbol_root(sym::self_); | 
 |         let first_name = if path.is_self() { &tmp } else { path.segments().first()? }; | 
 |         let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); | 
 |         if skip_to_mod { | 
 |             return self.module_scope.resolve_path_in_value_ns(db, path); | 
 |         } | 
 |  | 
 |         if n_segments <= 1 { | 
 |             let mut hygiene_info = hygiene_info(db, hygiene_id); | 
 |             for scope in self.scopes() { | 
 |                 match scope { | 
 |                     Scope::ExprScope(scope) => { | 
 |                         let entry = | 
 |                             scope.expr_scopes.entries(scope.scope_id).iter().find(|entry| { | 
 |                                 entry.name() == first_name && entry.hygiene() == hygiene_id | 
 |                             }); | 
 |  | 
 |                         if let Some(e) = entry { | 
 |                             return Some(( | 
 |                                 ResolveValueResult::ValueNs( | 
 |                                     ValueNs::LocalBinding(e.binding()), | 
 |                                     None, | 
 |                                 ), | 
 |                                 ResolvePathResultPrefixInfo::default(), | 
 |                             )); | 
 |                         } | 
 |                     } | 
 |                     Scope::MacroDefScope(macro_id) => { | 
 |                         handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id) | 
 |                     } | 
 |                     Scope::GenericParams { params, def } => { | 
 |                         if let &GenericDefId::ImplId(impl_) = def | 
 |                             && *first_name == sym::Self_ | 
 |                         { | 
 |                             return Some(( | 
 |                                 ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None), | 
 |                                 ResolvePathResultPrefixInfo::default(), | 
 |                             )); | 
 |                         } | 
 |                         if let Some(id) = params.find_const_by_name(first_name, *def) { | 
 |                             let val = ValueNs::GenericParam(id); | 
 |                             return Some(( | 
 |                                 ResolveValueResult::ValueNs(val, None), | 
 |                                 ResolvePathResultPrefixInfo::default(), | 
 |                             )); | 
 |                         } | 
 |                     } | 
 |                     Scope::BlockScope(m) => { | 
 |                         if let Some(def) = m.resolve_path_in_value_ns(db, path) { | 
 |                             return Some(def); | 
 |                         } | 
 |                     } | 
 |                 } | 
 |             } | 
 |         } else { | 
 |             for scope in self.scopes() { | 
 |                 match scope { | 
 |                     Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue, | 
 |                     Scope::GenericParams { params, def } => { | 
 |                         if let &GenericDefId::ImplId(impl_) = def { | 
 |                             if *first_name == sym::Self_ { | 
 |                                 return Some(( | 
 |                                     ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1, None), | 
 |                                     ResolvePathResultPrefixInfo::default(), | 
 |                                 )); | 
 |                             } | 
 |                         } else if let &GenericDefId::AdtId(adt) = def | 
 |                             && *first_name == sym::Self_ | 
 |                         { | 
 |                             let ty = TypeNs::AdtSelfType(adt); | 
 |                             return Some(( | 
 |                                 ResolveValueResult::Partial(ty, 1, None), | 
 |                                 ResolvePathResultPrefixInfo::default(), | 
 |                             )); | 
 |                         } | 
 |                         if let Some(id) = params.find_type_by_name(first_name, *def) { | 
 |                             let ty = TypeNs::GenericParam(id); | 
 |                             return Some(( | 
 |                                 ResolveValueResult::Partial(ty, 1, None), | 
 |                                 ResolvePathResultPrefixInfo::default(), | 
 |                             )); | 
 |                         } | 
 |                     } | 
 |                     Scope::BlockScope(m) => { | 
 |                         if let Some(def) = m.resolve_path_in_value_ns(db, path) { | 
 |                             return Some(def); | 
 |                         } | 
 |                     } | 
 |                 } | 
 |             } | 
 |         } | 
 |  | 
 |         if let Some(res) = self.module_scope.resolve_path_in_value_ns(db, path) { | 
 |             return Some(res); | 
 |         } | 
 |  | 
 |         // If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back | 
 |         // to resolving to the primitive type, to allow this to still work in the presence of | 
 |         // `use core::u16;`. | 
 |         if path.kind == PathKind::Plain | 
 |             && n_segments > 1 | 
 |             && let Some(builtin) = BuiltinType::by_name(first_name) | 
 |         { | 
 |             return Some(( | 
 |                 ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None), | 
 |                 ResolvePathResultPrefixInfo::default(), | 
 |             )); | 
 |         } | 
 |  | 
 |         None | 
 |     } | 
 |  | 
 |     pub fn resolve_path_in_value_ns_fully( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &Path, | 
 |         hygiene: HygieneId, | 
 |     ) -> Option<ValueNs> { | 
 |         match self.resolve_path_in_value_ns(db, path, hygiene)? { | 
 |             ResolveValueResult::ValueNs(it, _) => Some(it), | 
 |             ResolveValueResult::Partial(..) => None, | 
 |         } | 
 |     } | 
 |  | 
 |     pub fn resolve_path_as_macro( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &ModPath, | 
 |         expected_macro_kind: Option<MacroSubNs>, | 
 |     ) -> Option<(MacroId, Option<ImportOrExternCrate>)> { | 
 |         let (item_map, item_local_map, module) = self.item_scope_(); | 
 |         item_map | 
 |             .resolve_path( | 
 |                 item_local_map, | 
 |                 db, | 
 |                 module, | 
 |                 path, | 
 |                 BuiltinShadowMode::Other, | 
 |                 expected_macro_kind, | 
 |             ) | 
 |             .0 | 
 |             .take_macros_import() | 
 |     } | 
 |  | 
 |     pub fn resolve_path_as_macro_def( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &ModPath, | 
 |         expected_macro_kind: Option<MacroSubNs>, | 
 |     ) -> Option<MacroDefId> { | 
 |         self.resolve_path_as_macro(db, path, expected_macro_kind).map(|(it, _)| db.macro_def(it)) | 
 |     } | 
 |  | 
 |     pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option<LifetimeNs> { | 
 |         match lifetime { | 
 |             LifetimeRef::Static => Some(LifetimeNs::Static), | 
 |             LifetimeRef::Named(name) => self.scopes().find_map(|scope| match scope { | 
 |                 Scope::GenericParams { def, params } => { | 
 |                     params.find_lifetime_by_name(name, *def).map(LifetimeNs::LifetimeParam) | 
 |                 } | 
 |                 _ => None, | 
 |             }), | 
 |             LifetimeRef::Placeholder | LifetimeRef::Error => None, | 
 |             LifetimeRef::Param(lifetime_param_id) => { | 
 |                 Some(LifetimeNs::LifetimeParam(*lifetime_param_id)) | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     /// Returns a set of names available in the current scope. | 
 |     /// | 
 |     /// Note that this is a somewhat fuzzy concept -- internally, the compiler | 
 |     /// doesn't necessary follow a strict scoping discipline. Rather, it just | 
 |     /// tells for each ident what it resolves to. | 
 |     /// | 
 |     /// A good example is something like `str::from_utf8`. From scopes point of | 
 |     /// view, this code is erroneous -- both `str` module and `str` type occupy | 
 |     /// the same type namespace. | 
 |     /// | 
 |     /// We don't try to model that super-correctly -- this functionality is | 
 |     /// primarily exposed for completions. | 
 |     /// | 
 |     /// Note that in Rust one name can be bound to several items: | 
 |     /// | 
 |     /// ``` | 
 |     /// # #![allow(non_camel_case_types)] | 
 |     /// macro_rules! t { () => (()) } | 
 |     /// type t = t!(); | 
 |     /// const t: t = t!(); | 
 |     /// ``` | 
 |     /// | 
 |     /// That's why we return a multimap. | 
 |     /// | 
 |     /// The shadowing is accounted for: in | 
 |     /// | 
 |     /// ```ignore | 
 |     /// let it = 92; | 
 |     /// { | 
 |     ///     let it = 92; | 
 |     ///     $0 | 
 |     /// } | 
 |     /// ``` | 
 |     /// | 
 |     /// there will be only one entry for `it` in the result. | 
 |     /// | 
 |     /// The result is ordered *roughly* from the innermost scope to the | 
 |     /// outermost: when the name is introduced in two namespaces in two scopes, | 
 |     /// we use the position of the first scope. | 
 |     pub fn names_in_scope( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |     ) -> FxIndexMap<Name, SmallVec<[ScopeDef; 1]>> { | 
 |         let mut res = ScopeNames::default(); | 
 |         for scope in self.scopes() { | 
 |             scope.process_names(&mut res, db); | 
 |         } | 
 |         let ModuleItemMap { def_map, module_id, local_def_map } = self.module_scope; | 
 |         // FIXME: should we provide `self` here? | 
 |         // f( | 
 |         //     Name::self_param(), | 
 |         //     PerNs::types(Resolution::Def { | 
 |         //         def: m.module.into(), | 
 |         //     }), | 
 |         // ); | 
 |         def_map[module_id].scope.entries().for_each(|(name, def)| { | 
 |             res.add_per_ns(name, def); | 
 |         }); | 
 |  | 
 |         def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| { | 
 |             macs.iter().for_each(|&mac| { | 
 |                 res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac))); | 
 |             }) | 
 |         }); | 
 |         def_map.macro_use_prelude().iter().sorted_by_key(|&(k, _)| k.clone()).for_each( | 
 |             |(name, &(def, _extern_crate))| { | 
 |                 res.add(name, ScopeDef::ModuleDef(def.into())); | 
 |             }, | 
 |         ); | 
 |         local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| { | 
 |             res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into()))); | 
 |         }); | 
 |         BUILTIN_SCOPE.iter().for_each(|(name, &def)| { | 
 |             res.add_per_ns(name, def); | 
 |         }); | 
 |         if let Some((prelude, _use)) = def_map.prelude() { | 
 |             let prelude_def_map = prelude.def_map(db); | 
 |             for (name, def) in prelude_def_map[prelude.local_id].scope.entries() { | 
 |                 res.add_per_ns(name, def) | 
 |             } | 
 |         } | 
 |         res.map | 
 |     } | 
 |  | 
 |     /// Note: Not to be used directly within hir-def/hir-ty | 
 |     pub fn extern_crate_decls_in_scope<'a>( | 
 |         &'a self, | 
 |         db: &'a dyn DefDatabase, | 
 |     ) -> impl Iterator<Item = Name> + 'a { | 
 |         self.module_scope.def_map[self.module_scope.module_id] | 
 |             .scope | 
 |             .extern_crate_decls() | 
 |             .filter_map(|id| { | 
 |                 let loc = id.lookup(db); | 
 |                 let extern_crate = loc.source(db); | 
 |                 // If there is a rename (`as x`), extract the renamed name, or remove the `extern crate` | 
 |                 // if it is an underscore. | 
 |                 extern_crate | 
 |                     .value | 
 |                     .rename() | 
 |                     .map(|a| a.name().map(|it| it.as_name())) | 
 |                     .unwrap_or_else(|| extern_crate.value.name_ref().map(|it| it.as_name())) | 
 |             }) | 
 |     } | 
 |  | 
 |     pub fn extern_crates_in_scope(&self) -> impl Iterator<Item = (Name, ModuleId)> + '_ { | 
 |         self.module_scope | 
 |             .local_def_map | 
 |             .extern_prelude() | 
 |             .map(|(name, module_id)| (name.clone(), module_id.0.into())) | 
 |     } | 
 |  | 
 |     pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> { | 
 |         // FIXME(trait_alias): Trait alias brings aliased traits in scope! Note that supertraits of | 
 |         // aliased traits are NOT brought in scope (unless also aliased). | 
 |         let mut traits = FxHashSet::default(); | 
 |  | 
 |         for scope in self.scopes() { | 
 |             match scope { | 
 |                 Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()), | 
 |                 &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => { | 
 |                     let impl_data = db.impl_signature(impl_); | 
 |                     if let Some(target_trait) = impl_data.target_trait | 
 |                         && let Some(TypeNs::TraitId(trait_)) = self | 
 |                             .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path]) | 
 |                     { | 
 |                         traits.insert(trait_); | 
 |                     } | 
 |                 } | 
 |                 _ => (), | 
 |             } | 
 |         } | 
 |  | 
 |         // Fill in the prelude traits | 
 |         if let Some((prelude, _use)) = self.module_scope.def_map.prelude() { | 
 |             let prelude_def_map = prelude.def_map(db); | 
 |             traits.extend(prelude_def_map[prelude.local_id].scope.traits()); | 
 |         } | 
 |         // Fill in module visible traits | 
 |         traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits()); | 
 |         traits | 
 |     } | 
 |  | 
 |     pub fn traits_in_scope_from_block_scopes(&self) -> impl Iterator<Item = TraitId> + '_ { | 
 |         self.scopes() | 
 |             .filter_map(|scope| match scope { | 
 |                 Scope::BlockScope(m) => Some(m.def_map[m.module_id].scope.traits()), | 
 |                 _ => None, | 
 |             }) | 
 |             .flatten() | 
 |     } | 
 |  | 
 |     pub fn module(&self) -> ModuleId { | 
 |         let (def_map, _, local_id) = self.item_scope_(); | 
 |         def_map.module_id(local_id) | 
 |     } | 
 |  | 
 |     pub fn item_scope(&self) -> &ItemScope { | 
 |         let (def_map, _, local_id) = self.item_scope_(); | 
 |         &def_map[local_id].scope | 
 |     } | 
 |  | 
 |     pub fn krate(&self) -> Crate { | 
 |         self.module_scope.def_map.krate() | 
 |     } | 
 |  | 
 |     pub fn def_map(&self) -> &DefMap { | 
 |         self.item_scope_().0 | 
 |     } | 
 |  | 
 |     pub fn generic_def(&self) -> Option<GenericDefId> { | 
 |         self.scopes().find_map(|scope| match scope { | 
 |             Scope::GenericParams { def, .. } => Some(*def), | 
 |             _ => None, | 
 |         }) | 
 |     } | 
 |  | 
 |     pub fn generic_params(&self) -> Option<&GenericParams> { | 
 |         self.scopes().find_map(|scope| match scope { | 
 |             Scope::GenericParams { params, .. } => Some(&**params), | 
 |             _ => None, | 
 |         }) | 
 |     } | 
 |  | 
 |     pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, &GenericDefId)> { | 
 |         self.scopes().filter_map(|scope| match scope { | 
 |             Scope::GenericParams { params, def } => Some((&**params, def)), | 
 |             _ => None, | 
 |         }) | 
 |     } | 
 |  | 
 |     pub fn body_owner(&self) -> Option<DefWithBodyId> { | 
 |         self.scopes().find_map(|scope| match scope { | 
 |             Scope::ExprScope(it) => Some(it.owner), | 
 |             _ => None, | 
 |         }) | 
 |     } | 
 |  | 
 |     pub fn impl_def(&self) -> Option<ImplId> { | 
 |         self.scopes().find_map(|scope| match scope { | 
 |             &Scope::GenericParams { def: GenericDefId::ImplId(def), .. } => Some(def), | 
 |             _ => None, | 
 |         }) | 
 |     } | 
 |  | 
 |     /// Checks if we rename `renamed` (currently named `current_name`) to `new_name`, will the meaning of this reference | 
 |     /// (that contains `current_name` path) change from `renamed` to some another variable (returned as `Some`). | 
 |     pub fn rename_will_conflict_with_another_variable( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         current_name: &Name, | 
 |         current_name_as_path: &ModPath, | 
 |         mut hygiene_id: HygieneId, | 
 |         new_name: &Symbol, | 
 |         to_be_renamed: BindingId, | 
 |     ) -> Option<BindingId> { | 
 |         let mut hygiene_info = hygiene_info(db, hygiene_id); | 
 |         let mut will_be_resolved_to = None; | 
 |         for scope in self.scopes() { | 
 |             match scope { | 
 |                 Scope::ExprScope(scope) => { | 
 |                     for entry in scope.expr_scopes.entries(scope.scope_id) { | 
 |                         if entry.hygiene() == hygiene_id { | 
 |                             if entry.binding() == to_be_renamed { | 
 |                                 // This currently resolves to our renamed variable, now `will_be_resolved_to` | 
 |                                 // contains `Some` if the meaning will change or `None` if not. | 
 |                                 return will_be_resolved_to; | 
 |                             } else if entry.name().symbol() == new_name { | 
 |                                 will_be_resolved_to = Some(entry.binding()); | 
 |                             } | 
 |                         } | 
 |                     } | 
 |                 } | 
 |                 Scope::MacroDefScope(macro_id) => { | 
 |                     handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id) | 
 |                 } | 
 |                 Scope::GenericParams { params, def } => { | 
 |                     if params.find_const_by_name(current_name, *def).is_some() { | 
 |                         // It does not resolve to our renamed variable. | 
 |                         return None; | 
 |                     } | 
 |                 } | 
 |                 Scope::BlockScope(m) => { | 
 |                     if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() { | 
 |                         // It does not resolve to our renamed variable. | 
 |                         return None; | 
 |                     } | 
 |                 } | 
 |             } | 
 |         } | 
 |         // It does not resolve to our renamed variable. | 
 |         None | 
 |     } | 
 |  | 
 |     /// Checks if we rename `renamed` to `name`, will the meaning of this reference (that contains `name` path) change | 
 |     /// from some other variable (returned as `Some`) to `renamed`. | 
 |     pub fn rename_will_conflict_with_renamed( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         name: &Name, | 
 |         name_as_path: &ModPath, | 
 |         mut hygiene_id: HygieneId, | 
 |         to_be_renamed: BindingId, | 
 |     ) -> Option<BindingId> { | 
 |         let mut hygiene_info = hygiene_info(db, hygiene_id); | 
 |         let mut will_resolve_to_renamed = false; | 
 |         for scope in self.scopes() { | 
 |             match scope { | 
 |                 Scope::ExprScope(scope) => { | 
 |                     for entry in scope.expr_scopes.entries(scope.scope_id) { | 
 |                         if entry.binding() == to_be_renamed { | 
 |                             will_resolve_to_renamed = true; | 
 |                         } else if entry.hygiene() == hygiene_id && entry.name() == name { | 
 |                             if will_resolve_to_renamed { | 
 |                                 // This will resolve to the renamed variable before it resolves to the original variable. | 
 |                                 return Some(entry.binding()); | 
 |                             } else { | 
 |                                 // This will resolve to the original variable. | 
 |                                 return None; | 
 |                             } | 
 |                         } | 
 |                     } | 
 |                 } | 
 |                 Scope::MacroDefScope(macro_id) => { | 
 |                     handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id) | 
 |                 } | 
 |                 Scope::GenericParams { params, def } => { | 
 |                     if params.find_const_by_name(name, *def).is_some() { | 
 |                         // Here and below, it might actually resolve to our renamed variable - in which case it'll | 
 |                         // hide the generic parameter or some other thing (not a variable). We don't check for that | 
 |                         // because due to naming conventions, it is rare that variable will shadow a non-variable. | 
 |                         return None; | 
 |                     } | 
 |                 } | 
 |                 Scope::BlockScope(m) => { | 
 |                     if m.resolve_path_in_value_ns(db, name_as_path).is_some() { | 
 |                         return None; | 
 |                     } | 
 |                 } | 
 |             } | 
 |         } | 
 |         None | 
 |     } | 
 |  | 
 |     /// `expr_id` is required to be an expression id that comes after the top level expression scope in the given resolver | 
 |     #[must_use] | 
 |     pub fn update_to_inner_scope( | 
 |         &mut self, | 
 |         db: &'db dyn DefDatabase, | 
 |         owner: DefWithBodyId, | 
 |         expr_id: ExprId, | 
 |     ) -> UpdateGuard { | 
 |         #[inline(always)] | 
 |         fn append_expr_scope<'db>( | 
 |             db: &'db dyn DefDatabase, | 
 |             resolver: &mut Resolver<'db>, | 
 |             owner: DefWithBodyId, | 
 |             expr_scopes: &Arc<ExprScopes>, | 
 |             scope_id: ScopeId, | 
 |         ) { | 
 |             if let Some(macro_id) = expr_scopes.macro_def(scope_id) { | 
 |                 resolver.scopes.push(Scope::MacroDefScope(**macro_id)); | 
 |             } | 
 |             resolver.scopes.push(Scope::ExprScope(ExprScope { | 
 |                 owner, | 
 |                 expr_scopes: expr_scopes.clone(), | 
 |                 scope_id, | 
 |             })); | 
 |             if let Some(block) = expr_scopes.block(scope_id) { | 
 |                 let def_map = block_def_map(db, block); | 
 |                 let local_def_map = block.lookup(db).module.only_local_def_map(db); | 
 |                 resolver.scopes.push(Scope::BlockScope(ModuleItemMap { | 
 |                     def_map, | 
 |                     local_def_map, | 
 |                     module_id: DefMap::ROOT, | 
 |                 })); | 
 |                 // FIXME: This adds as many module scopes as there are blocks, but resolving in each | 
 |                 // already traverses all parents, so this is O(n²). I think we could only store the | 
 |                 // innermost module scope instead? | 
 |             } | 
 |         } | 
 |  | 
 |         let start = self.scopes.len(); | 
 |         let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_))); | 
 |         match innermost_scope { | 
 |             Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => { | 
 |                 let expr_scopes = expr_scopes.clone(); | 
 |                 let scope_chain = expr_scopes | 
 |                     .scope_chain(expr_scopes.scope_for(expr_id)) | 
 |                     .take_while(|&it| it != scope_id); | 
 |                 for scope_id in scope_chain { | 
 |                     append_expr_scope(db, self, owner, &expr_scopes, scope_id); | 
 |                 } | 
 |             } | 
 |             _ => { | 
 |                 let expr_scopes = db.expr_scopes(owner); | 
 |                 let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id)); | 
 |  | 
 |                 for scope_id in scope_chain { | 
 |                     append_expr_scope(db, self, owner, &expr_scopes, scope_id); | 
 |                 } | 
 |             } | 
 |         } | 
 |         self.scopes[start..].reverse(); | 
 |         UpdateGuard(start) | 
 |     } | 
 |  | 
 |     pub fn reset_to_guard(&mut self, UpdateGuard(start): UpdateGuard) { | 
 |         self.scopes.truncate(start); | 
 |     } | 
 | } | 
 |  | 
 | #[inline] | 
 | fn handle_macro_def_scope( | 
 |     db: &dyn DefDatabase, | 
 |     hygiene_id: &mut HygieneId, | 
 |     hygiene_info: &mut Option<(SyntaxContext, MacroDefId)>, | 
 |     macro_id: &MacroDefId, | 
 | ) { | 
 |     if let Some((parent_ctx, label_macro_id)) = hygiene_info | 
 |         && label_macro_id == macro_id | 
 |     { | 
 |         // A macro is allowed to refer to variables from before its declaration. | 
 |         // Therefore, if we got to the rib of its declaration, give up its hygiene | 
 |         // and use its parent expansion. | 
 |         *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db)); | 
 |         *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| { | 
 |             let expansion = db.lookup_intern_macro_call(expansion.into()); | 
 |             (parent_ctx.parent(db), expansion.def) | 
 |         }); | 
 |     } | 
 | } | 
 |  | 
 | #[inline] | 
 | fn hygiene_info( | 
 |     db: &dyn DefDatabase, | 
 |     hygiene_id: HygieneId, | 
 | ) -> Option<(SyntaxContext, MacroDefId)> { | 
 |     if !hygiene_id.is_root() { | 
 |         let ctx = hygiene_id.lookup(); | 
 |         ctx.outer_expn(db).map(|expansion| { | 
 |             let expansion = db.lookup_intern_macro_call(expansion.into()); | 
 |             (ctx.parent(db), expansion.def) | 
 |         }) | 
 |     } else { | 
 |         None | 
 |     } | 
 | } | 
 |  | 
 | pub struct UpdateGuard(usize); | 
 |  | 
 | impl<'db> Resolver<'db> { | 
 |     fn scopes(&self) -> impl Iterator<Item = &Scope<'db>> { | 
 |         self.scopes.iter().rev() | 
 |     } | 
 |  | 
 |     fn resolve_module_path( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &ModPath, | 
 |         shadow: BuiltinShadowMode, | 
 |     ) -> PerNs { | 
 |         let (item_map, item_local_map, module) = self.item_scope_(); | 
 |         // This method resolves `path` just like import paths, so no expected macro subns is given. | 
 |         let (module_res, segment_index) = | 
 |             item_map.resolve_path(item_local_map, db, module, path, shadow, None); | 
 |         if segment_index.is_some() { | 
 |             return PerNs::none(); | 
 |         } | 
 |         module_res | 
 |     } | 
 |  | 
 |     /// The innermost block scope that contains items or the module scope that contains this resolver. | 
 |     fn item_scope_(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) { | 
 |         self.scopes() | 
 |             .find_map(|scope| match scope { | 
 |                 Scope::BlockScope(m) => Some((m.def_map, m.local_def_map, m.module_id)), | 
 |                 _ => None, | 
 |             }) | 
 |             .unwrap_or(( | 
 |                 self.module_scope.def_map, | 
 |                 self.module_scope.local_def_map, | 
 |                 self.module_scope.module_id, | 
 |             )) | 
 |     } | 
 | } | 
 |  | 
 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | 
 | pub enum ScopeDef { | 
 |     ModuleDef(ModuleDefId), | 
 |     Unknown, | 
 |     ImplSelfType(ImplId), | 
 |     AdtSelfType(AdtId), | 
 |     GenericParam(GenericParamId), | 
 |     Local(BindingId), | 
 |     Label(LabelId), | 
 | } | 
 |  | 
 | impl<'db> Scope<'db> { | 
 |     fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) { | 
 |         match self { | 
 |             Scope::BlockScope(m) => { | 
 |                 m.def_map[m.module_id].scope.entries().for_each(|(name, def)| { | 
 |                     acc.add_per_ns(name, def); | 
 |                 }); | 
 |                 m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| { | 
 |                     macs.iter().for_each(|&mac| { | 
 |                         acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac))); | 
 |                     }) | 
 |                 }); | 
 |             } | 
 |             &Scope::GenericParams { ref params, def: parent } => { | 
 |                 if let GenericDefId::ImplId(impl_) = parent { | 
 |                     acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(impl_)); | 
 |                 } else if let GenericDefId::AdtId(adt) = parent { | 
 |                     acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(adt)); | 
 |                 } | 
 |  | 
 |                 for (local_id, param) in params.iter_type_or_consts() { | 
 |                     if let Some(name) = ¶m.name() { | 
 |                         let id = TypeOrConstParamId { parent, local_id }; | 
 |                         let data = &db.generic_params(parent)[local_id]; | 
 |                         acc.add( | 
 |                             name, | 
 |                             ScopeDef::GenericParam(match data { | 
 |                                 TypeOrConstParamData::TypeParamData(_) => { | 
 |                                     GenericParamId::TypeParamId(TypeParamId::from_unchecked(id)) | 
 |                                 } | 
 |                                 TypeOrConstParamData::ConstParamData(_) => { | 
 |                                     GenericParamId::ConstParamId(ConstParamId::from_unchecked(id)) | 
 |                                 } | 
 |                             }), | 
 |                         ); | 
 |                     } | 
 |                 } | 
 |                 for (local_id, param) in params.iter_lt() { | 
 |                     let id = LifetimeParamId { parent, local_id }; | 
 |                     acc.add(¶m.name, ScopeDef::GenericParam(id.into())) | 
 |                 } | 
 |             } | 
 |             Scope::ExprScope(scope) => { | 
 |                 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) { | 
 |                     acc.add(&name, ScopeDef::Label(label)) | 
 |                 } | 
 |                 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { | 
 |                     acc.add_local(e.name(), e.binding()); | 
 |                 }); | 
 |             } | 
 |             Scope::MacroDefScope(_) => {} | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | pub fn resolver_for_scope( | 
 |     db: &dyn DefDatabase, | 
 |     owner: DefWithBodyId, | 
 |     scope_id: Option<ScopeId>, | 
 | ) -> Resolver<'_> { | 
 |     let r = owner.resolver(db); | 
 |     let scopes = db.expr_scopes(owner); | 
 |     resolver_for_scope_(db, scopes, scope_id, r, owner) | 
 | } | 
 |  | 
 | fn resolver_for_scope_<'db>( | 
 |     db: &'db dyn DefDatabase, | 
 |     scopes: Arc<ExprScopes>, | 
 |     scope_id: Option<ScopeId>, | 
 |     mut r: Resolver<'db>, | 
 |     owner: DefWithBodyId, | 
 | ) -> Resolver<'db> { | 
 |     let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); | 
 |     r.scopes.reserve(scope_chain.len()); | 
 |  | 
 |     for scope in scope_chain.into_iter().rev() { | 
 |         if let Some(block) = scopes.block(scope) { | 
 |             let def_map = block_def_map(db, block); | 
 |             let local_def_map = block.lookup(db).module.only_local_def_map(db); | 
 |             r = r.push_block_scope(def_map, local_def_map); | 
 |             // FIXME: This adds as many module scopes as there are blocks, but resolving in each | 
 |             // already traverses all parents, so this is O(n²). I think we could only store the | 
 |             // innermost module scope instead? | 
 |         } | 
 |         if let Some(macro_id) = scopes.macro_def(scope) { | 
 |             r = r.push_scope(Scope::MacroDefScope(**macro_id)); | 
 |         } | 
 |  | 
 |         r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); | 
 |     } | 
 |     r | 
 | } | 
 |  | 
 | impl<'db> Resolver<'db> { | 
 |     fn push_scope(mut self, scope: Scope<'db>) -> Resolver<'db> { | 
 |         self.scopes.push(scope); | 
 |         self | 
 |     } | 
 |  | 
 |     fn push_generic_params_scope( | 
 |         self, | 
 |         db: &'db dyn DefDatabase, | 
 |         def: GenericDefId, | 
 |     ) -> Resolver<'db> { | 
 |         let params = db.generic_params(def); | 
 |         self.push_scope(Scope::GenericParams { def, params }) | 
 |     } | 
 |  | 
 |     fn push_block_scope( | 
 |         self, | 
 |         def_map: &'db DefMap, | 
 |         local_def_map: &'db LocalDefMap, | 
 |     ) -> Resolver<'db> { | 
 |         self.push_scope(Scope::BlockScope(ModuleItemMap { | 
 |             def_map, | 
 |             local_def_map, | 
 |             module_id: DefMap::ROOT, | 
 |         })) | 
 |     } | 
 |  | 
 |     fn push_expr_scope( | 
 |         self, | 
 |         owner: DefWithBodyId, | 
 |         expr_scopes: Arc<ExprScopes>, | 
 |         scope_id: ScopeId, | 
 |     ) -> Resolver<'db> { | 
 |         self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) | 
 |     } | 
 | } | 
 |  | 
 | impl<'db> ModuleItemMap<'db> { | 
 |     fn resolve_path_in_value_ns( | 
 |         &self, | 
 |         db: &'db dyn DefDatabase, | 
 |         path: &ModPath, | 
 |     ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> { | 
 |         let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally( | 
 |             self.local_def_map, | 
 |             db, | 
 |             self.module_id, | 
 |             path, | 
 |             BuiltinShadowMode::Other, | 
 |         ); | 
 |         match unresolved_idx { | 
 |             None => { | 
 |                 let (value, import) = to_value_ns(module_def)?; | 
 |                 Some((ResolveValueResult::ValueNs(value, import), prefix_info)) | 
 |             } | 
 |             Some(unresolved_idx) => { | 
 |                 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), | 
 |                     ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | 
 |                     ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 
 |  | 
 |                     ModuleDefId::ModuleId(_) | 
 |                     | ModuleDefId::FunctionId(_) | 
 |                     | ModuleDefId::EnumVariantId(_) | 
 |                     | ModuleDefId::ConstId(_) | 
 |                     | ModuleDefId::MacroId(_) | 
 |                     | ModuleDefId::StaticId(_) => return None, | 
 |                 }; | 
 |                 Some((ResolveValueResult::Partial(ty, unresolved_idx, def.import), prefix_info)) | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     fn resolve_path_in_type_ns( | 
 |         &self, | 
 |         db: &dyn DefDatabase, | 
 |         path: &ModPath, | 
 |     ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)> | 
 |     { | 
 |         let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally( | 
 |             self.local_def_map, | 
 |             db, | 
 |             self.module_id, | 
 |             path, | 
 |             BuiltinShadowMode::Other, | 
 |         ); | 
 |         let (res, import) = to_type_ns(module_def)?; | 
 |         Some((res, idx, import, prefix_info)) | 
 |     } | 
 | } | 
 |  | 
 | fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> { | 
 |     let (def, import) = per_ns.take_values_import()?; | 
 |     let res = match def { | 
 |         ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), | 
 |         ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), | 
 |         ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), | 
 |         ModuleDefId::ConstId(it) => ValueNs::ConstId(it), | 
 |         ModuleDefId::StaticId(it) => ValueNs::StaticId(it), | 
 |  | 
 |         ModuleDefId::AdtId(AdtId::EnumId(_) | AdtId::UnionId(_)) | 
 |         | ModuleDefId::TraitId(_) | 
 |         | ModuleDefId::TraitAliasId(_) | 
 |         | ModuleDefId::TypeAliasId(_) | 
 |         | ModuleDefId::BuiltinType(_) | 
 |         | ModuleDefId::MacroId(_) | 
 |         | ModuleDefId::ModuleId(_) => return None, | 
 |     }; | 
 |     Some((res, import)) | 
 | } | 
 |  | 
 | fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> { | 
 |     let def = per_ns.take_types_full()?; | 
 |     let res = match def.def { | 
 |         ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | 
 |         ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), | 
 |  | 
 |         ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | 
 |         ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 
 |  | 
 |         ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | 
 |         ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it), | 
 |  | 
 |         ModuleDefId::ModuleId(it) => TypeNs::ModuleId(it), | 
 |  | 
 |         ModuleDefId::FunctionId(_) | 
 |         | ModuleDefId::ConstId(_) | 
 |         | ModuleDefId::MacroId(_) | 
 |         | ModuleDefId::StaticId(_) => return None, | 
 |     }; | 
 |     Some((res, def.import)) | 
 | } | 
 |  | 
 | #[derive(Default)] | 
 | struct ScopeNames { | 
 |     map: FxIndexMap<Name, SmallVec<[ScopeDef; 1]>>, | 
 | } | 
 |  | 
 | impl ScopeNames { | 
 |     fn add(&mut self, name: &Name, def: ScopeDef) { | 
 |         let set = self.map.entry(name.clone()).or_default(); | 
 |         if !set.contains(&def) { | 
 |             set.push(def) | 
 |         } | 
 |     } | 
 |     fn add_per_ns(&mut self, name: &Name, def: PerNs) { | 
 |         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.def)) | 
 |         } | 
 |         if let Some(mac) = &def.macros { | 
 |             self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac.def))) | 
 |         } | 
 |         if def.is_none() { | 
 |             self.add(name, ScopeDef::Unknown) | 
 |         } | 
 |     } | 
 |     fn add_local(&mut self, name: &Name, binding: BindingId) { | 
 |         let set = self.map.entry(name.clone()).or_default(); | 
 |         // XXX: hack, account for local (and only local) shadowing. | 
 |         // | 
 |         // This should be somewhat more principled and take namespaces into | 
 |         // accounts, but, alas, scoping rules are a hoax. `str` type and `str` | 
 |         // module can be both available in the same scope. | 
 |         if set.iter().any(|it| matches!(it, &ScopeDef::Local(_))) { | 
 |             cov_mark::hit!(shadowing_shows_single_completion); | 
 |             return; | 
 |         } | 
 |         set.push(ScopeDef::Local(binding)) | 
 |     } | 
 | } | 
 |  | 
 | pub trait HasResolver: Copy { | 
 |     /// Builds a resolver for type references inside this def. | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_>; | 
 | } | 
 |  | 
 | impl HasResolver for ModuleId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         let (mut def_map, local_def_map) = self.local_def_map(db); | 
 |         let mut module_id = self.local_id; | 
 |  | 
 |         if !self.is_block_module() { | 
 |             return Resolver { | 
 |                 scopes: vec![], | 
 |                 module_scope: ModuleItemMap { def_map, local_def_map, module_id }, | 
 |             }; | 
 |         } | 
 |  | 
 |         let mut modules: SmallVec<[_; 1]> = smallvec![]; | 
 |         while let Some(parent) = def_map.parent() { | 
 |             let block_def_map = mem::replace(&mut def_map, parent.def_map(db)); | 
 |             modules.push(block_def_map); | 
 |             if !parent.is_block_module() { | 
 |                 module_id = parent.local_id; | 
 |                 break; | 
 |             } | 
 |         } | 
 |         let mut resolver = Resolver { | 
 |             scopes: Vec::with_capacity(modules.len()), | 
 |             module_scope: ModuleItemMap { def_map, local_def_map, module_id }, | 
 |         }; | 
 |         for def_map in modules.into_iter().rev() { | 
 |             resolver = resolver.push_block_scope(def_map, local_def_map); | 
 |         } | 
 |         resolver | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for CrateRootModuleId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         let (def_map, local_def_map) = self.local_def_map(db); | 
 |         Resolver { | 
 |             scopes: vec![], | 
 |             module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT }, | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for TraitId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self).push_generic_params_scope(db, self.into()) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for TraitAliasId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self).push_generic_params_scope(db, self.into()) | 
 |     } | 
 | } | 
 |  | 
 | impl<T: Into<AdtId> + Copy> HasResolver for T { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         let def = self.into(); | 
 |         def.module(db).resolver(db).push_generic_params_scope(db, def.into()) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for FunctionId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self).push_generic_params_scope(db, self.into()) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for ConstId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for StaticId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for TypeAliasId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self).push_generic_params_scope(db, self.into()) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for ImplId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for ExternBlockId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         // Same as parent's | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for ExternCrateId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for UseId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for DefWithBodyId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         match self { | 
 |             DefWithBodyId::ConstId(c) => c.resolver(db), | 
 |             DefWithBodyId::FunctionId(f) => f.resolver(db), | 
 |             DefWithBodyId::StaticId(s) => s.resolver(db), | 
 |             DefWithBodyId::VariantId(v) => v.resolver(db), | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for ItemContainerId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         match self { | 
 |             ItemContainerId::ModuleId(it) => it.resolver(db), | 
 |             ItemContainerId::TraitId(it) => it.resolver(db), | 
 |             ItemContainerId::ImplId(it) => it.resolver(db), | 
 |             ItemContainerId::ExternBlockId(it) => it.resolver(db), | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for GenericDefId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         match self { | 
 |             GenericDefId::FunctionId(inner) => inner.resolver(db), | 
 |             GenericDefId::AdtId(adt) => adt.resolver(db), | 
 |             GenericDefId::TraitId(inner) => inner.resolver(db), | 
 |             GenericDefId::TraitAliasId(inner) => inner.resolver(db), | 
 |             GenericDefId::TypeAliasId(inner) => inner.resolver(db), | 
 |             GenericDefId::ImplId(inner) => inner.resolver(db), | 
 |             GenericDefId::ConstId(inner) => inner.resolver(db), | 
 |             GenericDefId::StaticId(inner) => inner.resolver(db), | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for EnumVariantId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         self.lookup(db).parent.resolver(db) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for VariantId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         match self { | 
 |             VariantId::EnumVariantId(it) => it.resolver(db), | 
 |             VariantId::StructId(it) => it.resolver(db), | 
 |             VariantId::UnionId(it) => it.resolver(db), | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for MacroId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         match self { | 
 |             MacroId::Macro2Id(it) => it.resolver(db), | 
 |             MacroId::MacroRulesId(it) => it.resolver(db), | 
 |             MacroId::ProcMacroId(it) => it.resolver(db), | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for Macro2Id { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for ProcMacroId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | impl HasResolver for MacroRulesId { | 
 |     fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { | 
 |         lookup_resolver(db, self) | 
 |     } | 
 | } | 
 |  | 
 | fn lookup_resolver( | 
 |     db: &dyn DefDatabase, | 
 |     lookup: impl Lookup<Database = dyn DefDatabase, Data = impl AstIdLoc<Container = impl HasResolver>>, | 
 | ) -> Resolver<'_> { | 
 |     lookup.lookup(db).container().resolver(db) | 
 | } |