]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/method_resolution.rs
Add const generics
[rust.git] / crates / hir_ty / src / method_resolution.rs
1 //! This module is concerned with finding methods that a given type provides.
2 //! For details about how this works in rustc, see the method lookup page in the
3 //! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
4 //! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
5 use std::{iter, ops::ControlFlow, sync::Arc};
6
7 use arrayvec::ArrayVec;
8 use base_db::{CrateId, Edition};
9 use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, Mutability, UniverseIndex};
10 use hir_def::{
11     item_scope::ItemScope, lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId,
12     ConstId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId,
13     ModuleId, TraitId,
14 };
15 use hir_expand::name::Name;
16 use rustc_hash::{FxHashMap, FxHashSet};
17 use stdx::never;
18
19 use crate::{
20     autoderef::{self, AutoderefKind},
21     consteval::{self, ConstExt},
22     db::HirDatabase,
23     from_foreign_def_id,
24     infer::{unify::InferenceTable, Adjust, Adjustment, AutoBorrow, OverloadedDeref, PointerCast},
25     primitive::{self, FloatTy, IntTy, UintTy},
26     static_lifetime,
27     utils::all_super_traits,
28     AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, GenericArgData,
29     InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder,
30     TyExt, TyKind,
31 };
32
33 /// This is used as a key for indexing impls.
34 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
35 pub enum TyFingerprint {
36     // These are lang item impls:
37     Str,
38     Slice,
39     Array,
40     Never,
41     RawPtr(Mutability),
42     Scalar(Scalar),
43     // These can have user-defined impls:
44     Adt(hir_def::AdtId),
45     Dyn(TraitId),
46     ForeignType(ForeignDefId),
47     // These only exist for trait impls
48     Unit,
49     Unnameable,
50     Function(u32),
51 }
52
53 impl TyFingerprint {
54     /// Creates a TyFingerprint for looking up an inherent impl. Only certain
55     /// types can have inherent impls: if we have some `struct S`, we can have
56     /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
57     /// reference types and such.
58     pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
59         let fp = match ty.kind(Interner) {
60             TyKind::Str => TyFingerprint::Str,
61             TyKind::Never => TyFingerprint::Never,
62             TyKind::Slice(..) => TyFingerprint::Slice,
63             TyKind::Array(..) => TyFingerprint::Array,
64             TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
65             TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
66             TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
67             TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
68             TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
69             _ => return None,
70         };
71         Some(fp)
72     }
73
74     /// Creates a TyFingerprint for looking up a trait impl.
75     pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> {
76         let fp = match ty.kind(Interner) {
77             TyKind::Str => TyFingerprint::Str,
78             TyKind::Never => TyFingerprint::Never,
79             TyKind::Slice(..) => TyFingerprint::Slice,
80             TyKind::Array(..) => TyFingerprint::Array,
81             TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
82             TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
83             TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
84             TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
85             TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
86             TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty),
87             TyKind::Tuple(_, subst) => {
88                 let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(Interner));
89                 match first_ty {
90                     Some(ty) => return TyFingerprint::for_trait_impl(ty),
91                     None => TyFingerprint::Unit,
92                 }
93             }
94             TyKind::AssociatedType(_, _)
95             | TyKind::OpaqueType(_, _)
96             | TyKind::FnDef(_, _)
97             | TyKind::Closure(_, _)
98             | TyKind::Generator(..)
99             | TyKind::GeneratorWitness(..) => TyFingerprint::Unnameable,
100             TyKind::Function(fn_ptr) => {
101                 TyFingerprint::Function(fn_ptr.substitution.0.len(Interner) as u32)
102             }
103             TyKind::Alias(_)
104             | TyKind::Placeholder(_)
105             | TyKind::BoundVar(_)
106             | TyKind::InferenceVar(_, _)
107             | TyKind::Error => return None,
108         };
109         Some(fp)
110     }
111 }
112
113 pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
114     TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
115     TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
116     TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
117     TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
118     TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
119     TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
120     TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
121     TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
122     TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
123     TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
124     TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
125     TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
126 ];
127
128 pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
129     TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
130     TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
131 ];
132
133 /// Trait impls defined or available in some crate.
134 #[derive(Debug, Eq, PartialEq)]
135 pub struct TraitImpls {
136     // If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type.
137     map: FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>,
138 }
139
140 impl TraitImpls {
141     pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
142         let _p = profile::span("trait_impls_in_crate_query");
143         let mut impls = Self { map: FxHashMap::default() };
144
145         let crate_def_map = db.crate_def_map(krate);
146         impls.collect_def_map(db, &crate_def_map);
147         impls.shrink_to_fit();
148
149         Arc::new(impls)
150     }
151
152     pub(crate) fn trait_impls_in_block_query(
153         db: &dyn HirDatabase,
154         block: BlockId,
155     ) -> Option<Arc<Self>> {
156         let _p = profile::span("trait_impls_in_block_query");
157         let mut impls = Self { map: FxHashMap::default() };
158
159         let block_def_map = db.block_def_map(block)?;
160         impls.collect_def_map(db, &block_def_map);
161         impls.shrink_to_fit();
162
163         Some(Arc::new(impls))
164     }
165
166     pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
167         let _p = profile::span("trait_impls_in_deps_query");
168         let crate_graph = db.crate_graph();
169         let mut res = Self { map: FxHashMap::default() };
170
171         for krate in crate_graph.transitive_deps(krate) {
172             res.merge(&db.trait_impls_in_crate(krate));
173         }
174         res.shrink_to_fit();
175
176         Arc::new(res)
177     }
178
179     fn shrink_to_fit(&mut self) {
180         self.map.shrink_to_fit();
181         self.map.values_mut().for_each(|map| {
182             map.shrink_to_fit();
183             map.values_mut().for_each(Vec::shrink_to_fit);
184         });
185     }
186
187     fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
188         for (_module_id, module_data) in def_map.modules() {
189             for impl_id in module_data.scope.impls() {
190                 let target_trait = match db.impl_trait(impl_id) {
191                     Some(tr) => tr.skip_binders().hir_trait_id(),
192                     None => continue,
193                 };
194                 let self_ty = db.impl_self_ty(impl_id);
195                 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
196                 self.map
197                     .entry(target_trait)
198                     .or_default()
199                     .entry(self_ty_fp)
200                     .or_default()
201                     .push(impl_id);
202             }
203
204             // To better support custom derives, collect impls in all unnamed const items.
205             // const _: () = { ... };
206             for konst in collect_unnamed_consts(db, &module_data.scope) {
207                 let body = db.body(konst.into());
208                 for (_, block_def_map) in body.blocks(db.upcast()) {
209                     self.collect_def_map(db, &block_def_map);
210                 }
211             }
212         }
213     }
214
215     fn merge(&mut self, other: &Self) {
216         for (trait_, other_map) in &other.map {
217             let map = self.map.entry(*trait_).or_default();
218             for (fp, impls) in other_map {
219                 let vec = map.entry(*fp).or_default();
220                 vec.extend(impls);
221             }
222         }
223     }
224
225     /// Queries all trait impls for the given type.
226     pub fn for_self_ty_without_blanket_impls(
227         &self,
228         fp: TyFingerprint,
229     ) -> impl Iterator<Item = ImplId> + '_ {
230         self.map
231             .values()
232             .flat_map(move |impls| impls.get(&Some(fp)).into_iter())
233             .flat_map(|it| it.iter().copied())
234     }
235
236     /// Queries all impls of the given trait.
237     pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ {
238         self.map
239             .get(&trait_)
240             .into_iter()
241             .flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
242     }
243
244     /// Queries all impls of `trait_` that may apply to `self_ty`.
245     pub fn for_trait_and_self_ty(
246         &self,
247         trait_: TraitId,
248         self_ty: TyFingerprint,
249     ) -> impl Iterator<Item = ImplId> + '_ {
250         self.map
251             .get(&trait_)
252             .into_iter()
253             .flat_map(move |map| map.get(&None).into_iter().chain(map.get(&Some(self_ty))))
254             .flat_map(|v| v.iter().copied())
255     }
256
257     pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
258         self.map.values().flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
259     }
260 }
261
262 /// Inherent impls defined in some crate.
263 ///
264 /// Inherent impls can only be defined in the crate that also defines the self type of the impl
265 /// (note that some primitives are considered to be defined by both libcore and liballoc).
266 ///
267 /// This makes inherent impl lookup easier than trait impl lookup since we only have to consider a
268 /// single crate.
269 #[derive(Debug, Eq, PartialEq)]
270 pub struct InherentImpls {
271     map: FxHashMap<TyFingerprint, Vec<ImplId>>,
272 }
273
274 impl InherentImpls {
275     pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
276         let mut impls = Self { map: FxHashMap::default() };
277
278         let crate_def_map = db.crate_def_map(krate);
279         impls.collect_def_map(db, &crate_def_map);
280         impls.shrink_to_fit();
281
282         Arc::new(impls)
283     }
284
285     pub(crate) fn inherent_impls_in_block_query(
286         db: &dyn HirDatabase,
287         block: BlockId,
288     ) -> Option<Arc<Self>> {
289         let mut impls = Self { map: FxHashMap::default() };
290         if let Some(block_def_map) = db.block_def_map(block) {
291             impls.collect_def_map(db, &block_def_map);
292             impls.shrink_to_fit();
293             return Some(Arc::new(impls));
294         }
295         None
296     }
297
298     fn shrink_to_fit(&mut self) {
299         self.map.values_mut().for_each(Vec::shrink_to_fit);
300         self.map.shrink_to_fit();
301     }
302
303     fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
304         for (_module_id, module_data) in def_map.modules() {
305             for impl_id in module_data.scope.impls() {
306                 let data = db.impl_data(impl_id);
307                 if data.target_trait.is_some() {
308                     continue;
309                 }
310
311                 let self_ty = db.impl_self_ty(impl_id);
312                 let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders());
313                 if let Some(fp) = fp {
314                     self.map.entry(fp).or_default().push(impl_id);
315                 }
316                 // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
317             }
318
319             // To better support custom derives, collect impls in all unnamed const items.
320             // const _: () = { ... };
321             for konst in collect_unnamed_consts(db, &module_data.scope) {
322                 let body = db.body(konst.into());
323                 for (_, block_def_map) in body.blocks(db.upcast()) {
324                     self.collect_def_map(db, &block_def_map);
325                 }
326             }
327         }
328     }
329
330     pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
331         match TyFingerprint::for_inherent_impl(self_ty) {
332             Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
333             None => &[],
334         }
335     }
336
337     pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
338         self.map.values().flat_map(|v| v.iter().copied())
339     }
340 }
341
342 fn collect_unnamed_consts<'a>(
343     db: &'a dyn HirDatabase,
344     scope: &'a ItemScope,
345 ) -> impl Iterator<Item = ConstId> + 'a {
346     let unnamed_consts = scope.unnamed_consts();
347
348     // FIXME: Also treat consts named `_DERIVE_*` as unnamed, since synstructure generates those.
349     // Should be removed once synstructure stops doing that.
350     let synstructure_hack_consts = scope.values().filter_map(|(item, _)| match item {
351         ModuleDefId::ConstId(id) => {
352             let loc = id.lookup(db.upcast());
353             let item_tree = loc.id.item_tree(db.upcast());
354             if item_tree[loc.id.value]
355                 .name
356                 .as_ref()
357                 .map_or(false, |n| n.to_smol_str().starts_with("_DERIVE_"))
358             {
359                 Some(id)
360             } else {
361                 None
362             }
363         }
364         _ => None,
365     });
366
367     unnamed_consts.chain(synstructure_hack_consts)
368 }
369
370 pub fn def_crates(
371     db: &dyn HirDatabase,
372     ty: &Ty,
373     cur_crate: CrateId,
374 ) -> Option<ArrayVec<CrateId, 2>> {
375     // Types like slice can have inherent impls in several crates, (core and alloc).
376     // The corresponding impls are marked with lang items, so we can use them to find the required crates.
377     macro_rules! lang_item_crate {
378             ($($name:expr),+ $(,)?) => {{
379                 let mut v = ArrayVec::<LangItemTarget, 2>::new();
380                 $(
381                     v.extend(db.lang_item(cur_crate, $name.into()));
382                 )+
383                 v
384             }};
385         }
386
387     let mod_to_crate_ids = |module: ModuleId| Some(iter::once(module.krate()).collect());
388
389     let lang_item_targets = match ty.kind(Interner) {
390         TyKind::Adt(AdtId(def_id), _) => {
391             return mod_to_crate_ids(def_id.module(db.upcast()));
392         }
393         TyKind::Foreign(id) => {
394             return mod_to_crate_ids(
395                 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
396             );
397         }
398         TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
399         TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
400         TyKind::Scalar(Scalar::Float(f)) => match f {
401             // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
402             FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
403             FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
404         },
405         &TyKind::Scalar(Scalar::Int(t)) => {
406             lang_item_crate!(primitive::int_ty_to_string(t))
407         }
408         &TyKind::Scalar(Scalar::Uint(t)) => {
409             lang_item_crate!(primitive::uint_ty_to_string(t))
410         }
411         TyKind::Str => lang_item_crate!("str_alloc", "str"),
412         TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
413         TyKind::Array(..) => lang_item_crate!("array"),
414         TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
415         TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
416         TyKind::Dyn(_) => {
417             return ty.dyn_trait().and_then(|trait_| {
418                 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
419             });
420         }
421         _ => return None,
422     };
423     let res = lang_item_targets
424         .into_iter()
425         .filter_map(|it| match it {
426             LangItemTarget::ImplDefId(it) => Some(it),
427             _ => None,
428         })
429         .map(|it| it.lookup(db.upcast()).container.krate())
430         .collect();
431     Some(res)
432 }
433
434 /// Look up the method with the given name.
435 pub(crate) fn lookup_method(
436     ty: &Canonical<Ty>,
437     db: &dyn HirDatabase,
438     env: Arc<TraitEnvironment>,
439     traits_in_scope: &FxHashSet<TraitId>,
440     visible_from_module: VisibleFromModule,
441     name: &Name,
442 ) -> Option<(ReceiverAdjustments, FunctionId)> {
443     iterate_method_candidates(
444         ty,
445         db,
446         env,
447         traits_in_scope,
448         visible_from_module,
449         Some(name),
450         LookupMode::MethodCall,
451         |adjustments, f| match f {
452             AssocItemId::FunctionId(f) => Some((adjustments, f)),
453             _ => None,
454         },
455     )
456 }
457
458 /// Whether we're looking up a dotted method call (like `v.len()`) or a path
459 /// (like `Vec::new`).
460 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
461 pub enum LookupMode {
462     /// Looking up a method call like `v.len()`: We only consider candidates
463     /// that have a `self` parameter, and do autoderef.
464     MethodCall,
465     /// Looking up a path like `Vec::new` or `Vec::default`: We consider all
466     /// candidates including associated constants, but don't do autoderef.
467     Path,
468 }
469
470 #[derive(Clone, Copy)]
471 pub enum VisibleFromModule {
472     /// Filter for results that are visible from the given module
473     Filter(ModuleId),
474     /// Include impls from the given block.
475     IncludeBlock(BlockId),
476     /// Do nothing special in regards visibility
477     None,
478 }
479
480 impl From<Option<ModuleId>> for VisibleFromModule {
481     fn from(module: Option<ModuleId>) -> Self {
482         match module {
483             Some(module) => Self::Filter(module),
484             None => Self::None,
485         }
486     }
487 }
488
489 impl From<Option<BlockId>> for VisibleFromModule {
490     fn from(block: Option<BlockId>) -> Self {
491         match block {
492             Some(block) => Self::IncludeBlock(block),
493             None => Self::None,
494         }
495     }
496 }
497
498 #[derive(Debug, Clone, Default)]
499 pub struct ReceiverAdjustments {
500     autoref: Option<Mutability>,
501     autoderefs: usize,
502     unsize_array: bool,
503 }
504
505 impl ReceiverAdjustments {
506     pub(crate) fn apply(&self, table: &mut InferenceTable, ty: Ty) -> (Ty, Vec<Adjustment>) {
507         let mut ty = ty;
508         let mut adjust = Vec::new();
509         for _ in 0..self.autoderefs {
510             match autoderef::autoderef_step(table, ty.clone()) {
511                 None => {
512                     never!("autoderef not possible for {:?}", ty);
513                     ty = TyKind::Error.intern(Interner);
514                     break;
515                 }
516                 Some((kind, new_ty)) => {
517                     ty = new_ty.clone();
518                     adjust.push(Adjustment {
519                         kind: Adjust::Deref(match kind {
520                             // FIXME should we know the mutability here?
521                             AutoderefKind::Overloaded => Some(OverloadedDeref(Mutability::Not)),
522                             AutoderefKind::Builtin => None,
523                         }),
524                         target: new_ty,
525                     });
526                 }
527             }
528         }
529         if self.unsize_array {
530             ty = match ty.kind(Interner) {
531                 TyKind::Array(inner, _) => TyKind::Slice(inner.clone()).intern(Interner),
532                 _ => {
533                     never!("unsize_array with non-array {:?}", ty);
534                     ty
535                 }
536             };
537             // FIXME this is kind of wrong since the unsize needs to happen to a pointer/reference
538             adjust.push(Adjustment {
539                 kind: Adjust::Pointer(PointerCast::Unsize),
540                 target: ty.clone(),
541             });
542         }
543         if let Some(m) = self.autoref {
544             ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
545             adjust
546                 .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty.clone() });
547         }
548         (ty, adjust)
549     }
550
551     fn with_autoref(&self, m: Mutability) -> ReceiverAdjustments {
552         Self { autoref: Some(m), ..*self }
553     }
554 }
555
556 // This would be nicer if it just returned an iterator, but that runs into
557 // lifetime problems, because we need to borrow temp `CrateImplDefs`.
558 // FIXME add a context type here?
559 pub(crate) fn iterate_method_candidates<T>(
560     ty: &Canonical<Ty>,
561     db: &dyn HirDatabase,
562     env: Arc<TraitEnvironment>,
563     traits_in_scope: &FxHashSet<TraitId>,
564     visible_from_module: VisibleFromModule,
565     name: Option<&Name>,
566     mode: LookupMode,
567     mut callback: impl FnMut(ReceiverAdjustments, AssocItemId) -> Option<T>,
568 ) -> Option<T> {
569     let mut slot = None;
570     iterate_method_candidates_dyn(
571         ty,
572         db,
573         env,
574         traits_in_scope,
575         visible_from_module,
576         name,
577         mode,
578         &mut |adj, item| {
579             assert!(slot.is_none());
580             if let Some(it) = callback(adj, item) {
581                 slot = Some(it);
582                 return ControlFlow::Break(());
583             }
584             ControlFlow::Continue(())
585         },
586     );
587     slot
588 }
589
590 pub fn iterate_path_candidates(
591     ty: &Canonical<Ty>,
592     db: &dyn HirDatabase,
593     env: Arc<TraitEnvironment>,
594     traits_in_scope: &FxHashSet<TraitId>,
595     visible_from_module: VisibleFromModule,
596     name: Option<&Name>,
597     callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>,
598 ) -> ControlFlow<()> {
599     iterate_method_candidates_dyn(
600         ty,
601         db,
602         env,
603         traits_in_scope,
604         visible_from_module,
605         name,
606         LookupMode::Path,
607         // the adjustments are not relevant for path lookup
608         &mut |_, id| callback(id),
609     )
610 }
611
612 pub fn iterate_method_candidates_dyn(
613     ty: &Canonical<Ty>,
614     db: &dyn HirDatabase,
615     env: Arc<TraitEnvironment>,
616     traits_in_scope: &FxHashSet<TraitId>,
617     visible_from_module: VisibleFromModule,
618     name: Option<&Name>,
619     mode: LookupMode,
620     callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
621 ) -> ControlFlow<()> {
622     match mode {
623         LookupMode::MethodCall => {
624             // For method calls, rust first does any number of autoderef, and
625             // then one autoref (i.e. when the method takes &self or &mut self).
626             // Note that when we've got a receiver like &S, even if the method
627             // we find in the end takes &self, we still do the autoderef step
628             // (just as rustc does an autoderef and then autoref again).
629
630             // We have to be careful about the order we're looking at candidates
631             // in here. Consider the case where we're resolving `x.clone()`
632             // where `x: &Vec<_>`. This resolves to the clone method with self
633             // type `Vec<_>`, *not* `&_`. I.e. we need to consider methods where
634             // the receiver type exactly matches before cases where we have to
635             // do autoref. But in the autoderef steps, the `&_` self type comes
636             // up *before* the `Vec<_>` self type.
637             //
638             // On the other hand, we don't want to just pick any by-value method
639             // before any by-autoref method; it's just that we need to consider
640             // the methods by autoderef order of *receiver types*, not *self
641             // types*.
642
643             let mut table = InferenceTable::new(db, env.clone());
644             let ty = table.instantiate_canonical(ty.clone());
645             let (deref_chain, adj) = autoderef_method_receiver(&mut table, ty);
646             let deref_chains = stdx::slice_tails(&deref_chain);
647
648             let result = deref_chains.zip(adj).try_for_each(|(deref_chain, adj)| {
649                 iterate_method_candidates_with_autoref(
650                     deref_chain,
651                     adj,
652                     db,
653                     env.clone(),
654                     traits_in_scope,
655                     visible_from_module,
656                     name,
657                     callback,
658                 )
659             });
660             result
661         }
662         LookupMode::Path => {
663             // No autoderef for path lookups
664             iterate_method_candidates_for_self_ty(
665                 ty,
666                 db,
667                 env,
668                 traits_in_scope,
669                 visible_from_module,
670                 name,
671                 callback,
672             )
673         }
674     }
675 }
676
677 fn iterate_method_candidates_with_autoref(
678     deref_chain: &[Canonical<Ty>],
679     first_adjustment: ReceiverAdjustments,
680     db: &dyn HirDatabase,
681     env: Arc<TraitEnvironment>,
682     traits_in_scope: &FxHashSet<TraitId>,
683     visible_from_module: VisibleFromModule,
684     name: Option<&Name>,
685     mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
686 ) -> ControlFlow<()> {
687     let (receiver_ty, rest) = match deref_chain.split_first() {
688         Some((rec, rest)) => (rec, rest),
689         None => {
690             never!("received empty deref-chain");
691             return ControlFlow::Break(());
692         }
693     };
694     iterate_method_candidates_by_receiver(
695         receiver_ty,
696         first_adjustment.clone(),
697         rest,
698         db,
699         env.clone(),
700         traits_in_scope,
701         visible_from_module,
702         name,
703         &mut callback,
704     )?;
705
706     let refed = Canonical {
707         value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone())
708             .intern(Interner),
709         binders: receiver_ty.binders.clone(),
710     };
711
712     iterate_method_candidates_by_receiver(
713         &refed,
714         first_adjustment.with_autoref(Mutability::Not),
715         deref_chain,
716         db,
717         env.clone(),
718         traits_in_scope,
719         visible_from_module,
720         name,
721         &mut callback,
722     )?;
723
724     let ref_muted = Canonical {
725         value: TyKind::Ref(Mutability::Mut, static_lifetime(), receiver_ty.value.clone())
726             .intern(Interner),
727         binders: receiver_ty.binders.clone(),
728     };
729
730     iterate_method_candidates_by_receiver(
731         &ref_muted,
732         first_adjustment.with_autoref(Mutability::Mut),
733         deref_chain,
734         db,
735         env,
736         traits_in_scope,
737         visible_from_module,
738         name,
739         &mut callback,
740     )
741 }
742
743 fn iterate_method_candidates_by_receiver(
744     receiver_ty: &Canonical<Ty>,
745     receiver_adjustments: ReceiverAdjustments,
746     rest_of_deref_chain: &[Canonical<Ty>],
747     db: &dyn HirDatabase,
748     env: Arc<TraitEnvironment>,
749     traits_in_scope: &FxHashSet<TraitId>,
750     visible_from_module: VisibleFromModule,
751     name: Option<&Name>,
752     mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
753 ) -> ControlFlow<()> {
754     // We're looking for methods with *receiver* type receiver_ty. These could
755     // be found in any of the derefs of receiver_ty, so we have to go through
756     // that.
757     for self_ty in iter::once(receiver_ty).chain(rest_of_deref_chain) {
758         iterate_inherent_methods(
759             self_ty,
760             db,
761             env.clone(),
762             name,
763             Some(receiver_ty),
764             Some(receiver_adjustments.clone()),
765             visible_from_module,
766             &mut callback,
767         )?
768     }
769
770     for self_ty in iter::once(receiver_ty).chain(rest_of_deref_chain) {
771         iterate_trait_method_candidates(
772             self_ty,
773             db,
774             env.clone(),
775             traits_in_scope,
776             name,
777             Some(receiver_ty),
778             Some(receiver_adjustments.clone()),
779             &mut callback,
780         )?
781     }
782
783     ControlFlow::Continue(())
784 }
785
786 fn iterate_method_candidates_for_self_ty(
787     self_ty: &Canonical<Ty>,
788     db: &dyn HirDatabase,
789     env: Arc<TraitEnvironment>,
790     traits_in_scope: &FxHashSet<TraitId>,
791     visible_from_module: VisibleFromModule,
792     name: Option<&Name>,
793     mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
794 ) -> ControlFlow<()> {
795     iterate_inherent_methods(
796         self_ty,
797         db,
798         env.clone(),
799         name,
800         None,
801         None,
802         visible_from_module,
803         &mut callback,
804     )?;
805     iterate_trait_method_candidates(self_ty, db, env, traits_in_scope, name, None, None, callback)
806 }
807
808 fn iterate_trait_method_candidates(
809     self_ty: &Canonical<Ty>,
810     db: &dyn HirDatabase,
811     env: Arc<TraitEnvironment>,
812     traits_in_scope: &FxHashSet<TraitId>,
813     name: Option<&Name>,
814     receiver_ty: Option<&Canonical<Ty>>,
815     receiver_adjustments: Option<ReceiverAdjustments>,
816     callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
817 ) -> ControlFlow<()> {
818     let self_is_array = matches!(self_ty.value.kind(Interner), chalk_ir::TyKind::Array(..));
819     // if ty is `dyn Trait`, the trait doesn't need to be in scope
820     let inherent_trait =
821         self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
822     let env_traits = matches!(self_ty.value.kind(Interner), TyKind::Placeholder(_))
823         // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
824         .then(|| {
825             env.traits_in_scope_from_clauses(self_ty.value.clone())
826                 .flat_map(|t| all_super_traits(db.upcast(), t))
827         })
828         .into_iter()
829         .flatten();
830     let traits = inherent_trait.chain(env_traits).chain(traits_in_scope.iter().copied());
831
832     'traits: for t in traits {
833         let data = db.trait_data(t);
834
835         // Traits annotated with `#[rustc_skip_array_during_method_dispatch]` are skipped during
836         // method resolution, if the receiver is an array, and we're compiling for editions before
837         // 2021.
838         // This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for
839         // arrays.
840         if data.skip_array_during_method_dispatch && self_is_array {
841             // FIXME: this should really be using the edition of the method name's span, in case it
842             // comes from a macro
843             if db.crate_graph()[env.krate].edition < Edition::Edition2021 {
844                 continue;
845             }
846         }
847
848         // we'll be lazy about checking whether the type implements the
849         // trait, but if we find out it doesn't, we'll skip the rest of the
850         // iteration
851         let mut known_implemented = false;
852         for &(_, item) in data.items.iter() {
853             // Don't pass a `visible_from_module` down to `is_valid_candidate`,
854             // since only inherent methods should be included into visibility checking.
855             if !is_valid_candidate(db, env.clone(), name, receiver_ty, item, self_ty, None) {
856                 continue;
857             }
858             if !known_implemented {
859                 let goal = generic_implements_goal(db, env.clone(), t, self_ty);
860                 if db.trait_solve(env.krate, goal.cast(Interner)).is_none() {
861                     continue 'traits;
862                 }
863             }
864             known_implemented = true;
865             callback(receiver_adjustments.clone().unwrap_or_default(), item)?;
866         }
867     }
868     ControlFlow::Continue(())
869 }
870
871 fn filter_inherent_impls_for_self_ty<'i>(
872     impls: &'i InherentImpls,
873     self_ty: &Ty,
874 ) -> impl Iterator<Item = &'i ImplId> {
875     // inherent methods on arrays are fingerprinted as [T; {unknown}], so we must also consider them when
876     // resolving a method call on an array with a known len
877     let array_impls = {
878         match self_ty.kind(Interner) {
879             TyKind::Array(parameters, array_len) if !array_len.is_unknown() => {
880                 let unknown_array_len_ty =
881                     TyKind::Array(parameters.clone(), consteval::usize_const(None));
882
883                 Some(impls.for_self_ty(&unknown_array_len_ty.intern(Interner)))
884             }
885             _ => None,
886         }
887     }
888     .into_iter()
889     .flatten();
890
891     impls.for_self_ty(self_ty).iter().chain(array_impls)
892 }
893
894 fn iterate_inherent_methods(
895     self_ty: &Canonical<Ty>,
896     db: &dyn HirDatabase,
897     env: Arc<TraitEnvironment>,
898     name: Option<&Name>,
899     receiver_ty: Option<&Canonical<Ty>>,
900     receiver_adjustments: Option<ReceiverAdjustments>,
901     visible_from_module: VisibleFromModule,
902     callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
903 ) -> ControlFlow<()> {
904     let def_crates = match def_crates(db, &self_ty.value, env.krate) {
905         Some(k) => k,
906         None => return ControlFlow::Continue(()),
907     };
908
909     let (module, block) = match visible_from_module {
910         VisibleFromModule::Filter(module) => (Some(module), module.containing_block()),
911         VisibleFromModule::IncludeBlock(block) => (None, Some(block)),
912         VisibleFromModule::None => (None, None),
913     };
914
915     if let Some(block_id) = block {
916         if let Some(impls) = db.inherent_impls_in_block(block_id) {
917             impls_for_self_ty(
918                 &impls,
919                 self_ty,
920                 db,
921                 env.clone(),
922                 name,
923                 receiver_ty,
924                 receiver_adjustments.clone(),
925                 module,
926                 callback,
927             )?;
928         }
929     }
930
931     for krate in def_crates {
932         let impls = db.inherent_impls_in_crate(krate);
933         impls_for_self_ty(
934             &impls,
935             self_ty,
936             db,
937             env.clone(),
938             name,
939             receiver_ty,
940             receiver_adjustments.clone(),
941             module,
942             callback,
943         )?;
944     }
945     return ControlFlow::Continue(());
946
947     fn impls_for_self_ty(
948         impls: &InherentImpls,
949         self_ty: &Canonical<Ty>,
950         db: &dyn HirDatabase,
951         env: Arc<TraitEnvironment>,
952         name: Option<&Name>,
953         receiver_ty: Option<&Canonical<Ty>>,
954         receiver_adjustments: Option<ReceiverAdjustments>,
955         visible_from_module: Option<ModuleId>,
956         callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId) -> ControlFlow<()>,
957     ) -> ControlFlow<()> {
958         let impls_for_self_ty = filter_inherent_impls_for_self_ty(impls, &self_ty.value);
959         for &impl_def in impls_for_self_ty {
960             for &item in &db.impl_data(impl_def).items {
961                 if !is_valid_candidate(
962                     db,
963                     env.clone(),
964                     name,
965                     receiver_ty,
966                     item,
967                     self_ty,
968                     visible_from_module,
969                 ) {
970                     continue;
971                 }
972                 // we have to check whether the self type unifies with the type
973                 // that the impl is for. If we have a receiver type, this
974                 // already happens in `is_valid_candidate` above; if not, we
975                 // check it here
976                 if receiver_ty.is_none()
977                     && inherent_impl_substs(db, env.clone(), impl_def, self_ty).is_none()
978                 {
979                     cov_mark::hit!(impl_self_type_match_without_receiver);
980                     continue;
981                 }
982                 callback(receiver_adjustments.clone().unwrap_or_default(), item)?;
983             }
984         }
985         ControlFlow::Continue(())
986     }
987 }
988
989 /// Returns the receiver type for the index trait call.
990 pub fn resolve_indexing_op(
991     db: &dyn HirDatabase,
992     env: Arc<TraitEnvironment>,
993     ty: Canonical<Ty>,
994     index_trait: TraitId,
995 ) -> Option<ReceiverAdjustments> {
996     let mut table = InferenceTable::new(db, env.clone());
997     let ty = table.instantiate_canonical(ty);
998     let (deref_chain, adj) = autoderef_method_receiver(&mut table, ty);
999     for (ty, adj) in deref_chain.into_iter().zip(adj) {
1000         let goal = generic_implements_goal(db, env.clone(), index_trait, &ty);
1001         if db.trait_solve(env.krate, goal.cast(Interner)).is_some() {
1002             return Some(adj);
1003         }
1004     }
1005     None
1006 }
1007
1008 fn is_transformed_receiver_ty_equal(transformed_receiver_ty: &Ty, receiver_ty: &Ty) -> bool {
1009     if transformed_receiver_ty == receiver_ty {
1010         return true;
1011     }
1012
1013     // a transformed receiver may be considered equal (and a valid method call candidate) if it is an array
1014     // with an unknown (i.e. generic) length, and the receiver is an array with the same item type but a known len,
1015     // this allows inherent methods on arrays to be considered valid resolution candidates
1016     match (transformed_receiver_ty.kind(Interner), receiver_ty.kind(Interner)) {
1017         (
1018             TyKind::Array(transformed_array_ty, transformed_array_len),
1019             TyKind::Array(receiver_array_ty, receiver_array_len),
1020         ) if transformed_array_ty == receiver_array_ty
1021             && transformed_array_len.is_unknown()
1022             && !receiver_array_len.is_unknown() =>
1023         {
1024             true
1025         }
1026         _ => false,
1027     }
1028 }
1029
1030 fn is_valid_candidate(
1031     db: &dyn HirDatabase,
1032     env: Arc<TraitEnvironment>,
1033     name: Option<&Name>,
1034     receiver_ty: Option<&Canonical<Ty>>,
1035     item: AssocItemId,
1036     self_ty: &Canonical<Ty>,
1037     visible_from_module: Option<ModuleId>,
1038 ) -> bool {
1039     match item {
1040         AssocItemId::FunctionId(m) => {
1041             let data = db.function_data(m);
1042             if let Some(name) = name {
1043                 if &data.name != name {
1044                     return false;
1045                 }
1046             }
1047             if let Some(receiver_ty) = receiver_ty {
1048                 if !data.has_self_param() {
1049                     return false;
1050                 }
1051                 let transformed_receiver_ty = match transform_receiver_ty(db, env, m, self_ty) {
1052                     Some(ty) => ty,
1053                     None => return false,
1054                 };
1055
1056                 if !is_transformed_receiver_ty_equal(&transformed_receiver_ty, &receiver_ty.value) {
1057                     return false;
1058                 }
1059             }
1060             if let Some(from_module) = visible_from_module {
1061                 if !db.function_visibility(m).is_visible_from(db.upcast(), from_module) {
1062                     cov_mark::hit!(autoderef_candidate_not_visible);
1063                     return false;
1064                 }
1065             }
1066
1067             true
1068         }
1069         AssocItemId::ConstId(c) => {
1070             let data = db.const_data(c);
1071             name.map_or(true, |name| data.name.as_ref() == Some(name)) && receiver_ty.is_none()
1072         }
1073         _ => false,
1074     }
1075 }
1076
1077 pub(crate) fn inherent_impl_substs(
1078     db: &dyn HirDatabase,
1079     env: Arc<TraitEnvironment>,
1080     impl_id: ImplId,
1081     self_ty: &Canonical<Ty>,
1082 ) -> Option<Substitution> {
1083     // we create a var for each type parameter of the impl; we need to keep in
1084     // mind here that `self_ty` might have vars of its own
1085     let self_ty_vars = self_ty.binders.len(Interner);
1086     let vars = TyBuilder::subst_for_def(db, impl_id)
1087         .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
1088         .build();
1089     let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(Interner, &vars);
1090     let mut kinds = self_ty.binders.interned().to_vec();
1091     kinds.extend(vars.iter(Interner).map(|x| {
1092         let kind = match x.data(Interner) {
1093             GenericArgData::Ty(_) => chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
1094             GenericArgData::Const(c) => chalk_ir::VariableKind::Const(c.data(Interner).ty.clone()),
1095             GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
1096         };
1097         chalk_ir::WithKind::new(kind, UniverseIndex::ROOT)
1098     }));
1099     let tys = Canonical {
1100         binders: CanonicalVarKinds::from_iter(Interner, kinds),
1101         value: (self_ty_with_vars, self_ty.value.clone()),
1102     };
1103     let substs = super::infer::unify(db, env, &tys)?;
1104     // We only want the substs for the vars we added, not the ones from self_ty.
1105     // Also, if any of the vars we added are still in there, we replace them by
1106     // Unknown. I think this can only really happen if self_ty contained
1107     // Unknown, and in that case we want the result to contain Unknown in those
1108     // places again.
1109     let suffix =
1110         Substitution::from_iter(Interner, substs.iter(Interner).skip(self_ty_vars).cloned());
1111     Some(fallback_bound_vars(suffix, self_ty_vars))
1112 }
1113
1114 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
1115 /// num_vars_to_keep) by `TyKind::Unknown`.
1116 pub(crate) fn fallback_bound_vars<T: Fold<Interner> + HasInterner<Interner = Interner>>(
1117     s: T,
1118     num_vars_to_keep: usize,
1119 ) -> T::Result {
1120     crate::fold_free_vars(
1121         s,
1122         |bound, binders| {
1123             if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1124                 TyKind::Error.intern(Interner)
1125             } else {
1126                 bound.shifted_in_from(binders).to_ty(Interner)
1127             }
1128         },
1129         |ty, bound, binders| {
1130             if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
1131                 consteval::usize_const(None)
1132             } else {
1133                 bound.shifted_in_from(binders).to_const(Interner, ty)
1134             }
1135         },
1136     )
1137 }
1138
1139 fn transform_receiver_ty(
1140     db: &dyn HirDatabase,
1141     env: Arc<TraitEnvironment>,
1142     function_id: FunctionId,
1143     self_ty: &Canonical<Ty>,
1144 ) -> Option<Ty> {
1145     let substs = match function_id.lookup(db.upcast()).container {
1146         ItemContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
1147             .push(self_ty.value.clone())
1148             .fill_with_unknown()
1149             .build(),
1150         ItemContainerId::ImplId(impl_id) => {
1151             let impl_substs = inherent_impl_substs(db, env, impl_id, self_ty)?;
1152             TyBuilder::subst_for_def(db, function_id)
1153                 .use_parent_substs(&impl_substs)
1154                 .fill_with_unknown()
1155                 .build()
1156         }
1157         // No receiver
1158         ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => unreachable!(),
1159     };
1160     let sig = db.callable_item_signature(function_id.into());
1161     Some(sig.map(|s| s.params()[0].clone()).substitute(Interner, &substs))
1162 }
1163
1164 pub fn implements_trait(
1165     ty: &Canonical<Ty>,
1166     db: &dyn HirDatabase,
1167     env: Arc<TraitEnvironment>,
1168     trait_: TraitId,
1169 ) -> bool {
1170     let goal = generic_implements_goal(db, env.clone(), trait_, ty);
1171     let solution = db.trait_solve(env.krate, goal.cast(Interner));
1172
1173     solution.is_some()
1174 }
1175
1176 pub fn implements_trait_unique(
1177     ty: &Canonical<Ty>,
1178     db: &dyn HirDatabase,
1179     env: Arc<TraitEnvironment>,
1180     trait_: TraitId,
1181 ) -> bool {
1182     let goal = generic_implements_goal(db, env.clone(), trait_, ty);
1183     let solution = db.trait_solve(env.krate, goal.cast(Interner));
1184
1185     matches!(solution, Some(crate::Solution::Unique(_)))
1186 }
1187
1188 /// This creates Substs for a trait with the given Self type and type variables
1189 /// for all other parameters, to query Chalk with it.
1190 fn generic_implements_goal(
1191     db: &dyn HirDatabase,
1192     env: Arc<TraitEnvironment>,
1193     trait_: TraitId,
1194     self_ty: &Canonical<Ty>,
1195 ) -> Canonical<InEnvironment<super::DomainGoal>> {
1196     let mut kinds = self_ty.binders.interned().to_vec();
1197     let trait_ref = TyBuilder::trait_ref(db, trait_)
1198         .push(self_ty.value.clone())
1199         .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
1200         .build();
1201     kinds.extend(trait_ref.substitution.iter(Interner).skip(1).map(|x| {
1202         let vk = match x.data(Interner) {
1203             chalk_ir::GenericArgData::Ty(_) => {
1204                 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
1205             }
1206             chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
1207             chalk_ir::GenericArgData::Const(c) => {
1208                 chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
1209             }
1210         };
1211         chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
1212     }));
1213     let obligation = trait_ref.cast(Interner);
1214     Canonical {
1215         binders: CanonicalVarKinds::from_iter(Interner, kinds),
1216         value: InEnvironment::new(&env.env, obligation),
1217     }
1218 }
1219
1220 fn autoderef_method_receiver(
1221     table: &mut InferenceTable,
1222     ty: Ty,
1223 ) -> (Vec<Canonical<Ty>>, Vec<ReceiverAdjustments>) {
1224     let (mut deref_chain, mut adjustments): (Vec<_>, Vec<_>) = (Vec::new(), Vec::new());
1225     let mut autoderef = autoderef::Autoderef::new(table, ty);
1226     while let Some((ty, derefs)) = autoderef.next() {
1227         deref_chain.push(autoderef.table.canonicalize(ty).value);
1228         adjustments.push(ReceiverAdjustments {
1229             autoref: None,
1230             autoderefs: derefs,
1231             unsize_array: false,
1232         });
1233     }
1234     // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
1235     if let (Some((TyKind::Array(parameters, _), binders)), Some(adj)) = (
1236         deref_chain.last().map(|ty| (ty.value.kind(Interner), ty.binders.clone())),
1237         adjustments.last().cloned(),
1238     ) {
1239         let unsized_ty = TyKind::Slice(parameters.clone()).intern(Interner);
1240         deref_chain.push(Canonical { value: unsized_ty, binders });
1241         adjustments.push(ReceiverAdjustments { unsize_array: true, ..adj });
1242     }
1243     (deref_chain, adjustments)
1244 }