diff options
Diffstat (limited to 'crates/hir_def/src/nameres/path_resolution.rs')
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 67 |
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 | ||
13 | use std::iter::successors; | ||
14 | |||
15 | use base_db::Edition; | 13 | use base_db::Edition; |
14 | use hir_expand::name; | ||
16 | use hir_expand::name::Name; | 15 | use hir_expand::name::Name; |
17 | use test_utils::mark; | 16 | use 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 | ||
64 | impl DefMap { | 63 | impl 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 ¤t_map.parent { | 132 | match ¤t_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) |