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.rs97
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,