aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres/path_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres/path_resolution.rs')
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs72
1 files changed, 56 insertions, 16 deletions
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 695014c7b..fd6422d60 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -21,6 +21,7 @@ use crate::{
21 nameres::{BuiltinShadowMode, CrateDefMap}, 21 nameres::{BuiltinShadowMode, CrateDefMap},
22 path::{ModPath, PathKind}, 22 path::{ModPath, PathKind},
23 per_ns::PerNs, 23 per_ns::PerNs,
24 visibility::{RawVisibility, Visibility},
24 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 25 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
25}; 26};
26 27
@@ -61,7 +62,35 @@ impl ResolvePathResult {
61 62
62impl CrateDefMap { 63impl CrateDefMap {
63 pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { 64 pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs {
64 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)) 65 self.extern_prelude
66 .get(name)
67 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
68 }
69
70 pub(crate) fn resolve_visibility(
71 &self,
72 db: &impl DefDatabase,
73 original_module: LocalModuleId,
74 visibility: &RawVisibility,
75 ) -> Option<Visibility> {
76 match visibility {
77 RawVisibility::Module(path) => {
78 let (result, remaining) =
79 self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
80 if remaining.is_some() {
81 return None;
82 }
83 let types = result.take_types()?;
84 match types {
85 ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)),
86 _ => {
87 // error: visibility needs to refer to module
88 None
89 }
90 }
91 }
92 RawVisibility::Public => Some(Visibility::Public),
93 }
65 } 94 }
66 95
67 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change 96 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
@@ -88,17 +117,21 @@ impl CrateDefMap {
88 PathKind::DollarCrate(krate) => { 117 PathKind::DollarCrate(krate) => {
89 if krate == self.krate { 118 if krate == self.krate {
90 tested_by!(macro_dollar_crate_self); 119 tested_by!(macro_dollar_crate_self);
91 PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into()) 120 PerNs::types(
121 ModuleId { krate: self.krate, local_id: self.root }.into(),
122 Visibility::Public,
123 )
92 } else { 124 } else {
93 let def_map = db.crate_def_map(krate); 125 let def_map = db.crate_def_map(krate);
94 let module = ModuleId { krate, local_id: def_map.root }; 126 let module = ModuleId { krate, local_id: def_map.root };
95 tested_by!(macro_dollar_crate_other); 127 tested_by!(macro_dollar_crate_other);
96 PerNs::types(module.into()) 128 PerNs::types(module.into(), Visibility::Public)
97 } 129 }
98 } 130 }
99 PathKind::Crate => { 131 PathKind::Crate => PerNs::types(
100 PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into()) 132 ModuleId { krate: self.krate, local_id: self.root }.into(),
101 } 133 Visibility::Public,
134 ),
102 // plain import or absolute path in 2015: crate-relative with 135 // plain import or absolute path in 2015: crate-relative with
103 // fallback to extern prelude (with the simplification in 136 // fallback to extern prelude (with the simplification in
104 // rust-lang/rust#57745) 137 // rust-lang/rust#57745)
@@ -126,7 +159,10 @@ impl CrateDefMap {
126 let m = successors(Some(original_module), |m| self.modules[*m].parent) 159 let m = successors(Some(original_module), |m| self.modules[*m].parent)
127 .nth(lvl as usize); 160 .nth(lvl as usize);
128 if let Some(local_id) = m { 161 if let Some(local_id) = m {
129 PerNs::types(ModuleId { krate: self.krate, local_id }.into()) 162 PerNs::types(
163 ModuleId { krate: self.krate, local_id }.into(),
164 Visibility::Public,
165 )
130 } else { 166 } else {
131 log::debug!("super path in root module"); 167 log::debug!("super path in root module");
132 return ResolvePathResult::empty(ReachedFixedPoint::Yes); 168 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
@@ -140,7 +176,7 @@ impl CrateDefMap {
140 }; 176 };
141 if let Some(def) = self.extern_prelude.get(&segment) { 177 if let Some(def) = self.extern_prelude.get(&segment) {
142 log::debug!("absolute path {:?} resolved to crate {:?}", path, def); 178 log::debug!("absolute path {:?} resolved to crate {:?}", path, def);
143 PerNs::types(*def) 179 PerNs::types(*def, Visibility::Public)
144 } else { 180 } else {
145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude 181 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
146 } 182 }
@@ -148,7 +184,7 @@ impl CrateDefMap {
148 }; 184 };
149 185
150 for (i, segment) in segments { 186 for (i, segment) in segments {
151 let curr = match curr_per_ns.take_types() { 187 let (curr, vis) = match curr_per_ns.take_types_vis() {
152 Some(r) => r, 188 Some(r) => r,
153 None => { 189 None => {
154 // we still have path segments left, but the path so far 190 // we still have path segments left, but the path so far
@@ -189,11 +225,11 @@ impl CrateDefMap {
189 match enum_data.variant(&segment) { 225 match enum_data.variant(&segment) {
190 Some(local_id) => { 226 Some(local_id) => {
191 let variant = EnumVariantId { parent: e, local_id }; 227 let variant = EnumVariantId { parent: e, local_id };
192 PerNs::both(variant.into(), variant.into()) 228 PerNs::both(variant.into(), variant.into(), Visibility::Public)
193 } 229 }
194 None => { 230 None => {
195 return ResolvePathResult::with( 231 return ResolvePathResult::with(
196 PerNs::types(e.into()), 232 PerNs::types(e.into(), vis),
197 ReachedFixedPoint::Yes, 233 ReachedFixedPoint::Yes,
198 Some(i), 234 Some(i),
199 Some(self.krate), 235 Some(self.krate),
@@ -211,7 +247,7 @@ impl CrateDefMap {
211 ); 247 );
212 248
213 return ResolvePathResult::with( 249 return ResolvePathResult::with(
214 PerNs::types(s), 250 PerNs::types(s, vis),
215 ReachedFixedPoint::Yes, 251 ReachedFixedPoint::Yes,
216 Some(i), 252 Some(i),
217 Some(self.krate), 253 Some(self.krate),
@@ -235,11 +271,15 @@ impl CrateDefMap {
235 // - current module / scope 271 // - current module / scope
236 // - extern prelude 272 // - extern prelude
237 // - std prelude 273 // - std prelude
238 let from_legacy_macro = 274 let from_legacy_macro = self[module]
239 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); 275 .scope
276 .get_legacy_macro(name)
277 .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
240 let from_scope = self[module].scope.get(name, shadow); 278 let from_scope = self[module].scope.get(name, shadow);
241 let from_extern_prelude = 279 let from_extern_prelude = self
242 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 280 .extern_prelude
281 .get(name)
282 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public));
243 let from_prelude = self.resolve_in_prelude(db, name, shadow); 283 let from_prelude = self.resolve_in_prelude(db, name, shadow);
244 284
245 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) 285 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude)