diff options
author | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
---|---|---|
committer | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
commit | f05d7b41a719d848844b054a16477b29d0f063c6 (patch) | |
tree | 0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_hir_ty/src/method_resolution.rs | |
parent | 73ff610e41959e3e7c78a2b4b25b086883132956 (diff) | |
parent | 6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff) |
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/ra_hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 302 |
1 files changed, 180 insertions, 122 deletions
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index c19519cf1..fb4b30a13 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -2,12 +2,14 @@ | |||
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::{ |
9 | lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId, | 9 | builtin_type::{IntBitness, Signedness}, |
10 | HasModule, ImplId, Lookup, TraitId, | 10 | lang_item::LangItemTarget, |
11 | type_ref::Mutability, | ||
12 | AssocContainerId, AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId, | ||
11 | }; | 13 | }; |
12 | use hir_expand::name::Name; | 14 | use hir_expand::name::Name; |
13 | use ra_db::CrateId; | 15 | use ra_db::CrateId; |
@@ -16,8 +18,12 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
16 | 18 | ||
17 | use super::Substs; | 19 | use super::Substs; |
18 | use crate::{ | 20 | use crate::{ |
19 | autoderef, db::HirDatabase, primitive::FloatBitness, utils::all_super_traits, ApplicationTy, | 21 | autoderef, |
20 | Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 22 | db::HirDatabase, |
23 | primitive::{FloatBitness, FloatTy, IntTy}, | ||
24 | utils::all_super_traits, | ||
25 | ApplicationTy, Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TyKind, | ||
26 | TypeCtor, TypeWalk, | ||
21 | }; | 27 | }; |
22 | 28 | ||
23 | /// This is used as a key for indexing impls. | 29 | /// This is used as a key for indexing impls. |
@@ -38,136 +44,187 @@ impl TyFingerprint { | |||
38 | } | 44 | } |
39 | } | 45 | } |
40 | 46 | ||
41 | /// A queryable and mergeable collection of impls. | 47 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
42 | #[derive(Debug, PartialEq, Eq)] | 48 | TyFingerprint::Apply(TypeCtor::Int(IntTy { |
43 | pub struct CrateImplDefs { | 49 | signedness: Signedness::Unsigned, |
44 | inherent_impls: FxHashMap<TyFingerprint, Vec<ImplId>>, | 50 | bitness: IntBitness::X8, |
45 | impls_by_trait: FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>, | 51 | })), |
52 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
53 | signedness: Signedness::Unsigned, | ||
54 | bitness: IntBitness::X16, | ||
55 | })), | ||
56 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
57 | signedness: Signedness::Unsigned, | ||
58 | bitness: IntBitness::X32, | ||
59 | })), | ||
60 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
61 | signedness: Signedness::Unsigned, | ||
62 | bitness: IntBitness::X64, | ||
63 | })), | ||
64 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
65 | signedness: Signedness::Unsigned, | ||
66 | bitness: IntBitness::X128, | ||
67 | })), | ||
68 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
69 | signedness: Signedness::Unsigned, | ||
70 | bitness: IntBitness::Xsize, | ||
71 | })), | ||
72 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
73 | signedness: Signedness::Signed, | ||
74 | bitness: IntBitness::X8, | ||
75 | })), | ||
76 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
77 | signedness: Signedness::Signed, | ||
78 | bitness: IntBitness::X16, | ||
79 | })), | ||
80 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
81 | signedness: Signedness::Signed, | ||
82 | bitness: IntBitness::X32, | ||
83 | })), | ||
84 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
85 | signedness: Signedness::Signed, | ||
86 | bitness: IntBitness::X64, | ||
87 | })), | ||
88 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
89 | signedness: Signedness::Signed, | ||
90 | bitness: IntBitness::X128, | ||
91 | })), | ||
92 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
93 | signedness: Signedness::Signed, | ||
94 | bitness: IntBitness::Xsize, | ||
95 | })), | ||
96 | ]; | ||
97 | |||
98 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ | ||
99 | TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), | ||
100 | TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), | ||
101 | ]; | ||
102 | |||
103 | /// Trait impls defined or available in some crate. | ||
104 | #[derive(Debug, Eq, PartialEq)] | ||
105 | pub struct TraitImpls { | ||
106 | // If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type. | ||
107 | map: FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>, | ||
46 | } | 108 | } |
47 | 109 | ||
48 | impl CrateImplDefs { | 110 | impl TraitImpls { |
49 | pub(crate) fn impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<CrateImplDefs> { | 111 | pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { |
50 | let _p = profile("impls_in_crate_query"); | 112 | let _p = profile("trait_impls_in_crate_query"); |
51 | let mut res = CrateImplDefs { | 113 | let mut impls = Self { map: FxHashMap::default() }; |
52 | inherent_impls: FxHashMap::default(), | ||
53 | impls_by_trait: FxHashMap::default(), | ||
54 | }; | ||
55 | res.fill(db, krate); | ||
56 | 114 | ||
57 | Arc::new(res) | 115 | let crate_def_map = db.crate_def_map(krate); |
116 | for (_module_id, module_data) in crate_def_map.modules.iter() { | ||
117 | for impl_id in module_data.scope.impls() { | ||
118 | let target_trait = match db.impl_trait(impl_id) { | ||
119 | Some(tr) => tr.value.trait_, | ||
120 | None => continue, | ||
121 | }; | ||
122 | let self_ty = db.impl_self_ty(impl_id); | ||
123 | let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); | ||
124 | impls | ||
125 | .map | ||
126 | .entry(target_trait) | ||
127 | .or_default() | ||
128 | .entry(self_ty_fp) | ||
129 | .or_default() | ||
130 | .push(impl_id); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | Arc::new(impls) | ||
58 | } | 135 | } |
59 | 136 | ||
60 | /// Collects all impls from transitive dependencies of `krate` that may be used by `krate`. | 137 | pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { |
61 | /// | 138 | let _p = profile("trait_impls_in_deps_query"); |
62 | /// The full set of impls that can be used by `krate` is the returned map plus all the impls | ||
63 | /// from `krate` itself. | ||
64 | pub(crate) fn impls_from_deps_query( | ||
65 | db: &dyn HirDatabase, | ||
66 | krate: CrateId, | ||
67 | ) -> Arc<CrateImplDefs> { | ||
68 | let _p = profile("impls_from_deps_query"); | ||
69 | let crate_graph = db.crate_graph(); | 139 | let crate_graph = db.crate_graph(); |
70 | let mut res = CrateImplDefs { | 140 | let mut res = Self { map: FxHashMap::default() }; |
71 | inherent_impls: FxHashMap::default(), | ||
72 | impls_by_trait: FxHashMap::default(), | ||
73 | }; | ||
74 | 141 | ||
75 | // For each dependency, calculate `impls_from_deps` recursively, then add its own | 142 | for krate in crate_graph.transitive_deps(krate) { |
76 | // `impls_in_crate`. | 143 | res.merge(&db.trait_impls_in_crate(krate)); |
77 | // As we might visit crates multiple times, `merge` has to deduplicate impls to avoid | ||
78 | // wasting memory. | ||
79 | for dep in &crate_graph[krate].dependencies { | ||
80 | res.merge(&db.impls_from_deps(dep.crate_id)); | ||
81 | res.merge(&db.impls_in_crate(dep.crate_id)); | ||
82 | } | 144 | } |
83 | 145 | ||
84 | Arc::new(res) | 146 | Arc::new(res) |
85 | } | 147 | } |
86 | 148 | ||
87 | fn fill(&mut self, db: &dyn HirDatabase, krate: CrateId) { | ||
88 | let crate_def_map = db.crate_def_map(krate); | ||
89 | for (_module_id, module_data) in crate_def_map.modules.iter() { | ||
90 | for impl_id in module_data.scope.impls() { | ||
91 | match db.impl_trait(impl_id) { | ||
92 | Some(tr) => { | ||
93 | let self_ty = db.impl_self_ty(impl_id); | ||
94 | let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); | ||
95 | self.impls_by_trait | ||
96 | .entry(tr.value.trait_) | ||
97 | .or_default() | ||
98 | .entry(self_ty_fp) | ||
99 | .or_default() | ||
100 | .push(impl_id); | ||
101 | } | ||
102 | None => { | ||
103 | let self_ty = db.impl_self_ty(impl_id); | ||
104 | if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty.value) { | ||
105 | self.inherent_impls.entry(self_ty_fp).or_default().push(impl_id); | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | fn merge(&mut self, other: &Self) { | 149 | fn merge(&mut self, other: &Self) { |
114 | for (fp, impls) in &other.inherent_impls { | 150 | for (trait_, other_map) in &other.map { |
115 | let vec = self.inherent_impls.entry(*fp).or_default(); | 151 | let map = self.map.entry(*trait_).or_default(); |
116 | vec.extend(impls); | ||
117 | vec.sort(); | ||
118 | vec.dedup(); | ||
119 | } | ||
120 | |||
121 | for (trait_, other_map) in &other.impls_by_trait { | ||
122 | let map = self.impls_by_trait.entry(*trait_).or_default(); | ||
123 | for (fp, impls) in other_map { | 152 | for (fp, impls) in other_map { |
124 | let vec = map.entry(*fp).or_default(); | 153 | let vec = map.entry(*fp).or_default(); |
125 | vec.extend(impls); | 154 | vec.extend(impls); |
126 | vec.sort(); | ||
127 | vec.dedup(); | ||
128 | } | 155 | } |
129 | } | 156 | } |
130 | } | 157 | } |
131 | 158 | ||
132 | pub fn lookup_impl_defs(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ { | 159 | /// Queries all impls of the given trait. |
133 | let fingerprint = TyFingerprint::for_impl(ty); | 160 | pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ { |
134 | fingerprint.and_then(|f| self.inherent_impls.get(&f)).into_iter().flatten().copied() | 161 | self.map |
135 | } | 162 | .get(&trait_) |
136 | |||
137 | pub fn lookup_impl_defs_for_trait(&self, tr: TraitId) -> impl Iterator<Item = ImplId> + '_ { | ||
138 | self.impls_by_trait | ||
139 | .get(&tr) | ||
140 | .into_iter() | 163 | .into_iter() |
141 | .flat_map(|m| m.values().flat_map(|v| v.iter().copied())) | 164 | .flat_map(|map| map.values().flat_map(|v| v.iter().copied())) |
142 | } | 165 | } |
143 | 166 | ||
144 | pub fn lookup_impl_defs_for_trait_and_ty( | 167 | /// Queries all impls of `trait_` that may apply to `self_ty`. |
168 | pub fn for_trait_and_self_ty( | ||
145 | &self, | 169 | &self, |
146 | tr: TraitId, | 170 | trait_: TraitId, |
147 | fp: TyFingerprint, | 171 | self_ty: TyFingerprint, |
148 | ) -> impl Iterator<Item = ImplId> + '_ { | 172 | ) -> impl Iterator<Item = ImplId> + '_ { |
149 | self.impls_by_trait | 173 | self.map |
150 | .get(&tr) | 174 | .get(&trait_) |
151 | .and_then(|m| m.get(&Some(fp))) | ||
152 | .into_iter() | 175 | .into_iter() |
153 | .flatten() | 176 | .flat_map(move |map| map.get(&None).into_iter().chain(map.get(&Some(self_ty)))) |
154 | .copied() | 177 | .flat_map(|v| v.iter().copied()) |
155 | .chain( | 178 | } |
156 | self.impls_by_trait | 179 | |
157 | .get(&tr) | 180 | pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ { |
158 | .and_then(|m| m.get(&None)) | 181 | self.map.values().flat_map(|map| map.values().flat_map(|v| v.iter().copied())) |
159 | .into_iter() | 182 | } |
160 | .flatten() | 183 | } |
161 | .copied(), | 184 | |
162 | ) | 185 | /// Inherent impls defined in some crate. |
186 | /// | ||
187 | /// Inherent impls can only be defined in the crate that also defines the self type of the impl | ||
188 | /// (note that some primitives are considered to be defined by both libcore and liballoc). | ||
189 | /// | ||
190 | /// This makes inherent impl lookup easier than trait impl lookup since we only have to consider a | ||
191 | /// single crate. | ||
192 | #[derive(Debug, Eq, PartialEq)] | ||
193 | pub struct InherentImpls { | ||
194 | map: FxHashMap<TyFingerprint, Vec<ImplId>>, | ||
195 | } | ||
196 | |||
197 | impl InherentImpls { | ||
198 | pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { | ||
199 | let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default(); | ||
200 | |||
201 | let crate_def_map = db.crate_def_map(krate); | ||
202 | for (_module_id, module_data) in crate_def_map.modules.iter() { | ||
203 | for impl_id in module_data.scope.impls() { | ||
204 | let data = db.impl_data(impl_id); | ||
205 | if data.target_trait.is_some() { | ||
206 | continue; | ||
207 | } | ||
208 | |||
209 | let self_ty = db.impl_self_ty(impl_id); | ||
210 | if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { | ||
211 | map.entry(fp).or_default().push(impl_id); | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
216 | Arc::new(Self { map }) | ||
217 | } | ||
218 | |||
219 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { | ||
220 | match TyFingerprint::for_impl(self_ty) { | ||
221 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), | ||
222 | None => &[], | ||
223 | } | ||
163 | } | 224 | } |
164 | 225 | ||
165 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a { | 226 | pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ { |
166 | self.inherent_impls | 227 | self.map.values().flat_map(|v| v.iter().copied()) |
167 | .values() | ||
168 | .chain(self.impls_by_trait.values().flat_map(|m| m.values())) | ||
169 | .flatten() | ||
170 | .copied() | ||
171 | } | 228 | } |
172 | } | 229 | } |
173 | 230 | ||
@@ -377,7 +434,7 @@ fn iterate_method_candidates_with_autoref( | |||
377 | return true; | 434 | return true; |
378 | } | 435 | } |
379 | let refed = Canonical { | 436 | let refed = Canonical { |
380 | num_vars: deref_chain[0].num_vars, | 437 | kinds: deref_chain[0].kinds.clone(), |
381 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), | 438 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), |
382 | }; | 439 | }; |
383 | if iterate_method_candidates_by_receiver( | 440 | if iterate_method_candidates_by_receiver( |
@@ -393,7 +450,7 @@ fn iterate_method_candidates_with_autoref( | |||
393 | return true; | 450 | return true; |
394 | } | 451 | } |
395 | let ref_muted = Canonical { | 452 | let ref_muted = Canonical { |
396 | num_vars: deref_chain[0].num_vars, | 453 | kinds: deref_chain[0].kinds.clone(), |
397 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), | 454 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), |
398 | }; | 455 | }; |
399 | if iterate_method_candidates_by_receiver( | 456 | if iterate_method_candidates_by_receiver( |
@@ -524,9 +581,9 @@ fn iterate_inherent_methods( | |||
524 | None => return false, | 581 | None => return false, |
525 | }; | 582 | }; |
526 | for krate in def_crates { | 583 | for krate in def_crates { |
527 | let impls = db.impls_in_crate(krate); | 584 | let impls = db.inherent_impls_in_crate(krate); |
528 | 585 | ||
529 | for impl_def in impls.lookup_impl_defs(&self_ty.value) { | 586 | for &impl_def in impls.for_self_ty(&self_ty.value) { |
530 | for &item in db.impl_data(impl_def).items.iter() { | 587 | for &item in db.impl_data(impl_def).items.iter() { |
531 | if !is_valid_candidate(db, name, receiver_ty, item, self_ty) { | 588 | if !is_valid_candidate(db, name, receiver_ty, item, self_ty) { |
532 | continue; | 589 | continue; |
@@ -612,18 +669,19 @@ pub(crate) fn inherent_impl_substs( | |||
612 | // we create a var for each type parameter of the impl; we need to keep in | 669 | // 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 | 670 | // mind here that `self_ty` might have vars of its own |
614 | let vars = Substs::build_for_def(db, impl_id) | 671 | let vars = Substs::build_for_def(db, impl_id) |
615 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.num_vars) | 672 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) |
616 | .build(); | 673 | .build(); |
617 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 674 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); |
618 | let self_ty_with_vars = | 675 | let mut kinds = self_ty.kinds.to_vec(); |
619 | Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars }; | 676 | kinds.extend(iter::repeat(TyKind::General).take(vars.len())); |
620 | let substs = super::infer::unify(&self_ty_with_vars, self_ty); | 677 | let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; |
678 | let substs = super::infer::unify(&tys); | ||
621 | // We only want the substs for the vars we added, not the ones from self_ty. | 679 | // 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 | 680 | // 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 | 681 | // 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 | 682 | // Unknown, and in that case we want the result to contain Unknown in those |
625 | // places again. | 683 | // places again. |
626 | substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.num_vars)) | 684 | substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len())) |
627 | } | 685 | } |
628 | 686 | ||
629 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 687 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
@@ -683,15 +741,15 @@ fn generic_implements_goal( | |||
683 | trait_: TraitId, | 741 | trait_: TraitId, |
684 | self_ty: Canonical<Ty>, | 742 | self_ty: Canonical<Ty>, |
685 | ) -> Canonical<InEnvironment<super::Obligation>> { | 743 | ) -> Canonical<InEnvironment<super::Obligation>> { |
686 | let num_vars = self_ty.num_vars; | 744 | let mut kinds = self_ty.kinds.to_vec(); |
687 | let substs = super::Substs::build_for_def(db, trait_) | 745 | let substs = super::Substs::build_for_def(db, trait_) |
688 | .push(self_ty.value) | 746 | .push(self_ty.value) |
689 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, num_vars) | 747 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) |
690 | .build(); | 748 | .build(); |
691 | let num_vars = substs.len() - 1 + self_ty.num_vars; | 749 | kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1)); |
692 | let trait_ref = TraitRef { trait_, substs }; | 750 | let trait_ref = TraitRef { trait_, substs }; |
693 | let obligation = super::Obligation::Trait(trait_ref); | 751 | let obligation = super::Obligation::Trait(trait_ref); |
694 | Canonical { num_vars, value: InEnvironment::new(env, obligation) } | 752 | Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } |
695 | } | 753 | } |
696 | 754 | ||
697 | fn autoderef_method_receiver( | 755 | fn autoderef_method_receiver( |
@@ -704,9 +762,9 @@ fn autoderef_method_receiver( | |||
704 | if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = | 762 | if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = |
705 | deref_chain.last().map(|ty| &ty.value) | 763 | deref_chain.last().map(|ty| &ty.value) |
706 | { | 764 | { |
707 | let num_vars = deref_chain.last().unwrap().num_vars; | 765 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
708 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); | 766 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); |
709 | deref_chain.push(Canonical { value: unsized_ty, num_vars }) | 767 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
710 | } | 768 | } |
711 | deref_chain | 769 | deref_chain |
712 | } | 770 | } |