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.rs67
1 files changed, 41 insertions, 26 deletions
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index ec90f4e65..419e465ed 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -10,9 +10,8 @@
10//! 10//!
11//! `ReachedFixedPoint` signals about this. 11//! `ReachedFixedPoint` signals about this.
12 12
13use std::iter::successors;
14
15use base_db::Edition; 13use base_db::Edition;
14use hir_expand::name;
16use hir_expand::name::Name; 15use hir_expand::name::Name;
17use test_utils::mark; 16use test_utils::mark;
18 17
@@ -23,7 +22,7 @@ use crate::{
23 path::{ModPath, PathKind}, 22 path::{ModPath, PathKind},
24 per_ns::PerNs, 23 per_ns::PerNs,
25 visibility::{RawVisibility, Visibility}, 24 visibility::{RawVisibility, Visibility},
26 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 25 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId,
27}; 26};
28 27
29#[derive(Debug, Clone, Copy, PartialEq, Eq)] 28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -63,6 +62,10 @@ impl ResolvePathResult {
63 62
64impl DefMap { 63impl DefMap {
65 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 {
65 if name == &name!(self) {
66 mark::hit!(extern_crate_self_as);
67 return PerNs::types(self.module_id(self.root).into(), Visibility::Public);
68 }
66 self.extern_prelude 69 self.extern_prelude
67 .get(name) 70 .get(name)
68 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) 71 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
@@ -126,8 +129,8 @@ impl DefMap {
126 result.krate = result.krate.or(new.krate); 129 result.krate = result.krate.or(new.krate);
127 result.segment_index = result.segment_index.min(new.segment_index); 130 result.segment_index = result.segment_index.min(new.segment_index);
128 131
129 match &current_map.parent { 132 match &current_map.block {
130 Some(map) => current_map = map, 133 Some(block) => current_map = &block.parent,
131 None => return result, 134 None => return result,
132 } 135 }
133 } 136 }
@@ -146,21 +149,15 @@ impl DefMap {
146 PathKind::DollarCrate(krate) => { 149 PathKind::DollarCrate(krate) => {
147 if krate == self.krate { 150 if krate == self.krate {
148 mark::hit!(macro_dollar_crate_self); 151 mark::hit!(macro_dollar_crate_self);
149 PerNs::types( 152 PerNs::types(self.module_id(self.root).into(), Visibility::Public)
150 ModuleId { krate: self.krate, local_id: self.root }.into(),
151 Visibility::Public,
152 )
153 } else { 153 } else {
154 let def_map = db.crate_def_map(krate); 154 let def_map = db.crate_def_map(krate);
155 let module = ModuleId { krate, local_id: def_map.root }; 155 let module = def_map.module_id(def_map.root);
156 mark::hit!(macro_dollar_crate_other); 156 mark::hit!(macro_dollar_crate_other);
157 PerNs::types(module.into(), Visibility::Public) 157 PerNs::types(module.into(), Visibility::Public)
158 } 158 }
159 } 159 }
160 PathKind::Crate => PerNs::types( 160 PathKind::Crate => PerNs::types(self.module_id(self.root).into(), Visibility::Public),
161 ModuleId { krate: self.krate, local_id: self.root }.into(),
162 Visibility::Public,
163 ),
164 // plain import or absolute path in 2015: crate-relative with 161 // plain import or absolute path in 2015: crate-relative with
165 // fallback to extern prelude (with the simplification in 162 // fallback to extern prelude (with the simplification in
166 // rust-lang/rust#57745) 163 // rust-lang/rust#57745)
@@ -194,17 +191,35 @@ impl DefMap {
194 self.resolve_name_in_module(db, original_module, &segment, prefer_module) 191 self.resolve_name_in_module(db, original_module, &segment, prefer_module)
195 } 192 }
196 PathKind::Super(lvl) => { 193 PathKind::Super(lvl) => {
197 let m = successors(Some(original_module), |m| self.modules[*m].parent) 194 let mut module = original_module;
198 .nth(lvl as usize); 195 for i in 0..lvl {
199 if let Some(local_id) = m { 196 match self.modules[module].parent {
200 PerNs::types( 197 Some(it) => module = it,
201 ModuleId { krate: self.krate, local_id }.into(), 198 None => match &self.block {
202 Visibility::Public, 199 Some(block) => {
203 ) 200 // Look up remaining path in parent `DefMap`
204 } else { 201 let new_path = ModPath {
205 log::debug!("super path in root module"); 202 kind: PathKind::Super(lvl - i),
206 return ResolvePathResult::empty(ReachedFixedPoint::Yes); 203 segments: path.segments.clone(),
204 };
205 log::debug!("`super` path: {} -> {} in parent map", path, new_path);
206 return block.parent.resolve_path_fp_with_macro(
207 db,
208 mode,
209 block.parent_module,
210 &new_path,
211 shadow,
212 );
213 }
214 None => {
215 log::debug!("super path in root module");
216 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
217 }
218 },
219 }
207 } 220 }
221
222 PerNs::types(self.module_id(module).into(), Visibility::Public)
208 } 223 }
209 PathKind::Abs => { 224 PathKind::Abs => {
210 // 2018-style absolute path -- only extern prelude 225 // 2018-style absolute path -- only extern prelude
@@ -243,7 +258,7 @@ impl DefMap {
243 kind: PathKind::Super(0), 258 kind: PathKind::Super(0),
244 }; 259 };
245 log::debug!("resolving {:?} in other crate", path); 260 log::debug!("resolving {:?} in other crate", path);
246 let defp_map = db.crate_def_map(module.krate); 261 let defp_map = module.def_map(db);
247 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); 262 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
248 return ResolvePathResult::with( 263 return ResolvePathResult::with(
249 def, 264 def,
@@ -356,7 +371,7 @@ impl DefMap {
356 self 371 self
357 } else { 372 } else {
358 // Extend lifetime 373 // Extend lifetime
359 keep = db.crate_def_map(prelude.krate); 374 keep = prelude.def_map(db);
360 &keep 375 &keep
361 }; 376 };
362 def_map[prelude.local_id].scope.get(name) 377 def_map[prelude.local_id].scope.get(name)