aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-04-14 19:26:21 +0100
committerEdwin Cheng <[email protected]>2019-04-17 02:31:52 +0100
commit180655077a4d582d49d4aa14bed67b382f336cf0 (patch)
treec56007d36c734876481a5312bc79effd83f23bfe /crates/ra_hir/src/ty/infer.rs
parent546d9be2a7bf7b3942c125f922a01321aea6ad26 (diff)
Fix 1099
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs51
1 files changed, 48 insertions, 3 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 651a78fe5..fe6553f79 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -459,6 +459,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
459 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; 459 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? };
460 460
461 let remaining_index = remaining_index.unwrap_or(path.segments.len()); 461 let remaining_index = remaining_index.unwrap_or(path.segments.len());
462 let mut actual_def_ty: Option<Ty> = None;
462 463
463 // resolve intermediate segments 464 // resolve intermediate segments
464 for segment in &path.segments[remaining_index..] { 465 for segment in &path.segments[remaining_index..] {
@@ -468,9 +469,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
468 let typable: Option<TypableDef> = def.into(); 469 let typable: Option<TypableDef> = def.into();
469 let typable = typable?; 470 let typable = typable?;
470 471
471 let substs = 472 let mut substs =
472 Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable); 473 Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable);
473 self.db.type_for_def(typable, Namespace::Types).subst(&substs) 474
475 if remaining_index > 0 {
476 substs = Ty::substs_from_path_segment(
477 self.db,
478 &self.resolver,
479 &path.segments[remaining_index - 1],
480 typable,
481 );
482 }
483
484 let ty = self.db.type_for_def(typable, Namespace::Types);
485 ty.subst(&substs)
474 } 486 }
475 Resolution::LocalBinding(_) => { 487 Resolution::LocalBinding(_) => {
476 // can't have a local binding in an associated item path 488 // can't have a local binding in an associated item path
@@ -489,6 +501,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
489 // Attempt to find an impl_item for the type which has a name matching 501 // Attempt to find an impl_item for the type which has a name matching
490 // the current segment 502 // the current segment
491 log::debug!("looking for path segment: {:?}", segment); 503 log::debug!("looking for path segment: {:?}", segment);
504 actual_def_ty = Some(ty.clone());
505
492 let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| { 506 let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| {
493 let matching_def: Option<crate::ModuleDef> = match item { 507 let matching_def: Option<crate::ModuleDef> = match item {
494 crate::ImplItem::Method(func) => { 508 crate::ImplItem::Method(func) => {
@@ -528,9 +542,40 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
528 Resolution::Def(def) => { 542 Resolution::Def(def) => {
529 let typable: Option<TypableDef> = def.into(); 543 let typable: Option<TypableDef> = def.into();
530 let typable = typable?; 544 let typable = typable?;
545
546 let ty = self.db.type_for_def(typable, Namespace::Values);
531 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 547 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
532 let ty = self.db.type_for_def(typable, Namespace::Values).subst(&substs); 548 let ty = ty.subst(&substs);
533 let ty = self.insert_type_vars(ty); 549 let ty = self.insert_type_vars(ty);
550
551 // plug the old parent_ty in
552 if let Some(actual_def_ty) = actual_def_ty {
553 if let crate::ModuleDef::Function(func) = def {
554 let gen = func.generic_params(self.db);
555 if let Some(target_ty) = func.impl_block(self.db) {
556 let target_ty = target_ty.target_ty(self.db);
557 let old_params = target_ty.substs().unwrap().clone();
558
559 let target_ty = target_ty.subst(&substs);
560 let target_ty = self.insert_type_vars(target_ty);
561
562 if gen.count_parent_params() > 0 {
563 self.unify(&target_ty, &actual_def_ty);
564
565 if let Ty::Apply(ty) = &ty {
566 for (param, pty) in
567 old_params.iter().zip(target_ty.substs().unwrap().iter())
568 {
569 if let Ty::Param { idx, .. } = param {
570 self.unify(pty, &ty.parameters.0[*idx as usize]);
571 }
572 }
573 }
574 }
575 }
576 }
577 }
578
534 Some(ty) 579 Some(ty)
535 } 580 }
536 Resolution::LocalBinding(pat) => { 581 Resolution::LocalBinding(pat) => {