diff options
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 54 |
1 files changed, 19 insertions, 35 deletions
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 174ae9d38..19d57baae 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs | |||
@@ -70,7 +70,16 @@ impl CrateDefMap { | |||
70 | path: &Path, | 70 | path: &Path, |
71 | shadow: BuiltinShadowMode, | 71 | shadow: BuiltinShadowMode, |
72 | ) -> ResolvePathResult { | 72 | ) -> ResolvePathResult { |
73 | let mut segments = path.segments.iter().enumerate().peekable(); | 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 | |||
82 | let mut segments = path.segments.iter().enumerate(); | ||
74 | 83 | ||
75 | let mut curr_per_ns: PerNs = match path.kind { | 84 | let mut curr_per_ns: PerNs = match path.kind { |
76 | PathKind::DollarCrate(krate) => { | 85 | PathKind::DollarCrate(krate) => { |
@@ -98,29 +107,21 @@ impl CrateDefMap { | |||
98 | if self.edition == Edition::Edition2015 | 107 | if self.edition == Edition::Edition2015 |
99 | && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => | 108 | && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => |
100 | { | 109 | { |
101 | let segment = match segments.next() { | 110 | let (idx, segment) = match segments.next() { |
102 | Some((_, segment)) => segment, | 111 | Some((idx, segment)) => (idx, segment), |
103 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 112 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
104 | }; | 113 | }; |
105 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); | 114 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); |
106 | 115 | ||
107 | self.resolve_name_in_crate_root_or_extern_prelude( | 116 | self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx)) |
108 | &segment.name, | ||
109 | prefer_module(&mut segments, shadow), | ||
110 | ) | ||
111 | } | 117 | } |
112 | PathKind::Plain => { | 118 | PathKind::Plain => { |
113 | let segment = match segments.next() { | 119 | let (idx, segment) = match segments.next() { |
114 | Some((_, segment)) => segment, | 120 | Some((idx, segment)) => (idx, segment), |
115 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 121 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
116 | }; | 122 | }; |
117 | log::debug!("resolving {:?} in module", segment); | 123 | log::debug!("resolving {:?} in module", segment); |
118 | self.resolve_name_in_module( | 124 | self.resolve_name_in_module(db, original_module, &segment.name, prefer_module(idx)) |
119 | db, | ||
120 | original_module, | ||
121 | &segment.name, | ||
122 | prefer_module(&mut segments, shadow), | ||
123 | ) | ||
124 | } | 125 | } |
125 | PathKind::Super => { | 126 | PathKind::Super => { |
126 | if let Some(p) = self.modules[original_module].parent { | 127 | if let Some(p) = self.modules[original_module].parent { |
@@ -150,7 +151,7 @@ impl CrateDefMap { | |||
150 | } | 151 | } |
151 | }; | 152 | }; |
152 | 153 | ||
153 | while let Some((i, segment)) = segments.next() { | 154 | for (i, segment) in segments { |
154 | let curr = match curr_per_ns.take_types() { | 155 | let curr = match curr_per_ns.take_types() { |
155 | Some(r) => r, | 156 | Some(r) => r, |
156 | None => { | 157 | None => { |
@@ -180,10 +181,7 @@ impl CrateDefMap { | |||
180 | } | 181 | } |
181 | 182 | ||
182 | // Since it is a qualified path here, it should not contains legacy macros | 183 | // Since it is a qualified path here, it should not contains legacy macros |
183 | match self[module.local_id] | 184 | match self[module.local_id].scope.get(&segment.name, prefer_module(i)) { |
184 | .scope | ||
185 | .get(&segment.name, prefer_module(&mut segments, shadow)) | ||
186 | { | ||
187 | Some(res) => res.def, | 185 | Some(res) => res.def, |
188 | _ => { | 186 | _ => { |
189 | log::debug!("path segment {:?} not found", segment.name); | 187 | log::debug!("path segment {:?} not found", segment.name); |
@@ -226,22 +224,8 @@ impl CrateDefMap { | |||
226 | } | 224 | } |
227 | }; | 225 | }; |
228 | } | 226 | } |
229 | return ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None); | ||
230 | 227 | ||
231 | // if it is not the last segment, we prefer builtin as module | 228 | ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) |
232 | fn prefer_module<I>( | ||
233 | segments: &mut std::iter::Peekable<I>, | ||
234 | shadow: BuiltinShadowMode, | ||
235 | ) -> BuiltinShadowMode | ||
236 | where | ||
237 | I: Iterator, | ||
238 | { | ||
239 | if segments.peek().is_some() { | ||
240 | BuiltinShadowMode::Module | ||
241 | } else { | ||
242 | shadow | ||
243 | } | ||
244 | } | ||
245 | } | 229 | } |
246 | 230 | ||
247 | fn resolve_name_in_module( | 231 | fn resolve_name_in_module( |