Merge #7768
7768: Fix visibility computation when inside a block expression r=jonas-schievink a=jonas-schievink fixes https://github.com/rust-analyzer/rust-analyzer/issues/7728 bors r+ Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
commit
0d5a9e4104
@ -337,6 +337,12 @@ pub fn with_ancestor_maps<T>(
|
||||
None
|
||||
}
|
||||
|
||||
/// If this `DefMap` is for a block expression, returns the module containing the block (which
|
||||
/// might again be a block, or a module inside a block).
|
||||
pub fn parent(&self) -> Option<ModuleId> {
|
||||
Some(self.block?.parent)
|
||||
}
|
||||
|
||||
// FIXME: this can use some more human-readable format (ideally, an IR
|
||||
// even), as this should be a great debugging aid.
|
||||
pub fn dump(&self, db: &dyn DefDatabase) -> String {
|
||||
|
@ -608,7 +608,7 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||
(
|
||||
n,
|
||||
res.filter_visibility(|v| {
|
||||
v.is_visible_from_def_map(&self.def_map, module_id)
|
||||
v.is_visible_from_def_map(self.db, &self.def_map, module_id)
|
||||
}),
|
||||
)
|
||||
})
|
||||
@ -761,7 +761,7 @@ fn update_recursive(
|
||||
.filter(|(glob_importing_module, _)| {
|
||||
// we know all resolutions have the same visibility (`vis`), so we
|
||||
// just need to check that once
|
||||
vis.is_visible_from_def_map(&self.def_map, *glob_importing_module)
|
||||
vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -103,7 +103,7 @@ pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> boo
|
||||
return false;
|
||||
}
|
||||
let def_map = from_module.def_map(db);
|
||||
self.is_visible_from_def_map(&def_map, from_module.local_id)
|
||||
self.is_visible_from_def_map(db, &def_map, from_module.local_id)
|
||||
}
|
||||
|
||||
pub(crate) fn is_visible_from_other_crate(self) -> bool {
|
||||
@ -115,19 +115,41 @@ pub(crate) fn is_visible_from_other_crate(self) -> bool {
|
||||
|
||||
pub(crate) fn is_visible_from_def_map(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
def_map: &DefMap,
|
||||
from_module: crate::LocalModuleId,
|
||||
mut from_module: crate::LocalModuleId,
|
||||
) -> bool {
|
||||
let to_module = match self {
|
||||
Visibility::Module(m) => m,
|
||||
Visibility::Public => return true,
|
||||
};
|
||||
|
||||
// from_module needs to be a descendant of to_module
|
||||
let mut ancestors = std::iter::successors(Some(from_module), |m| {
|
||||
let parent_id = def_map[*m].parent?;
|
||||
Some(parent_id)
|
||||
});
|
||||
ancestors.any(|m| m == to_module.local_id)
|
||||
let mut def_map = def_map;
|
||||
let mut parent_arc;
|
||||
loop {
|
||||
if def_map.module_id(from_module) == to_module {
|
||||
return true;
|
||||
}
|
||||
match def_map[from_module].parent {
|
||||
Some(parent) => {
|
||||
from_module = parent;
|
||||
}
|
||||
None => {
|
||||
match def_map.parent() {
|
||||
Some(module) => {
|
||||
parent_arc = module.def_map(db);
|
||||
def_map = &*parent_arc;
|
||||
from_module = module.local_id;
|
||||
}
|
||||
None => {
|
||||
// Reached the root module, nothing left to check.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the most permissive visibility of `self` and `other`.
|
||||
|
@ -428,4 +428,32 @@ impl S { fn foo(&self) {} }
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_after_macro_call_in_submodule() {
|
||||
check(
|
||||
r#"
|
||||
macro_rules! empty {
|
||||
() => {};
|
||||
}
|
||||
|
||||
mod foo {
|
||||
#[derive(Debug, Default)]
|
||||
struct Template2 {}
|
||||
|
||||
impl Template2 {
|
||||
fn private(&self) {}
|
||||
}
|
||||
fn baz() {
|
||||
let goo: Template2 = Template2 {};
|
||||
empty!();
|
||||
goo.$0
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
me private() -> ()
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user