aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r--crates/hir_ty/src/method_resolution.rs232
1 files changed, 125 insertions, 107 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index bf7d5eded..7e09a1539 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -8,8 +8,8 @@ use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; 9use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, FunctionId,
12 ImplId, Lookup, ModuleId, TraitId, 12 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId,
13}; 13};
14use hir_expand::name::Name; 14use hir_expand::name::Name;
15use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
@@ -19,11 +19,11 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id, 22 static_lifetime,
23 utils::all_super_traits, 23 utils::all_super_traits,
24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, 25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder,
26 TypeWalk, 26 TyExt, TyKind, TypeWalk,
27}; 27};
28 28
29/// This is used as a key for indexing impls. 29/// This is used as a key for indexing impls.
@@ -47,18 +47,18 @@ impl TyFingerprint {
47 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 47 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
48 /// `impl &S`. Hence, this will return `None` for reference types and such. 48 /// `impl &S`. Hence, this will return `None` for reference types and such.
49 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 49 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
50 let fp = match *ty.interned(&Interner) { 50 let fp = match ty.kind(&Interner) {
51 TyKind::Str => TyFingerprint::Str, 51 TyKind::Str => TyFingerprint::Str,
52 TyKind::Never => TyFingerprint::Never, 52 TyKind::Never => TyFingerprint::Never,
53 TyKind::Slice(..) => TyFingerprint::Slice, 53 TyKind::Slice(..) => TyFingerprint::Slice,
54 TyKind::Array(..) => TyFingerprint::Array, 54 TyKind::Array(..) => TyFingerprint::Array,
55 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), 55 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
56 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 56 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
57 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 57 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(*cardinality),
58 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 58 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
59 TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), 59 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
60 TyKind::Function(FnPointer { num_args, sig, .. }) => { 60 TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
61 TyFingerprint::FnPtr(num_args, sig) 61 TyFingerprint::FnPtr(substs.0.len(&Interner) - 1, *sig)
62 } 62 }
63 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 63 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
64 _ => return None, 64 _ => return None,
@@ -100,25 +100,38 @@ impl TraitImpls {
100 let mut impls = Self { map: FxHashMap::default() }; 100 let mut impls = Self { map: FxHashMap::default() };
101 101
102 let crate_def_map = db.crate_def_map(krate); 102 let crate_def_map = db.crate_def_map(krate);
103 for (_module_id, module_data) in crate_def_map.modules() { 103 collect_def_map(db, &crate_def_map, &mut impls);
104 for impl_id in module_data.scope.impls() { 104
105 let target_trait = match db.impl_trait(impl_id) { 105 return Arc::new(impls);
106 Some(tr) => tr.value.hir_trait_id(), 106
107 None => continue, 107 fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) {
108 }; 108 for (_module_id, module_data) in def_map.modules() {
109 let self_ty = db.impl_self_ty(impl_id); 109 for impl_id in module_data.scope.impls() {
110 let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); 110 let target_trait = match db.impl_trait(impl_id) {
111 impls 111 Some(tr) => tr.skip_binders().hir_trait_id(),
112 .map 112 None => continue,
113 .entry(target_trait) 113 };
114 .or_default() 114 let self_ty = db.impl_self_ty(impl_id);
115 .entry(self_ty_fp) 115 let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders());
116 .or_default() 116 impls
117 .push(impl_id); 117 .map
118 .entry(target_trait)
119 .or_default()
120 .entry(self_ty_fp)
121 .or_default()
122 .push(impl_id);
123 }
124
125 // To better support custom derives, collect impls in all unnamed const items.
126 // const _: () = { ... };
127 for konst in module_data.scope.unnamed_consts() {
128 let body = db.body(konst.into());
129 for (_, block_def_map) in body.blocks(db.upcast()) {
130 collect_def_map(db, &block_def_map, impls);
131 }
132 }
118 } 133 }
119 } 134 }
120
121 Arc::new(impls)
122 } 135 }
123 136
124 pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { 137 pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
@@ -202,12 +215,15 @@ impl InherentImpls {
202 } 215 }
203 216
204 let self_ty = db.impl_self_ty(impl_id); 217 let self_ty = db.impl_self_ty(impl_id);
205 if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { 218 if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) {
206 map.entry(fp).or_default().push(impl_id); 219 map.entry(fp).or_default().push(impl_id);
207 } 220 }
208 } 221 }
209 } 222 }
210 223
224 // NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only
225 // support trait impls there.
226
211 Arc::new(Self { map }) 227 Arc::new(Self { map })
212 } 228 }
213 229
@@ -223,15 +239,14 @@ impl InherentImpls {
223 } 239 }
224} 240}
225 241
226impl Ty { 242pub fn def_crates(
227 pub fn def_crates( 243 db: &dyn HirDatabase,
228 &self, 244 ty: &Ty,
229 db: &dyn HirDatabase, 245 cur_crate: CrateId,
230 cur_crate: CrateId, 246) -> Option<ArrayVec<CrateId, 2>> {
231 ) -> Option<ArrayVec<CrateId, 2>> { 247 // Types like slice can have inherent impls in several crates, (core and alloc).
232 // Types like slice can have inherent impls in several crates, (core and alloc). 248 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
233 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 249 macro_rules! lang_item_crate {
234 macro_rules! lang_item_crate {
235 ($($name:expr),+ $(,)?) => {{ 250 ($($name:expr),+ $(,)?) => {{
236 let mut v = ArrayVec::<LangItemTarget, 2>::new(); 251 let mut v = ArrayVec::<LangItemTarget, 2>::new();
237 $( 252 $(
@@ -241,51 +256,50 @@ impl Ty {
241 }}; 256 }};
242 } 257 }
243 258
244 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 259 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
245 260
246 let lang_item_targets = match self.interned(&Interner) { 261 let lang_item_targets = match ty.kind(&Interner) {
247 TyKind::Adt(AdtId(def_id), _) => { 262 TyKind::Adt(AdtId(def_id), _) => {
248 return mod_to_crate_ids(def_id.module(db.upcast())); 263 return mod_to_crate_ids(def_id.module(db.upcast()));
249 } 264 }
250 TyKind::ForeignType(id) => { 265 TyKind::Foreign(id) => {
251 return mod_to_crate_ids( 266 return mod_to_crate_ids(
252 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), 267 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
253 ); 268 );
254 } 269 }
255 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 270 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
256 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), 271 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
257 TyKind::Scalar(Scalar::Float(f)) => match f { 272 TyKind::Scalar(Scalar::Float(f)) => match f {
258 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 273 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
259 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 274 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
260 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 275 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
261 }, 276 },
262 &TyKind::Scalar(Scalar::Int(t)) => { 277 &TyKind::Scalar(Scalar::Int(t)) => {
263 lang_item_crate!(primitive::int_ty_to_string(t)) 278 lang_item_crate!(primitive::int_ty_to_string(t))
264 } 279 }
265 &TyKind::Scalar(Scalar::Uint(t)) => { 280 &TyKind::Scalar(Scalar::Uint(t)) => {
266 lang_item_crate!(primitive::uint_ty_to_string(t)) 281 lang_item_crate!(primitive::uint_ty_to_string(t))
267 } 282 }
268 TyKind::Str => lang_item_crate!("str_alloc", "str"), 283 TyKind::Str => lang_item_crate!("str_alloc", "str"),
269 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 284 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
270 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 285 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
271 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 286 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
272 TyKind::Dyn(_) => { 287 TyKind::Dyn(_) => {
273 return self.dyn_trait().and_then(|trait_| { 288 return ty.dyn_trait().and_then(|trait_| {
274 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 289 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
275 }); 290 });
276 } 291 }
277 _ => return None, 292 _ => return None,
278 }; 293 };
279 let res = lang_item_targets 294 let res = lang_item_targets
280 .into_iter() 295 .into_iter()
281 .filter_map(|it| match it { 296 .filter_map(|it| match it {
282 LangItemTarget::ImplDefId(it) => Some(it), 297 LangItemTarget::ImplDefId(it) => Some(it),
283 _ => None, 298 _ => None,
284 }) 299 })
285 .map(|it| it.lookup(db.upcast()).container.krate()) 300 .map(|it| it.lookup(db.upcast()).container.krate())
286 .collect(); 301 .collect();
287 Some(res) 302 Some(res)
288 }
289} 303}
290 304
291/// Look up the method with the given name, returning the actual autoderefed 305/// Look up the method with the given name, returning the actual autoderefed
@@ -454,7 +468,8 @@ fn iterate_method_candidates_with_autoref(
454 } 468 }
455 let refed = Canonical { 469 let refed = Canonical {
456 binders: deref_chain[0].binders.clone(), 470 binders: deref_chain[0].binders.clone(),
457 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 471 value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone())
472 .intern(&Interner),
458 }; 473 };
459 if iterate_method_candidates_by_receiver( 474 if iterate_method_candidates_by_receiver(
460 &refed, 475 &refed,
@@ -471,7 +486,8 @@ fn iterate_method_candidates_with_autoref(
471 } 486 }
472 let ref_muted = Canonical { 487 let ref_muted = Canonical {
473 binders: deref_chain[0].binders.clone(), 488 binders: deref_chain[0].binders.clone(),
474 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 489 value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone())
490 .intern(&Interner),
475 }; 491 };
476 if iterate_method_candidates_by_receiver( 492 if iterate_method_candidates_by_receiver(
477 &ref_muted, 493 &ref_muted,
@@ -563,7 +579,7 @@ fn iterate_trait_method_candidates(
563 // if ty is `dyn Trait`, the trait doesn't need to be in scope 579 // if ty is `dyn Trait`, the trait doesn't need to be in scope
564 let inherent_trait = 580 let inherent_trait =
565 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 581 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
566 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { 582 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) {
567 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 583 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
568 env.traits_in_scope_from_clauses(&self_ty.value) 584 env.traits_in_scope_from_clauses(&self_ty.value)
569 .flat_map(|t| all_super_traits(db.upcast(), t)) 585 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -610,7 +626,7 @@ fn iterate_inherent_methods(
610 visible_from_module: Option<ModuleId>, 626 visible_from_module: Option<ModuleId>,
611 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, 627 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
612) -> bool { 628) -> bool {
613 let def_crates = match self_ty.value.def_crates(db, krate) { 629 let def_crates = match def_crates(db, &self_ty.value, krate) {
614 Some(k) => k, 630 Some(k) => k,
615 None => return false, 631 None => return false,
616 }; 632 };
@@ -675,7 +691,7 @@ fn is_valid_candidate(
675 } 691 }
676 } 692 }
677 if let Some(receiver_ty) = receiver_ty { 693 if let Some(receiver_ty) = receiver_ty {
678 if !data.has_self_param { 694 if !data.has_self_param() {
679 return false; 695 return false;
680 } 696 }
681 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { 697 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
@@ -710,29 +726,32 @@ pub(crate) fn inherent_impl_substs(
710) -> Option<Substitution> { 726) -> Option<Substitution> {
711 // we create a var for each type parameter of the impl; we need to keep in 727 // we create a var for each type parameter of the impl; we need to keep in
712 // mind here that `self_ty` might have vars of its own 728 // mind here that `self_ty` might have vars of its own
713 let vars = Substitution::build_for_def(db, impl_id) 729 let self_ty_vars = self_ty.binders.len(&Interner);
714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) 730 let vars = TyBuilder::subst_for_def(db, impl_id)
731 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
715 .build(); 732 .build();
716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 733 let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars);
717 let mut kinds = self_ty.binders.interned().to_vec(); 734 let mut kinds = self_ty.binders.interned().to_vec();
718 kinds.extend( 735 kinds.extend(
719 iter::repeat(chalk_ir::WithKind::new( 736 iter::repeat(chalk_ir::WithKind::new(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 737 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT, 738 UniverseIndex::ROOT,
722 )) 739 ))
723 .take(vars.len()), 740 .take(vars.len(&Interner)),
724 ); 741 );
725 let tys = Canonical { 742 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 743 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
727 value: (self_ty_with_vars, self_ty.value.clone()), 744 value: (self_ty_with_vars, self_ty.value.clone()),
728 }; 745 };
729 let substs = super::infer::unify(&tys); 746 let substs = super::infer::unify(&tys)?;
730 // We only want the substs for the vars we added, not the ones from self_ty. 747 // We only want the substs for the vars we added, not the ones from self_ty.
731 // Also, if any of the vars we added are still in there, we replace them by 748 // Also, if any of the vars we added are still in there, we replace them by
732 // Unknown. I think this can only really happen if self_ty contained 749 // Unknown. I think this can only really happen if self_ty contained
733 // Unknown, and in that case we want the result to contain Unknown in those 750 // Unknown, and in that case we want the result to contain Unknown in those
734 // places again. 751 // places again.
735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) 752 let suffix =
753 Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars));
754 Some(fallback_bound_vars(suffix, self_ty_vars))
736} 755}
737 756
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 757/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -740,9 +759,9 @@ pub(crate) fn inherent_impl_substs(
740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 759fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
741 s.fold_binders( 760 s.fold_binders(
742 &mut |ty, binders| { 761 &mut |ty, binders| {
743 if let TyKind::BoundVar(bound) = ty.interned(&Interner) { 762 if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 763 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
745 TyKind::Unknown.intern(&Interner) 764 TyKind::Error.intern(&Interner)
746 } else { 765 } else {
747 ty 766 ty
748 } 767 }
@@ -760,13 +779,13 @@ fn transform_receiver_ty(
760 self_ty: &Canonical<Ty>, 779 self_ty: &Canonical<Ty>,
761) -> Option<Ty> { 780) -> Option<Ty> {
762 let substs = match function_id.lookup(db.upcast()).container { 781 let substs = match function_id.lookup(db.upcast()).container {
763 AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id) 782 AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
764 .push(self_ty.value.clone()) 783 .push(self_ty.value.clone())
765 .fill_with_unknown() 784 .fill_with_unknown()
766 .build(), 785 .build(),
767 AssocContainerId::ImplId(impl_id) => { 786 AssocContainerId::ImplId(impl_id) => {
768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 787 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
769 Substitution::build_for_def(db, function_id) 788 TyBuilder::subst_for_def(db, function_id)
770 .use_parent_substs(&impl_substs) 789 .use_parent_substs(&impl_substs)
771 .fill_with_unknown() 790 .fill_with_unknown()
772 .build() 791 .build()
@@ -774,7 +793,7 @@ fn transform_receiver_ty(
774 AssocContainerId::ModuleId(_) => unreachable!(), 793 AssocContainerId::ModuleId(_) => unreachable!(),
775 }; 794 };
776 let sig = db.callable_item_signature(function_id.into()); 795 let sig = db.callable_item_signature(function_id.into());
777 Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) 796 Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs))
778} 797}
779 798
780pub fn implements_trait( 799pub fn implements_trait(
@@ -800,7 +819,7 @@ pub fn implements_trait_unique(
800 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 819 let goal = generic_implements_goal(db, env, trait_, ty.clone());
801 let solution = db.trait_solve(krate, goal); 820 let solution = db.trait_solve(krate, goal);
802 821
803 matches!(solution, Some(crate::traits::Solution::Unique(_))) 822 matches!(solution, Some(crate::Solution::Unique(_)))
804} 823}
805 824
806/// This creates Substs for a trait with the given Self type and type variables 825/// This creates Substs for a trait with the given Self type and type variables
@@ -812,7 +831,7 @@ fn generic_implements_goal(
812 self_ty: Canonical<Ty>, 831 self_ty: Canonical<Ty>,
813) -> Canonical<InEnvironment<super::DomainGoal>> { 832) -> Canonical<InEnvironment<super::DomainGoal>> {
814 let mut kinds = self_ty.binders.interned().to_vec(); 833 let mut kinds = self_ty.binders.interned().to_vec();
815 let substs = super::Substitution::build_for_def(db, trait_) 834 let trait_ref = TyBuilder::trait_ref(db, trait_)
816 .push(self_ty.value) 835 .push(self_ty.value)
817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 836 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
818 .build(); 837 .build();
@@ -821,13 +840,12 @@ fn generic_implements_goal(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 840 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT, 841 UniverseIndex::ROOT,
823 )) 842 ))
824 .take(substs.len() - 1), 843 .take(trait_ref.substitution.len(&Interner) - 1),
825 ); 844 );
826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
827 let obligation = trait_ref.cast(&Interner); 845 let obligation = trait_ref.cast(&Interner);
828 Canonical { 846 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 847 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
830 value: InEnvironment::new(env.env.clone(), obligation), 848 value: InEnvironment::new(&env.env, obligation),
831 } 849 }
832} 850}
833 851
@@ -838,8 +856,8 @@ fn autoderef_method_receiver(
838) -> Vec<Canonical<Ty>> { 856) -> Vec<Canonical<Ty>> {
839 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 857 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
840 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 858 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
841 if let Some(TyKind::Array(parameters)) = 859 if let Some(TyKind::Array(parameters, _)) =
842 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 860 deref_chain.last().map(|ty| ty.value.kind(&Interner))
843 { 861 {
844 let kinds = deref_chain.last().unwrap().binders.clone(); 862 let kinds = deref_chain.last().unwrap().binders.clone();
845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 863 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);