diff options
author | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
---|---|---|
committer | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
commit | f05d7b41a719d848844b054a16477b29d0f063c6 (patch) | |
tree | 0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_hir_def/src/visibility.rs | |
parent | 73ff610e41959e3e7c78a2b4b25b086883132956 (diff) | |
parent | 6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff) |
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/ra_hir_def/src/visibility.rs')
-rw-r--r-- | crates/ra_hir_def/src/visibility.rs | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs index 8136cb50c..1abffb4c3 100644 --- a/crates/ra_hir_def/src/visibility.rs +++ b/crates/ra_hir_def/src/visibility.rs | |||
@@ -5,6 +5,7 @@ use ra_syntax::ast; | |||
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | db::DefDatabase, | 7 | db::DefDatabase, |
8 | nameres::CrateDefMap, | ||
8 | path::{ModPath, PathKind}, | 9 | path::{ModPath, PathKind}, |
9 | ModuleId, | 10 | ModuleId, |
10 | }; | 11 | }; |
@@ -115,7 +116,7 @@ impl Visibility { | |||
115 | 116 | ||
116 | pub(crate) fn is_visible_from_def_map( | 117 | pub(crate) fn is_visible_from_def_map( |
117 | self, | 118 | self, |
118 | def_map: &crate::nameres::CrateDefMap, | 119 | def_map: &CrateDefMap, |
119 | from_module: crate::LocalModuleId, | 120 | from_module: crate::LocalModuleId, |
120 | ) -> bool { | 121 | ) -> bool { |
121 | let to_module = match self { | 122 | let to_module = match self { |
@@ -129,4 +130,42 @@ impl Visibility { | |||
129 | }); | 130 | }); |
130 | ancestors.any(|m| m == to_module.local_id) | 131 | ancestors.any(|m| m == to_module.local_id) |
131 | } | 132 | } |
133 | |||
134 | /// Returns the most permissive visibility of `self` and `other`. | ||
135 | /// | ||
136 | /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only | ||
137 | /// visible in unrelated modules). | ||
138 | pub(crate) fn max(self, other: Visibility, def_map: &CrateDefMap) -> Option<Visibility> { | ||
139 | match (self, other) { | ||
140 | (Visibility::Module(_), Visibility::Public) | ||
141 | | (Visibility::Public, Visibility::Module(_)) | ||
142 | | (Visibility::Public, Visibility::Public) => Some(Visibility::Public), | ||
143 | (Visibility::Module(mod_a), Visibility::Module(mod_b)) => { | ||
144 | if mod_a.krate != mod_b.krate { | ||
145 | return None; | ||
146 | } | ||
147 | |||
148 | let mut a_ancestors = std::iter::successors(Some(mod_a.local_id), |m| { | ||
149 | let parent_id = def_map[*m].parent?; | ||
150 | Some(parent_id) | ||
151 | }); | ||
152 | let mut b_ancestors = std::iter::successors(Some(mod_b.local_id), |m| { | ||
153 | let parent_id = def_map[*m].parent?; | ||
154 | Some(parent_id) | ||
155 | }); | ||
156 | |||
157 | if a_ancestors.any(|m| m == mod_b.local_id) { | ||
158 | // B is above A | ||
159 | return Some(Visibility::Module(mod_b)); | ||
160 | } | ||
161 | |||
162 | if b_ancestors.any(|m| m == mod_a.local_id) { | ||
163 | // A is above B | ||
164 | return Some(Visibility::Module(mod_a)); | ||
165 | } | ||
166 | |||
167 | None | ||
168 | } | ||
169 | } | ||
170 | } | ||
132 | } | 171 | } |