Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/item_scope.rs')
| -rw-r--r-- | crates/hir-def/src/item_scope.rs | 97 |
1 files changed, 70 insertions, 27 deletions
diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 86c3e0f041..df6b1f55c1 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -61,6 +61,18 @@ pub struct ImportId { pub idx: Idx<ast::UseTree>, } +impl PerNsGlobImports { + pub(crate) fn contains_type(&self, module_id: LocalModuleId, name: Name) -> bool { + self.types.contains(&(module_id, name)) + } + pub(crate) fn contains_value(&self, module_id: LocalModuleId, name: Name) -> bool { + self.values.contains(&(module_id, name)) + } + pub(crate) fn contains_macro(&self, module_id: LocalModuleId, name: Name) -> bool { + self.macros.contains(&(module_id, name)) + } +} + #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { /// Defs visible in this scope. This includes `declarations`, but also @@ -510,38 +522,48 @@ impl ItemScope { entry.insert(fld); changed = true; } - Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => { - if glob_imports.types.remove(&lookup) { - let import = match import { - Some(ImportType::ExternCrate(extern_crate)) => { - Some(ImportOrExternCrate::ExternCrate(extern_crate)) - } - Some(ImportType::Import(import)) => { - Some(ImportOrExternCrate::Import(import)) - } - None | Some(ImportType::Glob(_)) => None, - }; - let prev = std::mem::replace(&mut fld.2, import); - if let Some(import) = import { - self.use_imports_types.insert( - import, - match prev { - Some(ImportOrExternCrate::Import(import)) => { - ImportOrDef::Import(import) + Entry::Occupied(mut entry) => { + match import { + Some(ImportType::Glob(..)) => { + // Multiple globs may import the same item and they may + // override visibility from previously resolved globs. This is + // currently handled by `DefCollector`, because we need to + // compute the max visibility for items and we need `DefMap` + // for that. + } + _ => { + if glob_imports.types.remove(&lookup) { + let import = match import { + Some(ImportType::ExternCrate(extern_crate)) => { + Some(ImportOrExternCrate::ExternCrate(extern_crate)) } - Some(ImportOrExternCrate::ExternCrate(import)) => { - ImportOrDef::ExternCrate(import) + Some(ImportType::Import(import)) => { + Some(ImportOrExternCrate::Import(import)) } - None => ImportOrDef::Def(fld.0), - }, - ); + None | Some(ImportType::Glob(_)) => None, + }; + let prev = std::mem::replace(&mut fld.2, import); + if let Some(import) = import { + self.use_imports_types.insert( + import, + match prev { + Some(ImportOrExternCrate::Import(import)) => { + ImportOrDef::Import(import) + } + Some(ImportOrExternCrate::ExternCrate(import)) => { + ImportOrDef::ExternCrate(import) + } + None => ImportOrDef::Def(fld.0), + }, + ); + } + cov_mark::hit!(import_shadowed); + entry.insert(fld); + changed = true; + } } - cov_mark::hit!(import_shadowed); - entry.insert(fld); - changed = true; } } - _ => {} } } @@ -756,6 +778,27 @@ impl ItemScope { } } +// These methods are a temporary measure only meant to be used by `DefCollector::push_res_and_update_glob_vis()`. +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; + } + + 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; + } + + 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; + } +} + impl PerNs { pub(crate) fn from_def( def: ModuleDefId, |