aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/visibility.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/visibility.rs')
-rw-r--r--crates/hir_def/src/visibility.rs53
1 files changed, 37 insertions, 16 deletions
diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs
index f3bc9d680..0e3951910 100644
--- a/crates/hir_def/src/visibility.rs
+++ b/crates/hir_def/src/visibility.rs
@@ -5,7 +5,7 @@ use syntax::ast;
5 5
6use crate::{ 6use crate::{
7 db::DefDatabase, 7 db::DefDatabase,
8 nameres::CrateDefMap, 8 nameres::DefMap,
9 path::{ModPath, PathKind}, 9 path::{ModPath, PathKind},
10 ModuleId, 10 ModuleId,
11}; 11};
@@ -22,8 +22,7 @@ pub enum RawVisibility {
22 22
23impl RawVisibility { 23impl RawVisibility {
24 pub(crate) const fn private() -> RawVisibility { 24 pub(crate) const fn private() -> RawVisibility {
25 let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() }; 25 RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)))
26 RawVisibility::Module(path)
27 } 26 }
28 27
29 pub(crate) fn from_ast( 28 pub(crate) fn from_ast(
@@ -59,15 +58,15 @@ impl RawVisibility {
59 RawVisibility::Module(path) 58 RawVisibility::Module(path)
60 } 59 }
61 ast::VisibilityKind::PubCrate => { 60 ast::VisibilityKind::PubCrate => {
62 let path = ModPath { kind: PathKind::Crate, segments: Vec::new() }; 61 let path = ModPath::from_kind(PathKind::Crate);
63 RawVisibility::Module(path) 62 RawVisibility::Module(path)
64 } 63 }
65 ast::VisibilityKind::PubSuper => { 64 ast::VisibilityKind::PubSuper => {
66 let path = ModPath { kind: PathKind::Super(1), segments: Vec::new() }; 65 let path = ModPath::from_kind(PathKind::Super(1));
67 RawVisibility::Module(path) 66 RawVisibility::Module(path)
68 } 67 }
69 ast::VisibilityKind::PubSelf => { 68 ast::VisibilityKind::PubSelf => {
70 let path = ModPath { kind: PathKind::Plain, segments: Vec::new() }; 69 let path = ModPath::from_kind(PathKind::Plain);
71 RawVisibility::Module(path) 70 RawVisibility::Module(path)
72 } 71 }
73 ast::VisibilityKind::Pub => RawVisibility::Public, 72 ast::VisibilityKind::Pub => RawVisibility::Public,
@@ -103,8 +102,8 @@ impl Visibility {
103 if from_module.krate != to_module.krate { 102 if from_module.krate != to_module.krate {
104 return false; 103 return false;
105 } 104 }
106 let def_map = db.crate_def_map(from_module.krate); 105 let def_map = from_module.def_map(db);
107 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)
108 } 107 }
109 108
110 pub(crate) fn is_visible_from_other_crate(self) -> bool { 109 pub(crate) fn is_visible_from_other_crate(self) -> bool {
@@ -116,26 +115,48 @@ impl Visibility {
116 115
117 pub(crate) fn is_visible_from_def_map( 116 pub(crate) fn is_visible_from_def_map(
118 self, 117 self,
119 def_map: &CrateDefMap, 118 db: &dyn DefDatabase,
120 from_module: crate::LocalModuleId, 119 def_map: &DefMap,
120 mut from_module: crate::LocalModuleId,
121 ) -> bool { 121 ) -> bool {
122 let to_module = match self { 122 let to_module = match self {
123 Visibility::Module(m) => m, 123 Visibility::Module(m) => m,
124 Visibility::Public => return true, 124 Visibility::Public => return true,
125 }; 125 };
126
126 // from_module needs to be a descendant of to_module 127 // from_module needs to be a descendant of to_module
127 let mut ancestors = std::iter::successors(Some(from_module), |m| { 128 let mut def_map = def_map;
128 let parent_id = def_map[*m].parent?; 129 let mut parent_arc;
129 Some(parent_id) 130 loop {
130 }); 131 if def_map.module_id(from_module) == to_module {
131 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 }
132 } 153 }
133 154
134 /// Returns the most permissive visibility of `self` and `other`. 155 /// Returns the most permissive visibility of `self` and `other`.
135 /// 156 ///
136 /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only 157 /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only
137 /// visible in unrelated modules). 158 /// visible in unrelated modules).
138 pub(crate) fn max(self, other: Visibility, def_map: &CrateDefMap) -> Option<Visibility> { 159 pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> {
139 match (self, other) { 160 match (self, other) {
140 (Visibility::Module(_), Visibility::Public) 161 (Visibility::Module(_), Visibility::Public)
141 | (Visibility::Public, Visibility::Module(_)) 162 | (Visibility::Public, Visibility::Module(_))