Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/collector.rs')
-rw-r--r--crates/hir-def/src/nameres/collector.rs87
1 files changed, 82 insertions, 5 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index c51eea22dc..6f435d1f58 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -1025,7 +1025,7 @@ impl DefCollector<'_> {
fn update_recursive(
&mut self,
- // The module for which `resolutions` have been resolve
+ // The module for which `resolutions` have been resolved.
module_id: LocalModuleId,
resolutions: &[(Option<Name>, PerNs)],
// All resolutions are imported with this visibility; the visibilities in
@@ -1043,10 +1043,9 @@ impl DefCollector<'_> {
for (name, res) in resolutions {
match name {
Some(name) => {
- let scope = &mut self.def_map.modules[module_id].scope;
- changed |= scope.push_res_with_import(
- &mut self.from_glob_import,
- (module_id, name.clone()),
+ changed |= self.push_res_and_update_glob_vis(
+ module_id,
+ name,
res.with_visibility(vis),
import,
);
@@ -1112,6 +1111,84 @@ impl DefCollector<'_> {
}
}
+ fn push_res_and_update_glob_vis(
+ &mut self,
+ module_id: LocalModuleId,
+ name: &Name,
+ mut defs: PerNs,
+ def_import_type: Option<ImportType>,
+ ) -> bool {
+ let mut changed = false;
+
+ if let Some(ImportType::Glob(_)) = def_import_type {
+ let prev_defs = self.def_map[module_id].scope.get(name);
+
+ // Multiple globs may import the same item and they may override visibility from
+ // previously resolved globs. Handle overrides here and leave the rest to
+ // `ItemScope::push_res_with_import()`.
+ if let Some((def, def_vis, _)) = defs.types {
+ if let Some((prev_def, prev_vis, _)) = prev_defs.types {
+ if def == prev_def
+ && self.from_glob_import.contains_type(module_id, name.clone())
+ && def_vis != prev_vis
+ && def_vis.max(prev_vis, &self.def_map) == Some(def_vis)
+ {
+ changed = true;
+ // This import is being handled here, don't pass it down to
+ // `ItemScope::push_res_with_import()`.
+ defs.types = None;
+ self.def_map.modules[module_id]
+ .scope
+ .update_visibility_types(name, def_vis);
+ }
+ }
+ }
+
+ if let Some((def, def_vis, _)) = defs.values {
+ if let Some((prev_def, prev_vis, _)) = prev_defs.values {
+ if def == prev_def
+ && self.from_glob_import.contains_value(module_id, name.clone())
+ && def_vis != prev_vis
+ && def_vis.max(prev_vis, &self.def_map) == Some(def_vis)
+ {
+ changed = true;
+ // See comment above.
+ defs.values = None;
+ self.def_map.modules[module_id]
+ .scope
+ .update_visibility_values(name, def_vis);
+ }
+ }
+ }
+
+ if let Some((def, def_vis, _)) = defs.macros {
+ if let Some((prev_def, prev_vis, _)) = prev_defs.macros {
+ if def == prev_def
+ && self.from_glob_import.contains_macro(module_id, name.clone())
+ && def_vis != prev_vis
+ && def_vis.max(prev_vis, &self.def_map) == Some(def_vis)
+ {
+ changed = true;
+ // See comment above.
+ defs.macros = None;
+ self.def_map.modules[module_id]
+ .scope
+ .update_visibility_macros(name, def_vis);
+ }
+ }
+ }
+ }
+
+ changed |= self.def_map.modules[module_id].scope.push_res_with_import(
+ &mut self.from_glob_import,
+ (module_id, name.clone()),
+ defs,
+ def_import_type,
+ );
+
+ changed
+ }
+
fn resolve_macros(&mut self) -> ReachedFixedPoint {
let mut macros = mem::take(&mut self.unresolved_macros);
let mut resolved = Vec::new();