diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-07-01 19:41:06 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-01 19:41:06 +0100 |
commit | a33eefa3b26000b3018e6bb873f18dbe15ab4ab7 (patch) | |
tree | da55aac24be34db6750e6675673317f52e7db4dc /crates/ra_hir_ty/src/method_resolution.rs | |
parent | ec1d1a1b709a6eafff07077cdf75291d01cda3b6 (diff) | |
parent | d5d485ef9289589332893f2c0ad96cb366afe9d6 (diff) |
Merge #5149
5149: Implement Chalk variable kinds r=flodiebold a=flodiebold
This means we need to keep track of the kinds (general/int/float) of variables in `Canonical`, which requires some more ceremony. (It also exposes some places where we're not really dealing with canonicalization correctly -- another thing to be cleaned up when we switch to using Chalk's types directly.)
Should fix the last remaining issue of #2534.
Co-authored-by: Florian Diebold <[email protected]>
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 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. |
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. |
@@ -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 | ||
692 | fn autoderef_method_receiver( | 694 | fn 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 | } |