diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 316 |
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; | |||
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,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)] |
31 | pub enum TyFingerprint { | 30 | pub 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 | ||
45 | impl TyFingerprint { | 48 | impl 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 | ||
70 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 109 | pub(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 | ||
226 | impl Ty { | 286 | pub 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`. |
740 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { | 804 | fn 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 | ||
757 | fn transform_receiver_ty( | 814 | fn 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 | ||
780 | pub fn implements_trait( | 837 | pub 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); |