aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/path_resolution.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-01-25 18:24:04 +0000
committerGitHub <[email protected]>2021-01-25 18:24:04 +0000
commita37091d2d0175b0999d6383d48f538cdbf0267a0 (patch)
tree06981374f0c397b45e31b74c97ed337853fe59d2 /crates/hir_def/src/nameres/path_resolution.rs
parent2c735ed734be9b9041921478e0049fffd7160f78 (diff)
parent08253d5473348e2f3061e0c8d84c62de537a5821 (diff)
Merge #7431
7431: Handle `super` paths inside blocks correctly r=jonas-schievink a=jonas-schievink We now intern `BlockLoc` and use `BlockId` to refer to block expressions. This is needed to keep `ModuleId` simple, since it would otherwise have to store an arbitrarily long chain of blocks and couldn't be `Copy`. The `DefMap` hierarchy is now created as the caller descends into an item body. This is necessary to link the correct module as the block's parent, which is important for correct name resolution. As a result, we can now resolve `super` paths inside block expressions by climbing the `DefMap` chain. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/nameres/path_resolution.rs')
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs41
1 files changed, 30 insertions, 11 deletions
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index c1eded5f2..419e465ed 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -10,8 +10,6 @@
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;
16use hir_expand::name; 14use hir_expand::name;
17use hir_expand::name::Name; 15use hir_expand::name::Name;
@@ -131,8 +129,8 @@ impl DefMap {
131 result.krate = result.krate.or(new.krate); 129 result.krate = result.krate.or(new.krate);
132 result.segment_index = result.segment_index.min(new.segment_index); 130 result.segment_index = result.segment_index.min(new.segment_index);
133 131
134 match &current_map.parent { 132 match &current_map.block {
135 Some(map) => current_map = map, 133 Some(block) => current_map = &block.parent,
136 None => return result, 134 None => return result,
137 } 135 }
138 } 136 }
@@ -193,14 +191,35 @@ impl DefMap {
193 self.resolve_name_in_module(db, original_module, &segment, prefer_module) 191 self.resolve_name_in_module(db, original_module, &segment, prefer_module)
194 } 192 }
195 PathKind::Super(lvl) => { 193 PathKind::Super(lvl) => {
196 let m = successors(Some(original_module), |m| self.modules[*m].parent) 194 let mut module = original_module;
197 .nth(lvl as usize); 195 for i in 0..lvl {
198 if let Some(local_id) = m { 196 match self.modules[module].parent {
199 PerNs::types(self.module_id(local_id).into(), Visibility::Public) 197 Some(it) => module = it,
200 } else { 198 None => match &self.block {
201 log::debug!("super path in root module"); 199 Some(block) => {
202 return ResolvePathResult::empty(ReachedFixedPoint::Yes); 200 // Look up remaining path in parent `DefMap`
201 let new_path = ModPath {
202 kind: PathKind::Super(lvl - i),
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 }
203 } 220 }
221
222 PerNs::types(self.module_id(module).into(), Visibility::Public)
204 } 223 }
205 PathKind::Abs => { 224 PathKind::Abs => {
206 // 2018-style absolute path -- only extern prelude 225 // 2018-style absolute path -- only extern prelude