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.rs77
1 files changed, 52 insertions, 25 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 323060f61d..f51524c1b5 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -1209,42 +1209,69 @@ impl<'db> DefCollector<'db> {
// `ItemScope::push_res_with_import()`.
if let Some(def) = defs.types
&& let Some(prev_def) = prev_defs.types
- && def.def == prev_def.def
- && self.from_glob_import.contains_type(module_id, name.clone())
- && def.vis != prev_def.vis
- && def.vis.max(self.db, prev_def.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 def.def == prev_def.def
+ && self.from_glob_import.contains_type(module_id, name.clone())
+ && def.vis != prev_def.vis
+ && def.vis.max(self.db, prev_def.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);
+ }
+ // When the source module's definition changed (e.g., due to an explicit import
+ // shadowing a glob), propagate the new definition to modules that glob-import from it.
+ // We check that the previous definition came from the same glob import to avoid
+ // incorrectly overwriting definitions from different glob sources.
+ //
+ // Note this is not a perfect fix, but it makes
+ // https://github.com/rust-lang/rust-analyzer/issues/19224 work for now until we
+ // implement a proper glob graph
+ else if def.def != prev_def.def && prev_def.import == def_import_type {
+ changed = true;
+ defs.types = None;
+ self.def_map.modules[module_id].scope.update_def_types(name, def.def, def.vis);
+ }
}
if let Some(def) = defs.values
&& let Some(prev_def) = prev_defs.values
- && def.def == prev_def.def
- && self.from_glob_import.contains_value(module_id, name.clone())
- && def.vis != prev_def.vis
- && def.vis.max(self.db, prev_def.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 def.def == prev_def.def
+ && self.from_glob_import.contains_value(module_id, name.clone())
+ && def.vis != prev_def.vis
+ && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis)
+ {
+ changed = true;
+ defs.values = None;
+ self.def_map.modules[module_id].scope.update_visibility_values(name, def.vis);
+ } else if def.def != prev_def.def
+ && prev_def.import.map(ImportOrExternCrate::from) == def_import_type
+ {
+ changed = true;
+ defs.values = None;
+ self.def_map.modules[module_id].scope.update_def_values(name, def.def, def.vis);
+ }
}
if let Some(def) = defs.macros
&& let Some(prev_def) = prev_defs.macros
- && def.def == prev_def.def
- && self.from_glob_import.contains_macro(module_id, name.clone())
- && def.vis != prev_def.vis
- && def.vis.max(self.db, prev_def.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);
+ if def.def == prev_def.def
+ && self.from_glob_import.contains_macro(module_id, name.clone())
+ && def.vis != prev_def.vis
+ && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis)
+ {
+ changed = true;
+ defs.macros = None;
+ self.def_map.modules[module_id].scope.update_visibility_macros(name, def.vis);
+ } else if def.def != prev_def.def && prev_def.import == def_import_type {
+ changed = true;
+ defs.macros = None;
+ self.def_map.modules[module_id].scope.update_def_macros(name, def.def, def.vis);
+ }
}
}