diff options
Diffstat (limited to 'crates/hir_def/src/visibility.rs')
-rw-r--r-- | crates/hir_def/src/visibility.rs | 36 |
1 files changed, 29 insertions, 7 deletions
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 { | |||
103 | return false; | 103 | return false; |
104 | } | 104 | } |
105 | let def_map = from_module.def_map(db); | 105 | let def_map = from_module.def_map(db); |
106 | self.is_visible_from_def_map(&def_map, from_module.local_id) | 106 | self.is_visible_from_def_map(db, &def_map, from_module.local_id) |
107 | } | 107 | } |
108 | 108 | ||
109 | pub(crate) fn is_visible_from_other_crate(self) -> bool { | 109 | pub(crate) fn is_visible_from_other_crate(self) -> bool { |
@@ -115,19 +115,41 @@ impl Visibility { | |||
115 | 115 | ||
116 | pub(crate) fn is_visible_from_def_map( | 116 | pub(crate) fn is_visible_from_def_map( |
117 | self, | 117 | self, |
118 | db: &dyn DefDatabase, | ||
118 | def_map: &DefMap, | 119 | def_map: &DefMap, |
119 | from_module: crate::LocalModuleId, | 120 | mut from_module: crate::LocalModuleId, |
120 | ) -> bool { | 121 | ) -> bool { |
121 | let to_module = match self { | 122 | let to_module = match self { |
122 | Visibility::Module(m) => m, | 123 | Visibility::Module(m) => m, |
123 | Visibility::Public => return true, | 124 | Visibility::Public => return true, |
124 | }; | 125 | }; |
126 | |||
125 | // from_module needs to be a descendant of to_module | 127 | // from_module needs to be a descendant of to_module |
126 | let mut ancestors = std::iter::successors(Some(from_module), |m| { | 128 | let mut def_map = def_map; |
127 | let parent_id = def_map[*m].parent?; | 129 | let mut parent_arc; |
128 | Some(parent_id) | 130 | loop { |
129 | }); | 131 | if def_map.module_id(from_module) == to_module { |
130 | ancestors.any(|m| m == to_module.local_id) | 132 | return true; |
133 | } | ||
134 | match def_map[from_module].parent { | ||
135 | Some(parent) => { | ||
136 | from_module = parent; | ||
137 | } | ||
138 | None => { | ||
139 | match def_map.parent() { | ||
140 | Some(module) => { | ||
141 | parent_arc = module.def_map(db); | ||
142 | def_map = &*parent_arc; | ||
143 | from_module = module.local_id; | ||
144 | } | ||
145 | None => { | ||
146 | // Reached the root module, nothing left to check. | ||
147 | return false; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | } | ||
131 | } | 153 | } |
132 | 154 | ||
133 | /// Returns the most permissive visibility of `self` and `other`. | 155 | /// Returns the most permissive visibility of `self` and `other`. |