aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-24 06:45:08 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-24 06:45:08 +0000
commitc5e74cebdcbade069c0e1e81e298ab7d729e4cd5 (patch)
tree574d01f1f7532574ed22610341b3ac79da59d93f /crates/ra_hir/src/ty/infer.rs
parent1eef9fbefe44e919f6ddc7ce1c44625ffde6be1c (diff)
parent82fe7b77a3b4f49540ae1fc319bdd38afd73c877 (diff)
Merge #886
886: Associated method generics r=matklad a=flodiebold Refactor associated method resolution a bit and make it work with generics. Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs86
1 files changed, 53 insertions, 33 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 6ee9080d3..13080b5aa 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -360,46 +360,66 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
360 // we might have resolved into a type for which 360 // we might have resolved into a type for which
361 // we may find some associated item starting at the 361 // we may find some associated item starting at the
362 // path.segment pointed to by `remaining_index´ 362 // path.segment pointed to by `remaining_index´
363 let resolved = 363 let mut resolved =
364 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; 364 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? };
365 365
366 let remaining_index = remaining_index.unwrap_or(path.segments.len());
367
368 // resolve intermediate segments
369 for segment in &path.segments[remaining_index..] {
370 let ty = match resolved {
371 Resolution::Def(def) => {
372 let typable: Option<TypableDef> = def.into();
373 let typable = typable?;
374
375 let substs =
376 Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable);
377 self.db.type_for_def(typable, Namespace::Types).apply_substs(substs)
378 }
379 Resolution::LocalBinding(_) => {
380 // can't have a local binding in an associated item path
381 return None;
382 }
383 Resolution::GenericParam(..) => {
384 // TODO associated item of generic param
385 return None;
386 }
387 Resolution::SelfType(_) => {
388 // TODO associated item of self type
389 return None;
390 }
391 };
392
393 // Attempt to find an impl_item for the type which has a name matching
394 // the current segment
395 log::debug!("looking for path segment: {:?}", segment);
396 let item = ty.iterate_impl_items(self.db, |item| match item {
397 crate::ImplItem::Method(func) => {
398 let sig = func.signature(self.db);
399 if segment.name == *sig.name() {
400 return Some(func);
401 }
402 None
403 }
404
405 // TODO: Resolve associated const
406 crate::ImplItem::Const(_) => None,
407
408 // TODO: Resolve associated types
409 crate::ImplItem::Type(_) => None,
410 })?;
411 resolved = Resolution::Def(item.into());
412 }
413
366 match resolved { 414 match resolved {
367 Resolution::Def(def) => { 415 Resolution::Def(def) => {
368 let typable: Option<TypableDef> = def.into(); 416 let typable: Option<TypableDef> = def.into();
369 let typable = typable?; 417 let typable = typable?;
370 418
371 if let Some(remaining_index) = remaining_index { 419 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
372 let ty = self.db.type_for_def(typable, Namespace::Types); 420 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
373 // TODO: Keep resolving the segments 421 let ty = self.insert_type_vars(ty);
374 // if we have more segments to process 422 Some(ty)
375 let segment = &path.segments[remaining_index];
376
377 log::debug!("looking for path segment: {:?}", segment);
378
379 // Attempt to find an impl_item for the type which has a name matching
380 // the current segment
381 let ty = ty.iterate_impl_items(self.db, |item| match item {
382 crate::ImplItem::Method(func) => {
383 let sig = func.signature(self.db);
384 if segment.name == *sig.name() {
385 return Some(func.ty(self.db));
386 }
387 None
388 }
389
390 // TODO: Resolve associated const
391 crate::ImplItem::Const(_) => None,
392
393 // TODO: Resolve associated types
394 crate::ImplItem::Type(_) => None,
395 });
396 ty
397 } else {
398 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
399 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
400 let ty = self.insert_type_vars(ty);
401 Some(ty)
402 }
403 } 423 }
404 Resolution::LocalBinding(pat) => { 424 Resolution::LocalBinding(pat) => {
405 let ty = self.type_of_pat.get(pat)?; 425 let ty = self.type_of_pat.get(pat)?;