aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres')
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs71
2 files changed, 60 insertions, 15 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index fd8245113..d4bfcae1d 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -19,7 +19,7 @@ use crate::{
19 db::DefDatabase, 19 db::DefDatabase,
20 nameres::{ 20 nameres::{
21 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 21 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
22 raw, CrateDefMap, ModuleData, Resolution, ResolveMode, 22 raw, BuiltinShadowMode, CrateDefMap, ModuleData, Resolution, ResolveMode,
23 }, 23 },
24 path::{Path, PathKind}, 24 path::{Path, PathKind},
25 per_ns::PerNs, 25 per_ns::PerNs,
@@ -299,6 +299,7 @@ where
299 ResolveMode::Import, 299 ResolveMode::Import,
300 module_id, 300 module_id,
301 &import.path, 301 &import.path,
302 BuiltinShadowMode::Module,
302 ); 303 );
303 304
304 (res.resolved_def, res.reached_fixedpoint) 305 (res.resolved_def, res.reached_fixedpoint)
@@ -477,6 +478,7 @@ where
477 ResolveMode::Other, 478 ResolveMode::Other,
478 *module_id, 479 *module_id,
479 path, 480 path,
481 BuiltinShadowMode::Module,
480 ); 482 );
481 483
482 if let Some(def) = resolved_res.resolved_def.take_macros() { 484 if let Some(def) = resolved_res.resolved_def.take_macros() {
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index b72c55bd1..174ae9d38 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -16,7 +16,7 @@ use test_utils::tested_by;
16 16
17use crate::{ 17use crate::{
18 db::DefDatabase, 18 db::DefDatabase,
19 nameres::CrateDefMap, 19 nameres::{BuiltinShadowMode, CrateDefMap},
20 path::{Path, PathKind}, 20 path::{Path, PathKind},
21 per_ns::PerNs, 21 per_ns::PerNs,
22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
@@ -68,8 +68,10 @@ impl CrateDefMap {
68 mode: ResolveMode, 68 mode: ResolveMode,
69 original_module: LocalModuleId, 69 original_module: LocalModuleId,
70 path: &Path, 70 path: &Path,
71 shadow: BuiltinShadowMode,
71 ) -> ResolvePathResult { 72 ) -> ResolvePathResult {
72 let mut segments = path.segments.iter().enumerate(); 73 let mut segments = path.segments.iter().enumerate().peekable();
74
73 let mut curr_per_ns: PerNs = match path.kind { 75 let mut curr_per_ns: PerNs = match path.kind {
74 PathKind::DollarCrate(krate) => { 76 PathKind::DollarCrate(krate) => {
75 if krate == self.krate { 77 if krate == self.krate {
@@ -101,7 +103,11 @@ impl CrateDefMap {
101 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 103 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
102 }; 104 };
103 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); 105 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
104 self.resolve_name_in_crate_root_or_extern_prelude(&segment.name) 106
107 self.resolve_name_in_crate_root_or_extern_prelude(
108 &segment.name,
109 prefer_module(&mut segments, shadow),
110 )
105 } 111 }
106 PathKind::Plain => { 112 PathKind::Plain => {
107 let segment = match segments.next() { 113 let segment = match segments.next() {
@@ -109,7 +115,12 @@ impl CrateDefMap {
109 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 115 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
110 }; 116 };
111 log::debug!("resolving {:?} in module", segment); 117 log::debug!("resolving {:?} in module", segment);
112 self.resolve_name_in_module(db, original_module, &segment.name) 118 self.resolve_name_in_module(
119 db,
120 original_module,
121 &segment.name,
122 prefer_module(&mut segments, shadow),
123 )
113 } 124 }
114 PathKind::Super => { 125 PathKind::Super => {
115 if let Some(p) = self.modules[original_module].parent { 126 if let Some(p) = self.modules[original_module].parent {
@@ -139,7 +150,7 @@ impl CrateDefMap {
139 } 150 }
140 }; 151 };
141 152
142 for (i, segment) in segments { 153 while let Some((i, segment)) = segments.next() {
143 let curr = match curr_per_ns.take_types() { 154 let curr = match curr_per_ns.take_types() {
144 Some(r) => r, 155 Some(r) => r,
145 None => { 156 None => {
@@ -160,7 +171,7 @@ impl CrateDefMap {
160 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; 171 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
161 log::debug!("resolving {:?} in other crate", path); 172 log::debug!("resolving {:?} in other crate", path);
162 let defp_map = db.crate_def_map(module.krate); 173 let defp_map = db.crate_def_map(module.krate);
163 let (def, s) = defp_map.resolve_path(db, module.local_id, &path); 174 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
164 return ResolvePathResult::with( 175 return ResolvePathResult::with(
165 def, 176 def,
166 ReachedFixedPoint::Yes, 177 ReachedFixedPoint::Yes,
@@ -169,7 +180,10 @@ impl CrateDefMap {
169 } 180 }
170 181
171 // Since it is a qualified path here, it should not contains legacy macros 182 // Since it is a qualified path here, it should not contains legacy macros
172 match self[module.local_id].scope.get(&segment.name) { 183 match self[module.local_id]
184 .scope
185 .get(&segment.name, prefer_module(&mut segments, shadow))
186 {
173 Some(res) => res.def, 187 Some(res) => res.def,
174 _ => { 188 _ => {
175 log::debug!("path segment {:?} not found", segment.name); 189 log::debug!("path segment {:?} not found", segment.name);
@@ -212,7 +226,22 @@ impl CrateDefMap {
212 } 226 }
213 }; 227 };
214 } 228 }
215 ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) 229 return ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None);
230
231 // if it is not the last segment, we prefer builtin as module
232 fn prefer_module<I>(
233 segments: &mut std::iter::Peekable<I>,
234 shadow: BuiltinShadowMode,
235 ) -> BuiltinShadowMode
236 where
237 I: Iterator,
238 {
239 if segments.peek().is_some() {
240 BuiltinShadowMode::Module
241 } else {
242 shadow
243 }
244 }
216 } 245 }
217 246
218 fn resolve_name_in_module( 247 fn resolve_name_in_module(
@@ -220,6 +249,7 @@ impl CrateDefMap {
220 db: &impl DefDatabase, 249 db: &impl DefDatabase,
221 module: LocalModuleId, 250 module: LocalModuleId,
222 name: &Name, 251 name: &Name,
252 shadow: BuiltinShadowMode,
223 ) -> PerNs { 253 ) -> PerNs {
224 // Resolve in: 254 // Resolve in:
225 // - legacy scope of macro 255 // - legacy scope of macro
@@ -228,23 +258,33 @@ impl CrateDefMap {
228 // - std prelude 258 // - std prelude
229 let from_legacy_macro = 259 let from_legacy_macro =
230 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); 260 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros);
231 let from_scope = self[module].scope.get(name).map_or_else(PerNs::none, |res| res.def); 261 let from_scope =
262 self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
232 let from_extern_prelude = 263 let from_extern_prelude =
233 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 264 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
234 let from_prelude = self.resolve_in_prelude(db, name); 265 let from_prelude = self.resolve_in_prelude(db, name, shadow);
235 266
236 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) 267 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude)
237 } 268 }
238 269
239 fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { 270 fn resolve_name_in_crate_root_or_extern_prelude(
271 &self,
272 name: &Name,
273 shadow: BuiltinShadowMode,
274 ) -> PerNs {
240 let from_crate_root = 275 let from_crate_root =
241 self[self.root].scope.get(name).map_or_else(PerNs::none, |res| res.def); 276 self[self.root].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
242 let from_extern_prelude = self.resolve_name_in_extern_prelude(name); 277 let from_extern_prelude = self.resolve_name_in_extern_prelude(name);
243 278
244 from_crate_root.or(from_extern_prelude) 279 from_crate_root.or(from_extern_prelude)
245 } 280 }
246 281
247 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { 282 fn resolve_in_prelude(
283 &self,
284 db: &impl DefDatabase,
285 name: &Name,
286 shadow: BuiltinShadowMode,
287 ) -> PerNs {
248 if let Some(prelude) = self.prelude { 288 if let Some(prelude) = self.prelude {
249 let keep; 289 let keep;
250 let def_map = if prelude.krate == self.krate { 290 let def_map = if prelude.krate == self.krate {
@@ -254,7 +294,10 @@ impl CrateDefMap {
254 keep = db.crate_def_map(prelude.krate); 294 keep = db.crate_def_map(prelude.krate);
255 &keep 295 &keep
256 }; 296 };
257 def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) 297 def_map[prelude.local_id]
298 .scope
299 .get(name, shadow)
300 .map_or_else(PerNs::none, |res| res.def)
258 } else { 301 } else {
259 PerNs::none() 302 PerNs::none()
260 } 303 }