diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 329 |
1 files changed, 199 insertions, 130 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index a76586f0c..48bbcfd9f 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,51 +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 | static_lifetime, | ||
22 | utils::all_super_traits, | 23 | utils::all_super_traits, |
23 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, | 24 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner, |
24 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind, | 25 | Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, |
25 | TypeWalk, | ||
26 | }; | 26 | }; |
27 | 27 | ||
28 | /// This is used as a key for indexing impls. | 28 | /// This is used as a key for indexing impls. |
29 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 29 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
30 | pub enum TyFingerprint { | 30 | pub enum TyFingerprint { |
31 | // These are lang item impls: | ||
31 | Str, | 32 | Str, |
32 | Slice, | 33 | Slice, |
33 | Array, | 34 | Array, |
34 | Never, | 35 | Never, |
35 | RawPtr(Mutability), | 36 | RawPtr(Mutability), |
36 | Scalar(Scalar), | 37 | Scalar(Scalar), |
38 | // These can have user-defined impls: | ||
37 | Adt(hir_def::AdtId), | 39 | Adt(hir_def::AdtId), |
38 | Dyn(TraitId), | 40 | Dyn(TraitId), |
39 | Tuple(usize), | ||
40 | ForeignType(ForeignDefId), | 41 | ForeignType(ForeignDefId), |
41 | FnPtr(usize, FnSig), | 42 | // These only exist for trait impls |
43 | Unit, | ||
44 | Unnameable, | ||
45 | Function(u32), | ||
42 | } | 46 | } |
43 | 47 | ||
44 | impl TyFingerprint { | 48 | impl TyFingerprint { |
45 | /// Creates a TyFingerprint for looking up an impl. Only certain types can | 49 | /// 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 | 50 | /// 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. | 51 | /// an `impl S`, but not `impl &S`. Hence, this will return `None` for |
48 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 52 | /// reference types and such. |
49 | let fp = match *ty.kind(&Interner) { | 53 | pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> { |
54 | let fp = match ty.kind(&Interner) { | ||
50 | TyKind::Str => TyFingerprint::Str, | 55 | TyKind::Str => TyFingerprint::Str, |
51 | TyKind::Never => TyFingerprint::Never, | 56 | TyKind::Never => TyFingerprint::Never, |
52 | TyKind::Slice(..) => TyFingerprint::Slice, | 57 | TyKind::Slice(..) => TyFingerprint::Slice, |
53 | TyKind::Array(..) => TyFingerprint::Array, | 58 | TyKind::Array(..) => TyFingerprint::Array, |
54 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), | 59 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), |
55 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), | 60 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), |
56 | TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | 61 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), |
57 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), | 62 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), |
58 | TyKind::ForeignType(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_))?, | 63 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, |
63 | _ => return None, | 64 | _ => return None, |
64 | }; | 65 | }; |
65 | Some(fp) | 66 | Some(fp) |
66 | } | 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 | } | ||
67 | } | 107 | } |
68 | 108 | ||
69 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 109 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
@@ -99,25 +139,38 @@ impl TraitImpls { | |||
99 | let mut impls = Self { map: FxHashMap::default() }; | 139 | let mut impls = Self { map: FxHashMap::default() }; |
100 | 140 | ||
101 | let crate_def_map = db.crate_def_map(krate); | 141 | let crate_def_map = db.crate_def_map(krate); |
102 | for (_module_id, module_data) in crate_def_map.modules() { | 142 | collect_def_map(db, &crate_def_map, &mut impls); |
103 | for impl_id in module_data.scope.impls() { | 143 | |
104 | let target_trait = match db.impl_trait(impl_id) { | 144 | return Arc::new(impls); |
105 | Some(tr) => tr.value.hir_trait_id(), | 145 | |
106 | None => continue, | 146 | fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) { |
107 | }; | 147 | for (_module_id, module_data) in def_map.modules() { |
108 | let self_ty = db.impl_self_ty(impl_id); | 148 | for impl_id in module_data.scope.impls() { |
109 | let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); | 149 | let target_trait = match db.impl_trait(impl_id) { |
110 | impls | 150 | Some(tr) => tr.skip_binders().hir_trait_id(), |
111 | .map | 151 | None => continue, |
112 | .entry(target_trait) | 152 | }; |
113 | .or_default() | 153 | let self_ty = db.impl_self_ty(impl_id); |
114 | .entry(self_ty_fp) | 154 | let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders()); |
115 | .or_default() | 155 | impls |
116 | .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 | } | ||
117 | } | 172 | } |
118 | } | 173 | } |
119 | |||
120 | Arc::new(impls) | ||
121 | } | 174 | } |
122 | 175 | ||
123 | 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> { |
@@ -143,10 +196,13 @@ impl TraitImpls { | |||
143 | } | 196 | } |
144 | 197 | ||
145 | /// Queries all trait impls for the given type. | 198 | /// Queries all trait impls for the given type. |
146 | 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> + '_ { | ||
147 | self.map | 203 | self.map |
148 | .values() | 204 | .values() |
149 | .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()) |
150 | .flat_map(|it| it.iter().copied()) | 206 | .flat_map(|it| it.iter().copied()) |
151 | } | 207 | } |
152 | 208 | ||
@@ -190,28 +246,43 @@ pub struct InherentImpls { | |||
190 | 246 | ||
191 | impl InherentImpls { | 247 | impl InherentImpls { |
192 | pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { | 248 | pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { |
193 | let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default(); | 249 | let mut impls = Self { map: FxHashMap::default() }; |
194 | 250 | ||
195 | let crate_def_map = db.crate_def_map(krate); | 251 | let crate_def_map = db.crate_def_map(krate); |
196 | for (_module_id, module_data) in crate_def_map.modules() { | 252 | collect_def_map(db, &crate_def_map, &mut impls); |
197 | for impl_id in module_data.scope.impls() { | 253 | |
198 | let data = db.impl_data(impl_id); | 254 | return Arc::new(impls); |
199 | if data.target_trait.is_some() { | 255 | |
200 | continue; | 256 | fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut InherentImpls) { |
257 | for (_module_id, module_data) in def_map.modules() { | ||
258 | for impl_id in module_data.scope.impls() { | ||
259 | let data = db.impl_data(impl_id); | ||
260 | if data.target_trait.is_some() { | ||
261 | continue; | ||
262 | } | ||
263 | |||
264 | let self_ty = db.impl_self_ty(impl_id); | ||
265 | let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders()); | ||
266 | if let Some(fp) = fp { | ||
267 | impls.map.entry(fp).or_default().push(impl_id); | ||
268 | } | ||
269 | // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution) | ||
201 | } | 270 | } |
202 | 271 | ||
203 | let self_ty = db.impl_self_ty(impl_id); | 272 | // To better support custom derives, collect impls in all unnamed const items. |
204 | if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { | 273 | // const _: () = { ... }; |
205 | map.entry(fp).or_default().push(impl_id); | 274 | for konst in module_data.scope.unnamed_consts() { |
275 | let body = db.body(konst.into()); | ||
276 | for (_, block_def_map) in body.blocks(db.upcast()) { | ||
277 | collect_def_map(db, &block_def_map, impls); | ||
278 | } | ||
206 | } | 279 | } |
207 | } | 280 | } |
208 | } | 281 | } |
209 | |||
210 | Arc::new(Self { map }) | ||
211 | } | 282 | } |
212 | 283 | ||
213 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { | 284 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { |
214 | match TyFingerprint::for_impl(self_ty) { | 285 | match TyFingerprint::for_inherent_impl(self_ty) { |
215 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), | 286 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), |
216 | None => &[], | 287 | None => &[], |
217 | } | 288 | } |
@@ -222,15 +293,14 @@ impl InherentImpls { | |||
222 | } | 293 | } |
223 | } | 294 | } |
224 | 295 | ||
225 | impl Ty { | 296 | pub fn def_crates( |
226 | pub fn def_crates( | 297 | db: &dyn HirDatabase, |
227 | &self, | 298 | ty: &Ty, |
228 | db: &dyn HirDatabase, | 299 | cur_crate: CrateId, |
229 | cur_crate: CrateId, | 300 | ) -> Option<ArrayVec<CrateId, 2>> { |
230 | ) -> Option<ArrayVec<CrateId, 2>> { | 301 | // 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). | 302 | // 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. | 303 | macro_rules! lang_item_crate { |
233 | macro_rules! lang_item_crate { | ||
234 | ($($name:expr),+ $(,)?) => {{ | 304 | ($($name:expr),+ $(,)?) => {{ |
235 | let mut v = ArrayVec::<LangItemTarget, 2>::new(); | 305 | let mut v = ArrayVec::<LangItemTarget, 2>::new(); |
236 | $( | 306 | $( |
@@ -240,51 +310,50 @@ impl Ty { | |||
240 | }}; | 310 | }}; |
241 | } | 311 | } |
242 | 312 | ||
243 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 313 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
244 | 314 | ||
245 | let lang_item_targets = match self.kind(&Interner) { | 315 | let lang_item_targets = match ty.kind(&Interner) { |
246 | TyKind::Adt(AdtId(def_id), _) => { | 316 | TyKind::Adt(AdtId(def_id), _) => { |
247 | return mod_to_crate_ids(def_id.module(db.upcast())); | 317 | return mod_to_crate_ids(def_id.module(db.upcast())); |
248 | } | 318 | } |
249 | TyKind::ForeignType(id) => { | 319 | TyKind::Foreign(id) => { |
250 | return mod_to_crate_ids( | 320 | return mod_to_crate_ids( |
251 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), | 321 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), |
252 | ); | 322 | ); |
253 | } | 323 | } |
254 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 324 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
255 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), | 325 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), |
256 | TyKind::Scalar(Scalar::Float(f)) => match f { | 326 | TyKind::Scalar(Scalar::Float(f)) => match f { |
257 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 327 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
258 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 328 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
259 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | 329 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
260 | }, | 330 | }, |
261 | &TyKind::Scalar(Scalar::Int(t)) => { | 331 | &TyKind::Scalar(Scalar::Int(t)) => { |
262 | lang_item_crate!(primitive::int_ty_to_string(t)) | 332 | lang_item_crate!(primitive::int_ty_to_string(t)) |
263 | } | 333 | } |
264 | &TyKind::Scalar(Scalar::Uint(t)) => { | 334 | &TyKind::Scalar(Scalar::Uint(t)) => { |
265 | lang_item_crate!(primitive::uint_ty_to_string(t)) | 335 | lang_item_crate!(primitive::uint_ty_to_string(t)) |
266 | } | 336 | } |
267 | TyKind::Str => lang_item_crate!("str_alloc", "str"), | 337 | TyKind::Str => lang_item_crate!("str_alloc", "str"), |
268 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | 338 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), |
269 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), | 339 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), |
270 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | 340 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), |
271 | TyKind::Dyn(_) => { | 341 | TyKind::Dyn(_) => { |
272 | return self.dyn_trait().and_then(|trait_| { | 342 | return ty.dyn_trait().and_then(|trait_| { |
273 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 343 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
274 | }); | 344 | }); |
275 | } | 345 | } |
276 | _ => return None, | 346 | _ => return None, |
277 | }; | 347 | }; |
278 | let res = lang_item_targets | 348 | let res = lang_item_targets |
279 | .into_iter() | 349 | .into_iter() |
280 | .filter_map(|it| match it { | 350 | .filter_map(|it| match it { |
281 | LangItemTarget::ImplDefId(it) => Some(it), | 351 | LangItemTarget::ImplDefId(it) => Some(it), |
282 | _ => None, | 352 | _ => None, |
283 | }) | 353 | }) |
284 | .map(|it| it.lookup(db.upcast()).container.krate()) | 354 | .map(|it| it.lookup(db.upcast()).container.krate()) |
285 | .collect(); | 355 | .collect(); |
286 | Some(res) | 356 | Some(res) |
287 | } | ||
288 | } | 357 | } |
289 | 358 | ||
290 | /// Look up the method with the given name, returning the actual autoderefed | 359 | /// Look up the method with the given name, returning the actual autoderefed |
@@ -453,7 +522,8 @@ fn iterate_method_candidates_with_autoref( | |||
453 | } | 522 | } |
454 | let refed = Canonical { | 523 | let refed = Canonical { |
455 | binders: deref_chain[0].binders.clone(), | 524 | binders: deref_chain[0].binders.clone(), |
456 | value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), | 525 | value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone()) |
526 | .intern(&Interner), | ||
457 | }; | 527 | }; |
458 | if iterate_method_candidates_by_receiver( | 528 | if iterate_method_candidates_by_receiver( |
459 | &refed, | 529 | &refed, |
@@ -470,7 +540,8 @@ fn iterate_method_candidates_with_autoref( | |||
470 | } | 540 | } |
471 | let ref_muted = Canonical { | 541 | let ref_muted = Canonical { |
472 | binders: deref_chain[0].binders.clone(), | 542 | binders: deref_chain[0].binders.clone(), |
473 | value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), | 543 | value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone()) |
544 | .intern(&Interner), | ||
474 | }; | 545 | }; |
475 | if iterate_method_candidates_by_receiver( | 546 | if iterate_method_candidates_by_receiver( |
476 | &ref_muted, | 547 | &ref_muted, |
@@ -592,6 +663,7 @@ fn iterate_trait_method_candidates( | |||
592 | } | 663 | } |
593 | } | 664 | } |
594 | known_implemented = true; | 665 | known_implemented = true; |
666 | // FIXME: we shouldn't be ignoring the binders here | ||
595 | if callback(&self_ty.value, *item) { | 667 | if callback(&self_ty.value, *item) { |
596 | return true; | 668 | return true; |
597 | } | 669 | } |
@@ -609,7 +681,7 @@ fn iterate_inherent_methods( | |||
609 | visible_from_module: Option<ModuleId>, | 681 | visible_from_module: Option<ModuleId>, |
610 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 682 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
611 | ) -> bool { | 683 | ) -> bool { |
612 | let def_crates = match self_ty.value.def_crates(db, krate) { | 684 | let def_crates = match def_crates(db, &self_ty.value, krate) { |
613 | Some(k) => k, | 685 | Some(k) => k, |
614 | None => return false, | 686 | None => return false, |
615 | }; | 687 | }; |
@@ -709,10 +781,11 @@ pub(crate) fn inherent_impl_substs( | |||
709 | ) -> Option<Substitution> { | 781 | ) -> Option<Substitution> { |
710 | // we create a var for each type parameter of the impl; we need to keep in | 782 | // 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 | 783 | // mind here that `self_ty` might have vars of its own |
784 | let self_ty_vars = self_ty.binders.len(&Interner); | ||
712 | let vars = TyBuilder::subst_for_def(db, impl_id) | 785 | let vars = TyBuilder::subst_for_def(db, impl_id) |
713 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) | 786 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars) |
714 | .build(); | 787 | .build(); |
715 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 788 | let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars); |
716 | let mut kinds = self_ty.binders.interned().to_vec(); | 789 | let mut kinds = self_ty.binders.interned().to_vec(); |
717 | kinds.extend( | 790 | kinds.extend( |
718 | iter::repeat(chalk_ir::WithKind::new( | 791 | iter::repeat(chalk_ir::WithKind::new( |
@@ -725,33 +798,27 @@ pub(crate) fn inherent_impl_substs( | |||
725 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | 798 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), |
726 | value: (self_ty_with_vars, self_ty.value.clone()), | 799 | value: (self_ty_with_vars, self_ty.value.clone()), |
727 | }; | 800 | }; |
728 | let substs = super::infer::unify(&tys); | 801 | let substs = super::infer::unify(&tys)?; |
729 | // We only want the substs for the vars we added, not the ones from self_ty. | 802 | // 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 | 803 | // 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 | 804 | // 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 | 805 | // Unknown, and in that case we want the result to contain Unknown in those |
733 | // places again. | 806 | // places again. |
734 | substs | 807 | let suffix = |
735 | .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner))) | 808 | Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars)); |
809 | Some(fallback_bound_vars(suffix, self_ty_vars)) | ||
736 | } | 810 | } |
737 | 811 | ||
738 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 812 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
739 | /// num_vars_to_keep) by `TyKind::Unknown`. | 813 | /// num_vars_to_keep) by `TyKind::Unknown`. |
740 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { | 814 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { |
741 | s.fold_binders( | 815 | crate::fold_free_vars(s, |bound, binders| { |
742 | &mut |ty, binders| { | 816 | if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST { |
743 | if let TyKind::BoundVar(bound) = ty.kind(&Interner) { | 817 | TyKind::Error.intern(&Interner) |
744 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 818 | } else { |
745 | TyKind::Unknown.intern(&Interner) | 819 | bound.shifted_in_from(binders).to_ty(&Interner) |
746 | } else { | 820 | } |
747 | ty | 821 | }) |
748 | } | ||
749 | } else { | ||
750 | ty | ||
751 | } | ||
752 | }, | ||
753 | DebruijnIndex::INNERMOST, | ||
754 | ) | ||
755 | } | 822 | } |
756 | 823 | ||
757 | fn transform_receiver_ty( | 824 | fn transform_receiver_ty( |
@@ -774,7 +841,7 @@ fn transform_receiver_ty( | |||
774 | AssocContainerId::ModuleId(_) => unreachable!(), | 841 | AssocContainerId::ModuleId(_) => unreachable!(), |
775 | }; | 842 | }; |
776 | let sig = db.callable_item_signature(function_id.into()); | 843 | let sig = db.callable_item_signature(function_id.into()); |
777 | Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) | 844 | Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs)) |
778 | } | 845 | } |
779 | 846 | ||
780 | pub fn implements_trait( | 847 | pub fn implements_trait( |
@@ -800,7 +867,7 @@ pub fn implements_trait_unique( | |||
800 | let goal = generic_implements_goal(db, env, trait_, ty.clone()); | 867 | let goal = generic_implements_goal(db, env, trait_, ty.clone()); |
801 | let solution = db.trait_solve(krate, goal); | 868 | let solution = db.trait_solve(krate, goal); |
802 | 869 | ||
803 | matches!(solution, Some(crate::traits::Solution::Unique(_))) | 870 | matches!(solution, Some(crate::Solution::Unique(_))) |
804 | } | 871 | } |
805 | 872 | ||
806 | /// This creates Substs for a trait with the given Self type and type variables | 873 | /// This creates Substs for a trait with the given Self type and type variables |
@@ -826,7 +893,7 @@ fn generic_implements_goal( | |||
826 | let obligation = trait_ref.cast(&Interner); | 893 | let obligation = trait_ref.cast(&Interner); |
827 | Canonical { | 894 | Canonical { |
828 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | 895 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), |
829 | value: InEnvironment::new(env.env.clone(), obligation), | 896 | value: InEnvironment::new(&env.env, obligation), |
830 | } | 897 | } |
831 | } | 898 | } |
832 | 899 | ||
@@ -837,7 +904,9 @@ fn autoderef_method_receiver( | |||
837 | ) -> Vec<Canonical<Ty>> { | 904 | ) -> Vec<Canonical<Ty>> { |
838 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 905 | 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!) | 906 | // 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)) { | 907 | if let Some(TyKind::Array(parameters, _)) = |
908 | deref_chain.last().map(|ty| ty.value.kind(&Interner)) | ||
909 | { | ||
841 | let kinds = deref_chain.last().unwrap().binders.clone(); | 910 | let kinds = deref_chain.last().unwrap().binders.clone(); |
842 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); | 911 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); |
843 | deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) | 912 | deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) |