diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-def/src/visibility.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/hir-def/src/visibility.rs | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index 087268a9e..ab76ed43d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -11,7 +11,7 @@ use crate::{ nameres::DefMap, path::{ModPath, PathKind}, resolver::HasResolver, - ConstId, FunctionId, HasModule, LocalFieldId, ModuleId, VariantId, + ConstId, FunctionId, HasModule, LocalFieldId, LocalModuleId, ModuleId, VariantId, }; /// Visibility of an item, not yet resolved. @@ -120,7 +120,7 @@ impl Visibility { self, db: &dyn DefDatabase, def_map: &DefMap, - mut from_module: crate::LocalModuleId, + mut from_module: LocalModuleId, ) -> bool { let mut to_module = match self { Visibility::Module(m) => m, @@ -131,20 +131,23 @@ impl Visibility { // visibility as the containing module (even though no items are directly nameable from // there, getting this right is important for method resolution). // In that case, we adjust the visibility of `to_module` to point to the containing module. + // Additional complication: `to_module` might be in `from_module`'s `DefMap`, which we're // currently computing, so we must not call the `def_map` query for it. - let arc; - let to_module_def_map = - if to_module.krate == def_map.krate() && to_module.block == def_map.block_id() { - cov_mark::hit!(is_visible_from_same_block_def_map); - def_map - } else { - arc = to_module.def_map(db); - &arc - }; - let is_block_root = matches!(to_module.block, Some(_) if to_module_def_map[to_module.local_id].parent.is_none()); - if is_block_root { - to_module = to_module_def_map.containing_module(to_module.local_id).unwrap(); + let mut arc; + loop { + let to_module_def_map = + if to_module.krate == def_map.krate() && to_module.block == def_map.block_id() { + cov_mark::hit!(is_visible_from_same_block_def_map); + def_map + } else { + arc = to_module.def_map(db); + &arc + }; + match to_module_def_map.parent() { + Some(parent) => to_module = parent, + None => break, + } } // from_module needs to be a descendant of to_module |