aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs54
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(