diff options
Diffstat (limited to 'crates/ra_hir_def/src/nameres')
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 55 |
2 files changed, 43 insertions, 16 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..42a75226b 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 | ||
17 | use crate::{ | 17 | use 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,7 +68,17 @@ 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 { |
73 | // if it is not the last segment, we prefer the module to the builtin | ||
74 | let prefer_module = |index| { | ||
75 | if index == path.segments.len() - 1 { | ||
76 | shadow | ||
77 | } else { | ||
78 | BuiltinShadowMode::Module | ||
79 | } | ||
80 | }; | ||
81 | |||
72 | let mut segments = path.segments.iter().enumerate(); | 82 | let mut segments = path.segments.iter().enumerate(); |
73 | let mut curr_per_ns: PerNs = match path.kind { | 83 | let mut curr_per_ns: PerNs = match path.kind { |
74 | PathKind::DollarCrate(krate) => { | 84 | PathKind::DollarCrate(krate) => { |
@@ -96,20 +106,20 @@ impl CrateDefMap { | |||
96 | if self.edition == Edition::Edition2015 | 106 | if self.edition == Edition::Edition2015 |
97 | && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => | 107 | && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => |
98 | { | 108 | { |
99 | let segment = match segments.next() { | 109 | let (idx, segment) = match segments.next() { |
100 | Some((_, segment)) => segment, | 110 | Some((idx, segment)) => (idx, segment), |
101 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 111 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
102 | }; | 112 | }; |
103 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); | 113 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); |
104 | self.resolve_name_in_crate_root_or_extern_prelude(&segment.name) | 114 | self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx)) |
105 | } | 115 | } |
106 | PathKind::Plain => { | 116 | PathKind::Plain => { |
107 | let segment = match segments.next() { | 117 | let (idx, segment) = match segments.next() { |
108 | Some((_, segment)) => segment, | 118 | Some((idx, segment)) => (idx, segment), |
109 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 119 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
110 | }; | 120 | }; |
111 | log::debug!("resolving {:?} in module", segment); | 121 | log::debug!("resolving {:?} in module", segment); |
112 | self.resolve_name_in_module(db, original_module, &segment.name) | 122 | self.resolve_name_in_module(db, original_module, &segment.name, prefer_module(idx)) |
113 | } | 123 | } |
114 | PathKind::Super => { | 124 | PathKind::Super => { |
115 | if let Some(p) = self.modules[original_module].parent { | 125 | if let Some(p) = self.modules[original_module].parent { |
@@ -160,7 +170,7 @@ impl CrateDefMap { | |||
160 | Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; | 170 | Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; |
161 | log::debug!("resolving {:?} in other crate", path); | 171 | log::debug!("resolving {:?} in other crate", path); |
162 | let defp_map = db.crate_def_map(module.krate); | 172 | let defp_map = db.crate_def_map(module.krate); |
163 | let (def, s) = defp_map.resolve_path(db, module.local_id, &path); | 173 | let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); |
164 | return ResolvePathResult::with( | 174 | return ResolvePathResult::with( |
165 | def, | 175 | def, |
166 | ReachedFixedPoint::Yes, | 176 | ReachedFixedPoint::Yes, |
@@ -169,7 +179,7 @@ impl CrateDefMap { | |||
169 | } | 179 | } |
170 | 180 | ||
171 | // Since it is a qualified path here, it should not contains legacy macros | 181 | // Since it is a qualified path here, it should not contains legacy macros |
172 | match self[module.local_id].scope.get(&segment.name) { | 182 | match self[module.local_id].scope.get(&segment.name, prefer_module(i)) { |
173 | Some(res) => res.def, | 183 | Some(res) => res.def, |
174 | _ => { | 184 | _ => { |
175 | log::debug!("path segment {:?} not found", segment.name); | 185 | log::debug!("path segment {:?} not found", segment.name); |
@@ -212,6 +222,7 @@ impl CrateDefMap { | |||
212 | } | 222 | } |
213 | }; | 223 | }; |
214 | } | 224 | } |
225 | |||
215 | ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) | 226 | ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) |
216 | } | 227 | } |
217 | 228 | ||
@@ -220,6 +231,7 @@ impl CrateDefMap { | |||
220 | db: &impl DefDatabase, | 231 | db: &impl DefDatabase, |
221 | module: LocalModuleId, | 232 | module: LocalModuleId, |
222 | name: &Name, | 233 | name: &Name, |
234 | shadow: BuiltinShadowMode, | ||
223 | ) -> PerNs { | 235 | ) -> PerNs { |
224 | // Resolve in: | 236 | // Resolve in: |
225 | // - legacy scope of macro | 237 | // - legacy scope of macro |
@@ -228,23 +240,33 @@ impl CrateDefMap { | |||
228 | // - std prelude | 240 | // - std prelude |
229 | let from_legacy_macro = | 241 | let from_legacy_macro = |
230 | self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); | 242 | 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); | 243 | let from_scope = |
244 | self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def); | ||
232 | let from_extern_prelude = | 245 | let from_extern_prelude = |
233 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); | 246 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); |
234 | let from_prelude = self.resolve_in_prelude(db, name); | 247 | let from_prelude = self.resolve_in_prelude(db, name, shadow); |
235 | 248 | ||
236 | from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) | 249 | from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) |
237 | } | 250 | } |
238 | 251 | ||
239 | fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { | 252 | fn resolve_name_in_crate_root_or_extern_prelude( |
253 | &self, | ||
254 | name: &Name, | ||
255 | shadow: BuiltinShadowMode, | ||
256 | ) -> PerNs { | ||
240 | let from_crate_root = | 257 | let from_crate_root = |
241 | self[self.root].scope.get(name).map_or_else(PerNs::none, |res| res.def); | 258 | 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); | 259 | let from_extern_prelude = self.resolve_name_in_extern_prelude(name); |
243 | 260 | ||
244 | from_crate_root.or(from_extern_prelude) | 261 | from_crate_root.or(from_extern_prelude) |
245 | } | 262 | } |
246 | 263 | ||
247 | fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { | 264 | fn resolve_in_prelude( |
265 | &self, | ||
266 | db: &impl DefDatabase, | ||
267 | name: &Name, | ||
268 | shadow: BuiltinShadowMode, | ||
269 | ) -> PerNs { | ||
248 | if let Some(prelude) = self.prelude { | 270 | if let Some(prelude) = self.prelude { |
249 | let keep; | 271 | let keep; |
250 | let def_map = if prelude.krate == self.krate { | 272 | let def_map = if prelude.krate == self.krate { |
@@ -254,7 +276,10 @@ impl CrateDefMap { | |||
254 | keep = db.crate_def_map(prelude.krate); | 276 | keep = db.crate_def_map(prelude.krate); |
255 | &keep | 277 | &keep |
256 | }; | 278 | }; |
257 | def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) | 279 | def_map[prelude.local_id] |
280 | .scope | ||
281 | .get(name, shadow) | ||
282 | .map_or_else(PerNs::none, |res| res.def) | ||
258 | } else { | 283 | } else { |
259 | PerNs::none() | 284 | PerNs::none() |
260 | } | 285 | } |