aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/method_resolution.rs')
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs32
1 files changed, 17 insertions, 15 deletions
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 5dbabd12b..a45febbf7 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -2,7 +2,7 @@
2//! For details about how this works in rustc, see the method lookup page in the 2//! For details about how this works in rustc, see the method lookup page in the
3//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html) 3//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
4//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs. 4//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
5use std::sync::Arc; 5use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{ 8use hir_def::{
@@ -17,7 +17,8 @@ use rustc_hash::{FxHashMap, FxHashSet};
17use super::Substs; 17use super::Substs;
18use crate::{ 18use crate::{
19 autoderef, db::HirDatabase, primitive::FloatBitness, utils::all_super_traits, ApplicationTy, 19 autoderef, db::HirDatabase, primitive::FloatBitness, utils::all_super_traits, ApplicationTy,
20 Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 20 Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor,
21 TypeWalk,
21}; 22};
22 23
23/// This is used as a key for indexing impls. 24/// This is used as a key for indexing impls.
@@ -372,7 +373,7 @@ fn iterate_method_candidates_with_autoref(
372 return true; 373 return true;
373 } 374 }
374 let refed = Canonical { 375 let refed = Canonical {
375 num_vars: deref_chain[0].num_vars, 376 kinds: deref_chain[0].kinds.clone(),
376 value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), 377 value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()),
377 }; 378 };
378 if iterate_method_candidates_by_receiver( 379 if iterate_method_candidates_by_receiver(
@@ -388,7 +389,7 @@ fn iterate_method_candidates_with_autoref(
388 return true; 389 return true;
389 } 390 }
390 let ref_muted = Canonical { 391 let ref_muted = Canonical {
391 num_vars: deref_chain[0].num_vars, 392 kinds: deref_chain[0].kinds.clone(),
392 value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), 393 value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()),
393 }; 394 };
394 if iterate_method_candidates_by_receiver( 395 if iterate_method_candidates_by_receiver(
@@ -607,18 +608,19 @@ pub(crate) fn inherent_impl_substs(
607 // we create a var for each type parameter of the impl; we need to keep in 608 // we create a var for each type parameter of the impl; we need to keep in
608 // mind here that `self_ty` might have vars of its own 609 // mind here that `self_ty` might have vars of its own
609 let vars = Substs::build_for_def(db, impl_id) 610 let vars = Substs::build_for_def(db, impl_id)
610 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.num_vars) 611 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len())
611 .build(); 612 .build();
612 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 613 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
613 let self_ty_with_vars = 614 let mut kinds = self_ty.kinds.to_vec();
614 Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars }; 615 kinds.extend(iter::repeat(TyKind::General).take(vars.len()));
615 let substs = super::infer::unify(&self_ty_with_vars, self_ty); 616 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) };
617 let substs = super::infer::unify(&tys);
616 // We only want the substs for the vars we added, not the ones from self_ty. 618 // We only want the substs for the vars we added, not the ones from self_ty.
617 // Also, if any of the vars we added are still in there, we replace them by 619 // Also, if any of the vars we added are still in there, we replace them by
618 // Unknown. I think this can only really happen if self_ty contained 620 // Unknown. I think this can only really happen if self_ty contained
619 // Unknown, and in that case we want the result to contain Unknown in those 621 // Unknown, and in that case we want the result to contain Unknown in those
620 // places again. 622 // places again.
621 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.num_vars)) 623 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len()))
622} 624}
623 625
624/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 626/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -678,15 +680,15 @@ fn generic_implements_goal(
678 trait_: TraitId, 680 trait_: TraitId,
679 self_ty: Canonical<Ty>, 681 self_ty: Canonical<Ty>,
680) -> Canonical<InEnvironment<super::Obligation>> { 682) -> Canonical<InEnvironment<super::Obligation>> {
681 let num_vars = self_ty.num_vars; 683 let mut kinds = self_ty.kinds.to_vec();
682 let substs = super::Substs::build_for_def(db, trait_) 684 let substs = super::Substs::build_for_def(db, trait_)
683 .push(self_ty.value) 685 .push(self_ty.value)
684 .fill_with_bound_vars(DebruijnIndex::INNERMOST, num_vars) 686 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
685 .build(); 687 .build();
686 let num_vars = substs.len() - 1 + self_ty.num_vars; 688 kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1));
687 let trait_ref = TraitRef { trait_, substs }; 689 let trait_ref = TraitRef { trait_, substs };
688 let obligation = super::Obligation::Trait(trait_ref); 690 let obligation = super::Obligation::Trait(trait_ref);
689 Canonical { num_vars, value: InEnvironment::new(env, obligation) } 691 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
690} 692}
691 693
692fn autoderef_method_receiver( 694fn autoderef_method_receiver(
@@ -699,9 +701,9 @@ fn autoderef_method_receiver(
699 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = 701 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) =
700 deref_chain.last().map(|ty| &ty.value) 702 deref_chain.last().map(|ty| &ty.value)
701 { 703 {
702 let num_vars = deref_chain.last().unwrap().num_vars; 704 let kinds = deref_chain.last().unwrap().kinds.clone();
703 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); 705 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone());
704 deref_chain.push(Canonical { value: unsized_ty, num_vars }) 706 deref_chain.push(Canonical { value: unsized_ty, kinds })
705 } 707 }
706 deref_chain 708 deref_chain
707} 709}