aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/path_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres/path_resolution.rs')
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs51
1 files changed, 36 insertions, 15 deletions
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index 60471937c..ccc9f22eb 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -60,12 +60,26 @@ impl ResolvePathResult {
60} 60}
61 61
62impl DefMap { 62impl DefMap {
63 pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { 63 pub(super) fn resolve_name_in_extern_prelude(
64 &self,
65 db: &dyn DefDatabase,
66 name: &Name,
67 ) -> PerNs {
64 if name == &name!(self) { 68 if name == &name!(self) {
65 cov_mark::hit!(extern_crate_self_as); 69 cov_mark::hit!(extern_crate_self_as);
66 return PerNs::types(self.module_id(self.root).into(), Visibility::Public); 70 return PerNs::types(self.module_id(self.root).into(), Visibility::Public);
67 } 71 }
68 self.extern_prelude 72
73 let arc;
74 let root = match self.block {
75 Some(_) => {
76 arc = self.crate_root(db).def_map(db);
77 &*arc
78 }
79 None => self,
80 };
81
82 root.extern_prelude
69 .get(name) 83 .get(name)
70 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) 84 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
71 } 85 }
@@ -191,7 +205,7 @@ impl DefMap {
191 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 205 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
192 }; 206 };
193 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); 207 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
194 self.resolve_name_in_crate_root_or_extern_prelude(&segment) 208 self.resolve_name_in_crate_root_or_extern_prelude(db, &segment)
195 } 209 }
196 PathKind::Plain => { 210 PathKind::Plain => {
197 let (_, segment) = match segments.next() { 211 let (_, segment) = match segments.next() {
@@ -384,24 +398,31 @@ impl DefMap {
384 } 398 }
385 } 399 }
386 }; 400 };
387 // Give precedence to names in outer `DefMap`s over the extern prelude; only check prelude 401 let from_extern_prelude = self
388 // from the crate DefMap. 402 .extern_prelude
389 let from_extern_prelude = match self.block { 403 .get(name)
390 Some(_) => PerNs::none(), 404 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public));
391 None => self
392 .extern_prelude
393 .get(name)
394 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)),
395 };
396 405
397 let from_prelude = self.resolve_in_prelude(db, name); 406 let from_prelude = self.resolve_in_prelude(db, name);
398 407
399 from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) 408 from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude)
400 } 409 }
401 410
402 fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { 411 fn resolve_name_in_crate_root_or_extern_prelude(
403 let from_crate_root = self[self.root].scope.get(name); 412 &self,
404 let from_extern_prelude = self.resolve_name_in_extern_prelude(name); 413 db: &dyn DefDatabase,
414 name: &Name,
415 ) -> PerNs {
416 let arc;
417 let crate_def_map = match self.block {
418 Some(_) => {
419 arc = self.crate_root(db).def_map(db);
420 &arc
421 }
422 None => self,
423 };
424 let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name);
425 let from_extern_prelude = self.resolve_name_in_extern_prelude(db, name);
405 426
406 from_crate_root.or(from_extern_prelude) 427 from_crate_root.or(from_extern_prelude)
407 } 428 }