diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 294 |
1 files changed, 177 insertions, 117 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 19a1fa793..ece884241 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -8,62 +8,103 @@ 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}; |
16 | use stdx::always; | ||
16 | 17 | ||
17 | use crate::{ | 18 | use crate::{ |
18 | autoderef, | 19 | autoderef, |
19 | db::HirDatabase, | 20 | db::HirDatabase, |
20 | from_foreign_def_id, | 21 | from_foreign_def_id, |
21 | primitive::{self, FloatTy, IntTy, UintTy}, | 22 | primitive::{self, FloatTy, IntTy, UintTy}, |
23 | static_lifetime, | ||
22 | utils::all_super_traits, | 24 | utils::all_super_traits, |
23 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, | 25 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner, |
24 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind, | 26 | Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, |
25 | TypeWalk, | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | /// This is used as a key for indexing impls. | 29 | /// This is used as a key for indexing impls. |
29 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 30 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
30 | pub enum TyFingerprint { | 31 | pub enum TyFingerprint { |
32 | // These are lang item impls: | ||
31 | Str, | 33 | Str, |
32 | Slice, | 34 | Slice, |
33 | Array, | 35 | Array, |
34 | Never, | 36 | Never, |
35 | RawPtr(Mutability), | 37 | RawPtr(Mutability), |
36 | Scalar(Scalar), | 38 | Scalar(Scalar), |
39 | // These can have user-defined impls: | ||
37 | Adt(hir_def::AdtId), | 40 | Adt(hir_def::AdtId), |
38 | Dyn(TraitId), | 41 | Dyn(TraitId), |
39 | Tuple(usize), | ||
40 | ForeignType(ForeignDefId), | 42 | ForeignType(ForeignDefId), |
41 | FnPtr(usize, FnSig), | 43 | // These only exist for trait impls |
44 | Unit, | ||
45 | Unnameable, | ||
46 | Function(u32), | ||
42 | } | 47 | } |
43 | 48 | ||
44 | impl TyFingerprint { | 49 | impl TyFingerprint { |
45 | /// Creates a TyFingerprint for looking up an impl. Only certain types can | 50 | /// Creates a TyFingerprint for looking up an inherent impl. Only certain |
46 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 51 | /// types can have inherent impls: if we have some `struct S`, we can have |
47 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 52 | /// an `impl S`, but not `impl &S`. Hence, this will return `None` for |
48 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 53 | /// reference types and such. |
49 | let fp = match *ty.kind(&Interner) { | 54 | pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> { |
55 | let fp = match ty.kind(&Interner) { | ||
50 | TyKind::Str => TyFingerprint::Str, | 56 | TyKind::Str => TyFingerprint::Str, |
51 | TyKind::Never => TyFingerprint::Never, | 57 | TyKind::Never => TyFingerprint::Never, |
52 | TyKind::Slice(..) => TyFingerprint::Slice, | 58 | TyKind::Slice(..) => TyFingerprint::Slice, |
53 | TyKind::Array(..) => TyFingerprint::Array, | 59 | TyKind::Array(..) => TyFingerprint::Array, |
54 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), | 60 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), |
55 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), | 61 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), |
56 | TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | 62 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), |
57 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), | 63 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), |
58 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | ||
59 | TyKind::Function(FnPointer { num_args, sig, .. }) => { | ||
60 | TyFingerprint::FnPtr(num_args, sig) | ||
61 | } | ||
62 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | 64 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, |
63 | _ => return None, | 65 | _ => return None, |
64 | }; | 66 | }; |
65 | Some(fp) | 67 | Some(fp) |
66 | } | 68 | } |
69 | |||
70 | /// Creates a TyFingerprint for looking up a trait impl. | ||
71 | pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> { | ||
72 | let fp = match ty.kind(&Interner) { | ||
73 | TyKind::Str => TyFingerprint::Str, | ||
74 | TyKind::Never => TyFingerprint::Never, | ||
75 | TyKind::Slice(..) => TyFingerprint::Slice, | ||
76 | TyKind::Array(..) => TyFingerprint::Array, | ||
77 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), | ||
78 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), | ||
79 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), | ||
80 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), | ||
81 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
82 | TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty), | ||
83 | TyKind::Tuple(_, subst) => { | ||
84 | let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(&Interner)); | ||
85 | if let Some(ty) = first_ty { | ||
86 | return TyFingerprint::for_trait_impl(ty); | ||
87 | } else { | ||
88 | TyFingerprint::Unit | ||
89 | } | ||
90 | } | ||
91 | TyKind::AssociatedType(_, _) | ||
92 | | TyKind::OpaqueType(_, _) | ||
93 | | TyKind::FnDef(_, _) | ||
94 | | TyKind::Closure(_, _) | ||
95 | | TyKind::Generator(..) | ||
96 | | TyKind::GeneratorWitness(..) => TyFingerprint::Unnameable, | ||
97 | TyKind::Function(fn_ptr) => { | ||
98 | TyFingerprint::Function(fn_ptr.substitution.0.len(&Interner) as u32) | ||
99 | } | ||
100 | TyKind::Alias(_) | ||
101 | | TyKind::Placeholder(_) | ||
102 | | TyKind::BoundVar(_) | ||
103 | | TyKind::InferenceVar(_, _) | ||
104 | | TyKind::Error => return None, | ||
105 | }; | ||
106 | Some(fp) | ||
107 | } | ||
67 | } | 108 | } |
68 | 109 | ||
69 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 110 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
@@ -99,25 +140,38 @@ impl TraitImpls { | |||
99 | let mut impls = Self { map: FxHashMap::default() }; | 140 | let mut impls = Self { map: FxHashMap::default() }; |
100 | 141 | ||
101 | let crate_def_map = db.crate_def_map(krate); | 142 | let crate_def_map = db.crate_def_map(krate); |
102 | for (_module_id, module_data) in crate_def_map.modules() { | 143 | collect_def_map(db, &crate_def_map, &mut impls); |
103 | for impl_id in module_data.scope.impls() { | 144 | |
104 | let target_trait = match db.impl_trait(impl_id) { | 145 | return Arc::new(impls); |
105 | Some(tr) => tr.skip_binders().hir_trait_id(), | 146 | |
106 | None => continue, | 147 | fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) { |
107 | }; | 148 | for (_module_id, module_data) in def_map.modules() { |
108 | let self_ty = db.impl_self_ty(impl_id); | 149 | for impl_id in module_data.scope.impls() { |
109 | let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders()); | 150 | let target_trait = match db.impl_trait(impl_id) { |
110 | impls | 151 | Some(tr) => tr.skip_binders().hir_trait_id(), |
111 | .map | 152 | None => continue, |
112 | .entry(target_trait) | 153 | }; |
113 | .or_default() | 154 | let self_ty = db.impl_self_ty(impl_id); |
114 | .entry(self_ty_fp) | 155 | let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders()); |
115 | .or_default() | 156 | impls |
116 | .push(impl_id); | 157 | .map |
158 | .entry(target_trait) | ||
159 | .or_default() | ||
160 | .entry(self_ty_fp) | ||
161 | .or_default() | ||
162 | .push(impl_id); | ||
163 | } | ||
164 | |||
165 | // To better support custom derives, collect impls in all unnamed const items. | ||
166 | // const _: () = { ... }; | ||
167 | for konst in module_data.scope.unnamed_consts() { | ||
168 | let body = db.body(konst.into()); | ||
169 | for (_, block_def_map) in body.blocks(db.upcast()) { | ||
170 | collect_def_map(db, &block_def_map, impls); | ||
171 | } | ||
172 | } | ||
117 | } | 173 | } |
118 | } | 174 | } |
119 | |||
120 | Arc::new(impls) | ||
121 | } | 175 | } |
122 | 176 | ||
123 | pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { | 177 | pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { |
@@ -143,10 +197,13 @@ impl TraitImpls { | |||
143 | } | 197 | } |
144 | 198 | ||
145 | /// Queries all trait impls for the given type. | 199 | /// Queries all trait impls for the given type. |
146 | pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ { | 200 | pub fn for_self_ty_without_blanket_impls( |
201 | &self, | ||
202 | fp: TyFingerprint, | ||
203 | ) -> impl Iterator<Item = ImplId> + '_ { | ||
147 | self.map | 204 | self.map |
148 | .values() | 205 | .values() |
149 | .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp)))) | 206 | .flat_map(move |impls| impls.get(&Some(fp)).into_iter()) |
150 | .flat_map(|it| it.iter().copied()) | 207 | .flat_map(|it| it.iter().copied()) |
151 | } | 208 | } |
152 | 209 | ||
@@ -201,17 +258,22 @@ impl InherentImpls { | |||
201 | } | 258 | } |
202 | 259 | ||
203 | let self_ty = db.impl_self_ty(impl_id); | 260 | let self_ty = db.impl_self_ty(impl_id); |
204 | if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) { | 261 | let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders()); |
262 | always!(fp.is_some()); | ||
263 | if let Some(fp) = fp { | ||
205 | map.entry(fp).or_default().push(impl_id); | 264 | map.entry(fp).or_default().push(impl_id); |
206 | } | 265 | } |
207 | } | 266 | } |
208 | } | 267 | } |
209 | 268 | ||
269 | // NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only | ||
270 | // support trait impls there. | ||
271 | |||
210 | Arc::new(Self { map }) | 272 | Arc::new(Self { map }) |
211 | } | 273 | } |
212 | 274 | ||
213 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { | 275 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { |
214 | match TyFingerprint::for_impl(self_ty) { | 276 | match TyFingerprint::for_inherent_impl(self_ty) { |
215 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), | 277 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), |
216 | None => &[], | 278 | None => &[], |
217 | } | 279 | } |
@@ -222,15 +284,14 @@ impl InherentImpls { | |||
222 | } | 284 | } |
223 | } | 285 | } |
224 | 286 | ||
225 | impl Ty { | 287 | pub fn def_crates( |
226 | pub fn def_crates( | 288 | db: &dyn HirDatabase, |
227 | &self, | 289 | ty: &Ty, |
228 | db: &dyn HirDatabase, | 290 | cur_crate: CrateId, |
229 | cur_crate: CrateId, | 291 | ) -> Option<ArrayVec<CrateId, 2>> { |
230 | ) -> Option<ArrayVec<CrateId, 2>> { | 292 | // Types like slice can have inherent impls in several crates, (core and alloc). |
231 | // Types like slice can have inherent impls in several crates, (core and alloc). | 293 | // The corresponding impls are marked with lang items, so we can use them to find the required crates. |
232 | // The corresponding impls are marked with lang items, so we can use them to find the required crates. | 294 | macro_rules! lang_item_crate { |
233 | macro_rules! lang_item_crate { | ||
234 | ($($name:expr),+ $(,)?) => {{ | 295 | ($($name:expr),+ $(,)?) => {{ |
235 | let mut v = ArrayVec::<LangItemTarget, 2>::new(); | 296 | let mut v = ArrayVec::<LangItemTarget, 2>::new(); |
236 | $( | 297 | $( |
@@ -240,51 +301,50 @@ impl Ty { | |||
240 | }}; | 301 | }}; |
241 | } | 302 | } |
242 | 303 | ||
243 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 304 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
244 | 305 | ||
245 | let lang_item_targets = match self.kind(&Interner) { | 306 | let lang_item_targets = match ty.kind(&Interner) { |
246 | TyKind::Adt(AdtId(def_id), _) => { | 307 | TyKind::Adt(AdtId(def_id), _) => { |
247 | return mod_to_crate_ids(def_id.module(db.upcast())); | 308 | return mod_to_crate_ids(def_id.module(db.upcast())); |
248 | } | 309 | } |
249 | TyKind::Foreign(id) => { | 310 | TyKind::Foreign(id) => { |
250 | return mod_to_crate_ids( | 311 | return mod_to_crate_ids( |
251 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), | 312 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), |
252 | ); | 313 | ); |
253 | } | 314 | } |
254 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 315 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
255 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), | 316 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), |
256 | TyKind::Scalar(Scalar::Float(f)) => match f { | 317 | TyKind::Scalar(Scalar::Float(f)) => match f { |
257 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 318 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
258 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 319 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
259 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | 320 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
260 | }, | 321 | }, |
261 | &TyKind::Scalar(Scalar::Int(t)) => { | 322 | &TyKind::Scalar(Scalar::Int(t)) => { |
262 | lang_item_crate!(primitive::int_ty_to_string(t)) | 323 | lang_item_crate!(primitive::int_ty_to_string(t)) |
263 | } | 324 | } |
264 | &TyKind::Scalar(Scalar::Uint(t)) => { | 325 | &TyKind::Scalar(Scalar::Uint(t)) => { |
265 | lang_item_crate!(primitive::uint_ty_to_string(t)) | 326 | lang_item_crate!(primitive::uint_ty_to_string(t)) |
266 | } | 327 | } |
267 | TyKind::Str => lang_item_crate!("str_alloc", "str"), | 328 | TyKind::Str => lang_item_crate!("str_alloc", "str"), |
268 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | 329 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), |
269 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), | 330 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), |
270 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | 331 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), |
271 | TyKind::Dyn(_) => { | 332 | TyKind::Dyn(_) => { |
272 | return self.dyn_trait().and_then(|trait_| { | 333 | return ty.dyn_trait().and_then(|trait_| { |
273 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 334 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
274 | }); | 335 | }); |
275 | } | 336 | } |
276 | _ => return None, | 337 | _ => return None, |
277 | }; | 338 | }; |
278 | let res = lang_item_targets | 339 | let res = lang_item_targets |
279 | .into_iter() | 340 | .into_iter() |
280 | .filter_map(|it| match it { | 341 | .filter_map(|it| match it { |
281 | LangItemTarget::ImplDefId(it) => Some(it), | 342 | LangItemTarget::ImplDefId(it) => Some(it), |
282 | _ => None, | 343 | _ => None, |
283 | }) | 344 | }) |
284 | .map(|it| it.lookup(db.upcast()).container.krate()) | 345 | .map(|it| it.lookup(db.upcast()).container.krate()) |
285 | .collect(); | 346 | .collect(); |
286 | Some(res) | 347 | Some(res) |
287 | } | ||
288 | } | 348 | } |
289 | 349 | ||
290 | /// Look up the method with the given name, returning the actual autoderefed | 350 | /// Look up the method with the given name, returning the actual autoderefed |
@@ -453,7 +513,8 @@ fn iterate_method_candidates_with_autoref( | |||
453 | } | 513 | } |
454 | let refed = Canonical { | 514 | let refed = Canonical { |
455 | binders: deref_chain[0].binders.clone(), | 515 | binders: deref_chain[0].binders.clone(), |
456 | value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), | 516 | value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone()) |
517 | .intern(&Interner), | ||
457 | }; | 518 | }; |
458 | if iterate_method_candidates_by_receiver( | 519 | if iterate_method_candidates_by_receiver( |
459 | &refed, | 520 | &refed, |
@@ -470,7 +531,8 @@ fn iterate_method_candidates_with_autoref( | |||
470 | } | 531 | } |
471 | let ref_muted = Canonical { | 532 | let ref_muted = Canonical { |
472 | binders: deref_chain[0].binders.clone(), | 533 | binders: deref_chain[0].binders.clone(), |
473 | value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), | 534 | value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone()) |
535 | .intern(&Interner), | ||
474 | }; | 536 | }; |
475 | if iterate_method_candidates_by_receiver( | 537 | if iterate_method_candidates_by_receiver( |
476 | &ref_muted, | 538 | &ref_muted, |
@@ -592,6 +654,7 @@ fn iterate_trait_method_candidates( | |||
592 | } | 654 | } |
593 | } | 655 | } |
594 | known_implemented = true; | 656 | known_implemented = true; |
657 | // FIXME: we shouldn't be ignoring the binders here | ||
595 | if callback(&self_ty.value, *item) { | 658 | if callback(&self_ty.value, *item) { |
596 | return true; | 659 | return true; |
597 | } | 660 | } |
@@ -609,7 +672,7 @@ fn iterate_inherent_methods( | |||
609 | visible_from_module: Option<ModuleId>, | 672 | visible_from_module: Option<ModuleId>, |
610 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 673 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
611 | ) -> bool { | 674 | ) -> bool { |
612 | let def_crates = match self_ty.value.def_crates(db, krate) { | 675 | let def_crates = match def_crates(db, &self_ty.value, krate) { |
613 | Some(k) => k, | 676 | Some(k) => k, |
614 | None => return false, | 677 | None => return false, |
615 | }; | 678 | }; |
@@ -709,8 +772,9 @@ pub(crate) fn inherent_impl_substs( | |||
709 | ) -> Option<Substitution> { | 772 | ) -> Option<Substitution> { |
710 | // we create a var for each type parameter of the impl; we need to keep in | 773 | // we create a var for each type parameter of the impl; we need to keep in |
711 | // mind here that `self_ty` might have vars of its own | 774 | // mind here that `self_ty` might have vars of its own |
775 | let self_ty_vars = self_ty.binders.len(&Interner); | ||
712 | let vars = TyBuilder::subst_for_def(db, impl_id) | 776 | let vars = TyBuilder::subst_for_def(db, impl_id) |
713 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) | 777 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars) |
714 | .build(); | 778 | .build(); |
715 | let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars); | 779 | let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars); |
716 | let mut kinds = self_ty.binders.interned().to_vec(); | 780 | let mut kinds = self_ty.binders.interned().to_vec(); |
@@ -725,33 +789,27 @@ pub(crate) fn inherent_impl_substs( | |||
725 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | 789 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), |
726 | value: (self_ty_with_vars, self_ty.value.clone()), | 790 | value: (self_ty_with_vars, self_ty.value.clone()), |
727 | }; | 791 | }; |
728 | let substs = super::infer::unify(&tys); | 792 | let substs = super::infer::unify(&tys)?; |
729 | // We only want the substs for the vars we added, not the ones from self_ty. | 793 | // We only want the substs for the vars we added, not the ones from self_ty. |
730 | // Also, if any of the vars we added are still in there, we replace them by | 794 | // Also, if any of the vars we added are still in there, we replace them by |
731 | // Unknown. I think this can only really happen if self_ty contained | 795 | // Unknown. I think this can only really happen if self_ty contained |
732 | // Unknown, and in that case we want the result to contain Unknown in those | 796 | // Unknown, and in that case we want the result to contain Unknown in those |
733 | // places again. | 797 | // places again. |
734 | substs | 798 | let suffix = |
735 | .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner))) | 799 | Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars)); |
800 | Some(fallback_bound_vars(suffix, self_ty_vars)) | ||
736 | } | 801 | } |
737 | 802 | ||
738 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 803 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
739 | /// num_vars_to_keep) by `TyKind::Unknown`. | 804 | /// num_vars_to_keep) by `TyKind::Unknown`. |
740 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { | 805 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { |
741 | s.fold_binders( | 806 | crate::fold_free_vars(s, |bound, binders| { |
742 | &mut |ty, binders| { | 807 | if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST { |
743 | if let TyKind::BoundVar(bound) = ty.kind(&Interner) { | 808 | TyKind::Error.intern(&Interner) |
744 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 809 | } else { |
745 | TyKind::Error.intern(&Interner) | 810 | bound.shifted_in_from(binders).to_ty(&Interner) |
746 | } else { | 811 | } |
747 | ty | 812 | }) |
748 | } | ||
749 | } else { | ||
750 | ty | ||
751 | } | ||
752 | }, | ||
753 | DebruijnIndex::INNERMOST, | ||
754 | ) | ||
755 | } | 813 | } |
756 | 814 | ||
757 | fn transform_receiver_ty( | 815 | fn transform_receiver_ty( |
@@ -826,7 +884,7 @@ fn generic_implements_goal( | |||
826 | let obligation = trait_ref.cast(&Interner); | 884 | let obligation = trait_ref.cast(&Interner); |
827 | Canonical { | 885 | Canonical { |
828 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | 886 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), |
829 | value: InEnvironment::new(env.env.clone(), obligation), | 887 | value: InEnvironment::new(&env.env, obligation), |
830 | } | 888 | } |
831 | } | 889 | } |
832 | 890 | ||
@@ -837,7 +895,9 @@ fn autoderef_method_receiver( | |||
837 | ) -> Vec<Canonical<Ty>> { | 895 | ) -> Vec<Canonical<Ty>> { |
838 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 896 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
839 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 897 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
840 | if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) { | 898 | if let Some(TyKind::Array(parameters, _)) = |
899 | deref_chain.last().map(|ty| ty.value.kind(&Interner)) | ||
900 | { | ||
841 | let kinds = deref_chain.last().unwrap().binders.clone(); | 901 | let kinds = deref_chain.last().unwrap().binders.clone(); |
842 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); | 902 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); |
843 | deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) | 903 | deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) |