diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 232 |
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; | |||
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; | 9 | use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; |
10 | use hir_def::{ | 10 | use 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 | }; |
14 | use hir_expand::name::Name; | 14 | use hir_expand::name::Name; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use 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 | ||
226 | impl Ty { | 242 | pub 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( | |||
740 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { | 759 | fn 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 | ||
780 | pub fn implements_trait( | 799 | pub 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); |