diff options
Diffstat (limited to 'crates/ra_hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 32 |
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 c19519cf1..c3edd6885 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. |
5 | use std::sync::Arc; | 5 | use std::{iter, sync::Arc}; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{ | 8 | use hir_def::{ |
@@ -17,7 +17,8 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
17 | use super::Substs; | 17 | use super::Substs; |
18 | use crate::{ | 18 | use 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. |
@@ -377,7 +378,7 @@ fn iterate_method_candidates_with_autoref( | |||
377 | return true; | 378 | return true; |
378 | } | 379 | } |
379 | let refed = Canonical { | 380 | let refed = Canonical { |
380 | num_vars: deref_chain[0].num_vars, | 381 | kinds: deref_chain[0].kinds.clone(), |
381 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), | 382 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), |
382 | }; | 383 | }; |
383 | if iterate_method_candidates_by_receiver( | 384 | if iterate_method_candidates_by_receiver( |
@@ -393,7 +394,7 @@ fn iterate_method_candidates_with_autoref( | |||
393 | return true; | 394 | return true; |
394 | } | 395 | } |
395 | let ref_muted = Canonical { | 396 | let ref_muted = Canonical { |
396 | num_vars: deref_chain[0].num_vars, | 397 | kinds: deref_chain[0].kinds.clone(), |
397 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), | 398 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), |
398 | }; | 399 | }; |
399 | if iterate_method_candidates_by_receiver( | 400 | if iterate_method_candidates_by_receiver( |
@@ -612,18 +613,19 @@ pub(crate) fn inherent_impl_substs( | |||
612 | // we create a var for each type parameter of the impl; we need to keep in | 613 | // we create a var for each type parameter of the impl; we need to keep in |
613 | // mind here that `self_ty` might have vars of its own | 614 | // mind here that `self_ty` might have vars of its own |
614 | let vars = Substs::build_for_def(db, impl_id) | 615 | let vars = Substs::build_for_def(db, impl_id) |
615 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.num_vars) | 616 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) |
616 | .build(); | 617 | .build(); |
617 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 618 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); |
618 | let self_ty_with_vars = | 619 | let mut kinds = self_ty.kinds.to_vec(); |
619 | Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars }; | 620 | kinds.extend(iter::repeat(TyKind::General).take(vars.len())); |
620 | let substs = super::infer::unify(&self_ty_with_vars, self_ty); | 621 | let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; |
622 | let substs = super::infer::unify(&tys); | ||
621 | // We only want the substs for the vars we added, not the ones from self_ty. | 623 | // We only want the substs for the vars we added, not the ones from self_ty. |
622 | // Also, if any of the vars we added are still in there, we replace them by | 624 | // Also, if any of the vars we added are still in there, we replace them by |
623 | // Unknown. I think this can only really happen if self_ty contained | 625 | // Unknown. I think this can only really happen if self_ty contained |
624 | // Unknown, and in that case we want the result to contain Unknown in those | 626 | // Unknown, and in that case we want the result to contain Unknown in those |
625 | // places again. | 627 | // places again. |
626 | substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.num_vars)) | 628 | substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len())) |
627 | } | 629 | } |
628 | 630 | ||
629 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 631 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
@@ -683,15 +685,15 @@ fn generic_implements_goal( | |||
683 | trait_: TraitId, | 685 | trait_: TraitId, |
684 | self_ty: Canonical<Ty>, | 686 | self_ty: Canonical<Ty>, |
685 | ) -> Canonical<InEnvironment<super::Obligation>> { | 687 | ) -> Canonical<InEnvironment<super::Obligation>> { |
686 | let num_vars = self_ty.num_vars; | 688 | let mut kinds = self_ty.kinds.to_vec(); |
687 | let substs = super::Substs::build_for_def(db, trait_) | 689 | let substs = super::Substs::build_for_def(db, trait_) |
688 | .push(self_ty.value) | 690 | .push(self_ty.value) |
689 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, num_vars) | 691 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) |
690 | .build(); | 692 | .build(); |
691 | let num_vars = substs.len() - 1 + self_ty.num_vars; | 693 | kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1)); |
692 | let trait_ref = TraitRef { trait_, substs }; | 694 | let trait_ref = TraitRef { trait_, substs }; |
693 | let obligation = super::Obligation::Trait(trait_ref); | 695 | let obligation = super::Obligation::Trait(trait_ref); |
694 | Canonical { num_vars, value: InEnvironment::new(env, obligation) } | 696 | Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } |
695 | } | 697 | } |
696 | 698 | ||
697 | fn autoderef_method_receiver( | 699 | fn autoderef_method_receiver( |
@@ -704,9 +706,9 @@ fn autoderef_method_receiver( | |||
704 | if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = | 706 | if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = |
705 | deref_chain.last().map(|ty| &ty.value) | 707 | deref_chain.last().map(|ty| &ty.value) |
706 | { | 708 | { |
707 | let num_vars = deref_chain.last().unwrap().num_vars; | 709 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
708 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); | 710 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); |
709 | deref_chain.push(Canonical { value: unsized_ty, num_vars }) | 711 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
710 | } | 712 | } |
711 | deref_chain | 713 | deref_chain |
712 | } | 714 | } |