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.rs316
1 files changed, 186 insertions, 130 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index bf7d5eded..3693e3284 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,52 +19,91 @@ 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, ForeignDefId, InEnvironment, Interner,
25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, 25 Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
26 TypeWalk,
27}; 26};
28 27
29/// This is used as a key for indexing impls. 28/// This is used as a key for indexing impls.
30#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 29#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
31pub enum TyFingerprint { 30pub enum TyFingerprint {
31 // These are lang item impls:
32 Str, 32 Str,
33 Slice, 33 Slice,
34 Array, 34 Array,
35 Never, 35 Never,
36 RawPtr(Mutability), 36 RawPtr(Mutability),
37 Scalar(Scalar), 37 Scalar(Scalar),
38 // These can have user-defined impls:
38 Adt(hir_def::AdtId), 39 Adt(hir_def::AdtId),
39 Dyn(TraitId), 40 Dyn(TraitId),
40 Tuple(usize),
41 ForeignType(ForeignDefId), 41 ForeignType(ForeignDefId),
42 FnPtr(usize, FnSig), 42 // These only exist for trait impls
43 Unit,
44 Unnameable,
45 Function(u32),
43} 46}
44 47
45impl TyFingerprint { 48impl TyFingerprint {
46 /// Creates a TyFingerprint for looking up an impl. Only certain types can 49 /// Creates a TyFingerprint for looking up an inherent impl. Only certain
47 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 50 /// types can have inherent impls: if we have some `struct S`, we can have
48 /// `impl &S`. Hence, this will return `None` for reference types and such. 51 /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
49 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 52 /// reference types and such.
50 let fp = match *ty.interned(&Interner) { 53 pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
54 let fp = match ty.kind(&Interner) {
51 TyKind::Str => TyFingerprint::Str, 55 TyKind::Str => TyFingerprint::Str,
52 TyKind::Never => TyFingerprint::Never, 56 TyKind::Never => TyFingerprint::Never,
53 TyKind::Slice(..) => TyFingerprint::Slice, 57 TyKind::Slice(..) => TyFingerprint::Slice,
54 TyKind::Array(..) => TyFingerprint::Array, 58 TyKind::Array(..) => TyFingerprint::Array,
55 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), 59 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
56 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 60 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
57 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 61 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
58 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 62 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
59 TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
60 TyKind::Function(FnPointer { num_args, sig, .. }) => {
61 TyFingerprint::FnPtr(num_args, sig)
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,
65 }; 65 };
66 Some(fp) 66 Some(fp)
67 } 67 }
68
69 /// Creates a TyFingerprint for looking up a trait impl.
70 pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> {
71 let fp = match ty.kind(&Interner) {
72 TyKind::Str => TyFingerprint::Str,
73 TyKind::Never => TyFingerprint::Never,
74 TyKind::Slice(..) => TyFingerprint::Slice,
75 TyKind::Array(..) => TyFingerprint::Array,
76 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
77 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
78 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
79 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
80 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
81 TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty),
82 TyKind::Tuple(_, subst) => {
83 let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(&Interner));
84 if let Some(ty) = first_ty {
85 return TyFingerprint::for_trait_impl(ty);
86 } else {
87 TyFingerprint::Unit
88 }
89 }
90 TyKind::AssociatedType(_, _)
91 | TyKind::OpaqueType(_, _)
92 | TyKind::FnDef(_, _)
93 | TyKind::Closure(_, _)
94 | TyKind::Generator(..)
95 | TyKind::GeneratorWitness(..) => TyFingerprint::Unnameable,
96 TyKind::Function(fn_ptr) => {
97 TyFingerprint::Function(fn_ptr.substitution.0.len(&Interner) as u32)
98 }
99 TyKind::Alias(_)
100 | TyKind::Placeholder(_)
101 | TyKind::BoundVar(_)
102 | TyKind::InferenceVar(_, _)
103 | TyKind::Error => return None,
104 };
105 Some(fp)
106 }
68} 107}
69 108
70pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 109pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
@@ -100,25 +139,38 @@ impl TraitImpls {
100 let mut impls = Self { map: FxHashMap::default() }; 139 let mut impls = Self { map: FxHashMap::default() };
101 140
102 let crate_def_map = db.crate_def_map(krate); 141 let crate_def_map = db.crate_def_map(krate);
103 for (_module_id, module_data) in crate_def_map.modules() { 142 collect_def_map(db, &crate_def_map, &mut impls);
104 for impl_id in module_data.scope.impls() { 143
105 let target_trait = match db.impl_trait(impl_id) { 144 return Arc::new(impls);
106 Some(tr) => tr.value.hir_trait_id(), 145
107 None => continue, 146 fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) {
108 }; 147 for (_module_id, module_data) in def_map.modules() {
109 let self_ty = db.impl_self_ty(impl_id); 148 for impl_id in module_data.scope.impls() {
110 let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); 149 let target_trait = match db.impl_trait(impl_id) {
111 impls 150 Some(tr) => tr.skip_binders().hir_trait_id(),
112 .map 151 None => continue,
113 .entry(target_trait) 152 };
114 .or_default() 153 let self_ty = db.impl_self_ty(impl_id);
115 .entry(self_ty_fp) 154 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
116 .or_default() 155 impls
117 .push(impl_id); 156 .map
157 .entry(target_trait)
158 .or_default()
159 .entry(self_ty_fp)
160 .or_default()
161 .push(impl_id);
162 }
163
164 // To better support custom derives, collect impls in all unnamed const items.
165 // const _: () = { ... };
166 for konst in module_data.scope.unnamed_consts() {
167 let body = db.body(konst.into());
168 for (_, block_def_map) in body.blocks(db.upcast()) {
169 collect_def_map(db, &block_def_map, impls);
170 }
171 }
118 } 172 }
119 } 173 }
120
121 Arc::new(impls)
122 } 174 }
123 175
124 pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { 176 pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
@@ -144,10 +196,13 @@ impl TraitImpls {
144 } 196 }
145 197
146 /// Queries all trait impls for the given type. 198 /// Queries all trait impls for the given type.
147 pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ { 199 pub fn for_self_ty_without_blanket_impls(
200 &self,
201 fp: TyFingerprint,
202 ) -> impl Iterator<Item = ImplId> + '_ {
148 self.map 203 self.map
149 .values() 204 .values()
150 .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp)))) 205 .flat_map(move |impls| impls.get(&Some(fp)).into_iter())
151 .flat_map(|it| it.iter().copied()) 206 .flat_map(|it| it.iter().copied())
152 } 207 }
153 208
@@ -202,17 +257,22 @@ impl InherentImpls {
202 } 257 }
203 258
204 let self_ty = db.impl_self_ty(impl_id); 259 let self_ty = db.impl_self_ty(impl_id);
205 if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { 260 let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders());
261 if let Some(fp) = fp {
206 map.entry(fp).or_default().push(impl_id); 262 map.entry(fp).or_default().push(impl_id);
207 } 263 }
264 // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
208 } 265 }
209 } 266 }
210 267
268 // NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only
269 // support trait impls there.
270
211 Arc::new(Self { map }) 271 Arc::new(Self { map })
212 } 272 }
213 273
214 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { 274 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
215 match TyFingerprint::for_impl(self_ty) { 275 match TyFingerprint::for_inherent_impl(self_ty) {
216 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), 276 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
217 None => &[], 277 None => &[],
218 } 278 }
@@ -223,15 +283,14 @@ impl InherentImpls {
223 } 283 }
224} 284}
225 285
226impl Ty { 286pub fn def_crates(
227 pub fn def_crates( 287 db: &dyn HirDatabase,
228 &self, 288 ty: &Ty,
229 db: &dyn HirDatabase, 289 cur_crate: CrateId,
230 cur_crate: CrateId, 290) -> Option<ArrayVec<CrateId, 2>> {
231 ) -> Option<ArrayVec<CrateId, 2>> { 291 // 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). 292 // 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. 293 macro_rules! lang_item_crate {
234 macro_rules! lang_item_crate {
235 ($($name:expr),+ $(,)?) => {{ 294 ($($name:expr),+ $(,)?) => {{
236 let mut v = ArrayVec::<LangItemTarget, 2>::new(); 295 let mut v = ArrayVec::<LangItemTarget, 2>::new();
237 $( 296 $(
@@ -241,51 +300,50 @@ impl Ty {
241 }}; 300 }};
242 } 301 }
243 302
244 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 303 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
245 304
246 let lang_item_targets = match self.interned(&Interner) { 305 let lang_item_targets = match ty.kind(&Interner) {
247 TyKind::Adt(AdtId(def_id), _) => { 306 TyKind::Adt(AdtId(def_id), _) => {
248 return mod_to_crate_ids(def_id.module(db.upcast())); 307 return mod_to_crate_ids(def_id.module(db.upcast()));
249 } 308 }
250 TyKind::ForeignType(id) => { 309 TyKind::Foreign(id) => {
251 return mod_to_crate_ids( 310 return mod_to_crate_ids(
252 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), 311 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
253 ); 312 );
254 } 313 }
255 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 314 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
256 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), 315 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
257 TyKind::Scalar(Scalar::Float(f)) => match f { 316 TyKind::Scalar(Scalar::Float(f)) => match f {
258 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 317 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
259 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 318 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
260 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 319 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
261 }, 320 },
262 &TyKind::Scalar(Scalar::Int(t)) => { 321 &TyKind::Scalar(Scalar::Int(t)) => {
263 lang_item_crate!(primitive::int_ty_to_string(t)) 322 lang_item_crate!(primitive::int_ty_to_string(t))
264 } 323 }
265 &TyKind::Scalar(Scalar::Uint(t)) => { 324 &TyKind::Scalar(Scalar::Uint(t)) => {
266 lang_item_crate!(primitive::uint_ty_to_string(t)) 325 lang_item_crate!(primitive::uint_ty_to_string(t))
267 } 326 }
268 TyKind::Str => lang_item_crate!("str_alloc", "str"), 327 TyKind::Str => lang_item_crate!("str_alloc", "str"),
269 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 328 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
270 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 329 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
271 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 330 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
272 TyKind::Dyn(_) => { 331 TyKind::Dyn(_) => {
273 return self.dyn_trait().and_then(|trait_| { 332 return ty.dyn_trait().and_then(|trait_| {
274 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 333 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
275 }); 334 });
276 } 335 }
277 _ => return None, 336 _ => return None,
278 }; 337 };
279 let res = lang_item_targets 338 let res = lang_item_targets
280 .into_iter() 339 .into_iter()
281 .filter_map(|it| match it { 340 .filter_map(|it| match it {
282 LangItemTarget::ImplDefId(it) => Some(it), 341 LangItemTarget::ImplDefId(it) => Some(it),
283 _ => None, 342 _ => None,
284 }) 343 })
285 .map(|it| it.lookup(db.upcast()).container.krate()) 344 .map(|it| it.lookup(db.upcast()).container.krate())
286 .collect(); 345 .collect();
287 Some(res) 346 Some(res)
288 }
289} 347}
290 348
291/// Look up the method with the given name, returning the actual autoderefed 349/// Look up the method with the given name, returning the actual autoderefed
@@ -454,7 +512,8 @@ fn iterate_method_candidates_with_autoref(
454 } 512 }
455 let refed = Canonical { 513 let refed = Canonical {
456 binders: deref_chain[0].binders.clone(), 514 binders: deref_chain[0].binders.clone(),
457 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 515 value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone())
516 .intern(&Interner),
458 }; 517 };
459 if iterate_method_candidates_by_receiver( 518 if iterate_method_candidates_by_receiver(
460 &refed, 519 &refed,
@@ -471,7 +530,8 @@ fn iterate_method_candidates_with_autoref(
471 } 530 }
472 let ref_muted = Canonical { 531 let ref_muted = Canonical {
473 binders: deref_chain[0].binders.clone(), 532 binders: deref_chain[0].binders.clone(),
474 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 533 value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone())
534 .intern(&Interner),
475 }; 535 };
476 if iterate_method_candidates_by_receiver( 536 if iterate_method_candidates_by_receiver(
477 &ref_muted, 537 &ref_muted,
@@ -563,7 +623,7 @@ fn iterate_trait_method_candidates(
563 // if ty is `dyn Trait`, the trait doesn't need to be in scope 623 // if ty is `dyn Trait`, the trait doesn't need to be in scope
564 let inherent_trait = 624 let inherent_trait =
565 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 625 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) { 626 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 627 // 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) 628 env.traits_in_scope_from_clauses(&self_ty.value)
569 .flat_map(|t| all_super_traits(db.upcast(), t)) 629 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -593,6 +653,7 @@ fn iterate_trait_method_candidates(
593 } 653 }
594 } 654 }
595 known_implemented = true; 655 known_implemented = true;
656 // FIXME: we shouldn't be ignoring the binders here
596 if callback(&self_ty.value, *item) { 657 if callback(&self_ty.value, *item) {
597 return true; 658 return true;
598 } 659 }
@@ -610,7 +671,7 @@ fn iterate_inherent_methods(
610 visible_from_module: Option<ModuleId>, 671 visible_from_module: Option<ModuleId>,
611 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, 672 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
612) -> bool { 673) -> bool {
613 let def_crates = match self_ty.value.def_crates(db, krate) { 674 let def_crates = match def_crates(db, &self_ty.value, krate) {
614 Some(k) => k, 675 Some(k) => k,
615 None => return false, 676 None => return false,
616 }; 677 };
@@ -675,7 +736,7 @@ fn is_valid_candidate(
675 } 736 }
676 } 737 }
677 if let Some(receiver_ty) = receiver_ty { 738 if let Some(receiver_ty) = receiver_ty {
678 if !data.has_self_param { 739 if !data.has_self_param() {
679 return false; 740 return false;
680 } 741 }
681 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { 742 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
@@ -710,48 +771,44 @@ pub(crate) fn inherent_impl_substs(
710) -> Option<Substitution> { 771) -> Option<Substitution> {
711 // we create a var for each type parameter of the impl; we need to keep in 772 // 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 773 // mind here that `self_ty` might have vars of its own
713 let vars = Substitution::build_for_def(db, impl_id) 774 let self_ty_vars = self_ty.binders.len(&Interner);
714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) 775 let vars = TyBuilder::subst_for_def(db, impl_id)
776 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
715 .build(); 777 .build();
716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 778 let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars);
717 let mut kinds = self_ty.binders.interned().to_vec(); 779 let mut kinds = self_ty.binders.interned().to_vec();
718 kinds.extend( 780 kinds.extend(
719 iter::repeat(chalk_ir::WithKind::new( 781 iter::repeat(chalk_ir::WithKind::new(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 782 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT, 783 UniverseIndex::ROOT,
722 )) 784 ))
723 .take(vars.len()), 785 .take(vars.len(&Interner)),
724 ); 786 );
725 let tys = Canonical { 787 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 788 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
727 value: (self_ty_with_vars, self_ty.value.clone()), 789 value: (self_ty_with_vars, self_ty.value.clone()),
728 }; 790 };
729 let substs = super::infer::unify(&tys); 791 let substs = super::infer::unify(&tys)?;
730 // We only want the substs for the vars we added, not the ones from self_ty. 792 // 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 793 // 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 794 // 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 795 // Unknown, and in that case we want the result to contain Unknown in those
734 // places again. 796 // places again.
735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) 797 let suffix =
798 Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars));
799 Some(fallback_bound_vars(suffix, self_ty_vars))
736} 800}
737 801
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 802/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
739/// num_vars_to_keep) by `TyKind::Unknown`. 803/// num_vars_to_keep) by `TyKind::Unknown`.
740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 804fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
741 s.fold_binders( 805 crate::fold_free_vars(s, |bound, binders| {
742 &mut |ty, binders| { 806 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
743 if let TyKind::BoundVar(bound) = ty.interned(&Interner) { 807 TyKind::Error.intern(&Interner)
744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 808 } else {
745 TyKind::Unknown.intern(&Interner) 809 bound.shifted_in_from(binders).to_ty(&Interner)
746 } else { 810 }
747 ty 811 })
748 }
749 } else {
750 ty
751 }
752 },
753 DebruijnIndex::INNERMOST,
754 )
755} 812}
756 813
757fn transform_receiver_ty( 814fn transform_receiver_ty(
@@ -760,13 +817,13 @@ fn transform_receiver_ty(
760 self_ty: &Canonical<Ty>, 817 self_ty: &Canonical<Ty>,
761) -> Option<Ty> { 818) -> Option<Ty> {
762 let substs = match function_id.lookup(db.upcast()).container { 819 let substs = match function_id.lookup(db.upcast()).container {
763 AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id) 820 AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
764 .push(self_ty.value.clone()) 821 .push(self_ty.value.clone())
765 .fill_with_unknown() 822 .fill_with_unknown()
766 .build(), 823 .build(),
767 AssocContainerId::ImplId(impl_id) => { 824 AssocContainerId::ImplId(impl_id) => {
768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 825 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
769 Substitution::build_for_def(db, function_id) 826 TyBuilder::subst_for_def(db, function_id)
770 .use_parent_substs(&impl_substs) 827 .use_parent_substs(&impl_substs)
771 .fill_with_unknown() 828 .fill_with_unknown()
772 .build() 829 .build()
@@ -774,7 +831,7 @@ fn transform_receiver_ty(
774 AssocContainerId::ModuleId(_) => unreachable!(), 831 AssocContainerId::ModuleId(_) => unreachable!(),
775 }; 832 };
776 let sig = db.callable_item_signature(function_id.into()); 833 let sig = db.callable_item_signature(function_id.into());
777 Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) 834 Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs))
778} 835}
779 836
780pub fn implements_trait( 837pub fn implements_trait(
@@ -800,7 +857,7 @@ pub fn implements_trait_unique(
800 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 857 let goal = generic_implements_goal(db, env, trait_, ty.clone());
801 let solution = db.trait_solve(krate, goal); 858 let solution = db.trait_solve(krate, goal);
802 859
803 matches!(solution, Some(crate::traits::Solution::Unique(_))) 860 matches!(solution, Some(crate::Solution::Unique(_)))
804} 861}
805 862
806/// This creates Substs for a trait with the given Self type and type variables 863/// This creates Substs for a trait with the given Self type and type variables
@@ -812,7 +869,7 @@ fn generic_implements_goal(
812 self_ty: Canonical<Ty>, 869 self_ty: Canonical<Ty>,
813) -> Canonical<InEnvironment<super::DomainGoal>> { 870) -> Canonical<InEnvironment<super::DomainGoal>> {
814 let mut kinds = self_ty.binders.interned().to_vec(); 871 let mut kinds = self_ty.binders.interned().to_vec();
815 let substs = super::Substitution::build_for_def(db, trait_) 872 let trait_ref = TyBuilder::trait_ref(db, trait_)
816 .push(self_ty.value) 873 .push(self_ty.value)
817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 874 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
818 .build(); 875 .build();
@@ -821,13 +878,12 @@ fn generic_implements_goal(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 878 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT, 879 UniverseIndex::ROOT,
823 )) 880 ))
824 .take(substs.len() - 1), 881 .take(trait_ref.substitution.len(&Interner) - 1),
825 ); 882 );
826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
827 let obligation = trait_ref.cast(&Interner); 883 let obligation = trait_ref.cast(&Interner);
828 Canonical { 884 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 885 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
830 value: InEnvironment::new(env.env.clone(), obligation), 886 value: InEnvironment::new(&env.env, obligation),
831 } 887 }
832} 888}
833 889
@@ -838,8 +894,8 @@ fn autoderef_method_receiver(
838) -> Vec<Canonical<Ty>> { 894) -> Vec<Canonical<Ty>> {
839 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 895 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!) 896 // 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)) = 897 if let Some(TyKind::Array(parameters, _)) =
842 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 898 deref_chain.last().map(|ty| ty.value.kind(&Interner))
843 { 899 {
844 let kinds = deref_chain.last().unwrap().binders.clone(); 900 let kinds = deref_chain.last().unwrap().binders.clone();
845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 901 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);