From cf456d72dbdc44dfde9b79b632ee952ea161d5c4 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 23 Feb 2021 14:54:01 +0100 Subject: Add test --- crates/ide_completion/src/completions/dot.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'crates') diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs index 0880a3830..084d7721d 100644 --- a/crates/ide_completion/src/completions/dot.rs +++ b/crates/ide_completion/src/completions/dot.rs @@ -428,4 +428,32 @@ fn main() { make_s!().f$0; } "#]], ) } + + #[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() -> () + "#]], + ); + } } -- cgit v1.2.3 From 338823f73aefbf7957b928ad76fc5f55cc43df9c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 23 Feb 2021 17:56:16 +0100 Subject: is_visible_from_def_map: handle block expressions --- crates/hir_def/src/nameres.rs | 6 ++++++ crates/hir_def/src/nameres/collector.rs | 4 ++-- crates/hir_def/src/visibility.rs | 36 ++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 9 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 34ff07f3c..f92232eb3 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs @@ -337,6 +337,12 @@ impl DefMap { 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 { + 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 { diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 6bd41bc08..9996a0807 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -608,7 +608,7 @@ impl DefCollector<'_> { ( 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 @@ impl DefCollector<'_> { .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::>(); diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs index 38da3132b..0e3951910 100644 --- a/crates/hir_def/src/visibility.rs +++ b/crates/hir_def/src/visibility.rs @@ -103,7 +103,7 @@ impl Visibility { 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 @@ impl Visibility { 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`. -- cgit v1.2.3