hir_ty/
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 rustc_hir_analysis/check/method/probe.rs.
5use std::ops::ControlFlow;
6
7use arrayvec::ArrayVec;
8use base_db::Crate;
9use chalk_ir::{UniverseIndex, WithKind, cast::Cast};
10use hir_def::{
11    AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup,
12    ModuleId, TraitId,
13    nameres::{DefMap, assoc::ImplItems, block_def_map, crate_def_map},
14    signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags},
15};
16use hir_expand::name::Name;
17use intern::sym;
18use rustc_hash::{FxHashMap, FxHashSet};
19use rustc_type_ir::inherent::{IntoKind, SliceLike};
20use smallvec::{SmallVec, smallvec};
21use stdx::never;
22use triomphe::Arc;
23
24use crate::{
25    AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData,
26    Goal, InEnvironment, Interner, Mutability, Scalar, Substitution, TraitEnvironment, TraitRef,
27    TraitRefExt, Ty, TyBuilder, TyExt, TyKind, TyVariableKind, VariableKind, WhereClause,
28    autoderef::{self, AutoderefKind},
29    db::HirDatabase,
30    error_lifetime, from_chalk_trait_id, from_foreign_def_id,
31    infer::{Adjust, Adjustment, OverloadedDeref, PointerCast, unify::InferenceTable},
32    lang_items::is_box,
33    next_solver::SolverDefId,
34    primitive::{FloatTy, IntTy, UintTy},
35    to_chalk_trait_id,
36    traits::NextTraitSolveResult,
37    utils::all_super_traits,
38};
39
40/// This is used as a key for indexing impls.
41#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
42pub enum TyFingerprint {
43    // These are lang item impls:
44    Str,
45    Slice,
46    Array,
47    Never,
48    Ref(Mutability),
49    RawPtr(Mutability),
50    Scalar(Scalar),
51    // These can have user-defined impls:
52    Adt(hir_def::AdtId),
53    Dyn(TraitId),
54    ForeignType(ForeignDefId),
55    // These only exist for trait impls
56    Unit,
57    Unnameable,
58    Function(u32),
59}
60
61impl TyFingerprint {
62    /// Creates a TyFingerprint for looking up an inherent impl. Only certain
63    /// types can have inherent impls: if we have some `struct S`, we can have
64    /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
65    /// reference types and such.
66    pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
67        let fp = match ty.kind(Interner) {
68            TyKind::Str => TyFingerprint::Str,
69            TyKind::Never => TyFingerprint::Never,
70            TyKind::Slice(..) => TyFingerprint::Slice,
71            TyKind::Array(..) => TyFingerprint::Array,
72            TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
73            TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
74            TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
75            TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
76            TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
77            _ => return None,
78        };
79        Some(fp)
80    }
81
82    /// Creates a TyFingerprint for looking up a trait impl.
83    pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> {
84        let fp = match ty.kind(Interner) {
85            TyKind::Str => TyFingerprint::Str,
86            TyKind::Never => TyFingerprint::Never,
87            TyKind::Slice(..) => TyFingerprint::Slice,
88            TyKind::Array(..) => TyFingerprint::Array,
89            TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
90            TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
91            TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
92            TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
93            TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
94            TyKind::Ref(mutability, _, _) => TyFingerprint::Ref(*mutability),
95            TyKind::Tuple(_, subst) => {
96                let first_ty = subst.interned().first().map(|arg| arg.assert_ty_ref(Interner));
97                match first_ty {
98                    Some(ty) => return TyFingerprint::for_trait_impl(ty),
99                    None => TyFingerprint::Unit,
100                }
101            }
102            TyKind::AssociatedType(_, _)
103            | TyKind::OpaqueType(_, _)
104            | TyKind::FnDef(_, _)
105            | TyKind::Closure(_, _)
106            | TyKind::Coroutine(..)
107            | TyKind::CoroutineWitness(..) => TyFingerprint::Unnameable,
108            TyKind::Function(fn_ptr) => {
109                TyFingerprint::Function(fn_ptr.substitution.0.len(Interner) as u32)
110            }
111            TyKind::Alias(_)
112            | TyKind::Placeholder(_)
113            | TyKind::BoundVar(_)
114            | TyKind::InferenceVar(_, _)
115            | TyKind::Error => return None,
116        };
117        Some(fp)
118    }
119
120    /// Creates a TyFingerprint for looking up a trait impl.
121    pub fn for_trait_impl_ns<'db>(ty: &crate::next_solver::Ty<'db>) -> Option<TyFingerprint> {
122        use rustc_type_ir::TyKind;
123        let fp = match (*ty).kind() {
124            TyKind::Str => TyFingerprint::Str,
125            TyKind::Never => TyFingerprint::Never,
126            TyKind::Slice(..) => TyFingerprint::Slice,
127            TyKind::Array(..) => TyFingerprint::Array,
128            TyKind::Int(int) => TyFingerprint::Scalar(Scalar::Int(match int {
129                rustc_type_ir::IntTy::Isize => IntTy::Isize,
130                rustc_type_ir::IntTy::I8 => IntTy::I8,
131                rustc_type_ir::IntTy::I16 => IntTy::I16,
132                rustc_type_ir::IntTy::I32 => IntTy::I32,
133                rustc_type_ir::IntTy::I64 => IntTy::I64,
134                rustc_type_ir::IntTy::I128 => IntTy::I128,
135            })),
136            TyKind::Uint(uint) => TyFingerprint::Scalar(Scalar::Uint(match uint {
137                rustc_type_ir::UintTy::Usize => UintTy::Usize,
138                rustc_type_ir::UintTy::U8 => UintTy::U8,
139                rustc_type_ir::UintTy::U16 => UintTy::U16,
140                rustc_type_ir::UintTy::U32 => UintTy::U32,
141                rustc_type_ir::UintTy::U64 => UintTy::U64,
142                rustc_type_ir::UintTy::U128 => UintTy::U128,
143            })),
144            TyKind::Float(float) => TyFingerprint::Scalar(Scalar::Float(match float {
145                rustc_type_ir::FloatTy::F16 => FloatTy::F16,
146                rustc_type_ir::FloatTy::F32 => FloatTy::F32,
147                rustc_type_ir::FloatTy::F64 => FloatTy::F64,
148                rustc_type_ir::FloatTy::F128 => FloatTy::F128,
149            })),
150            TyKind::Bool => TyFingerprint::Scalar(Scalar::Bool),
151            TyKind::Char => TyFingerprint::Scalar(Scalar::Char),
152            TyKind::Adt(def, _) => TyFingerprint::Adt(def.inner().id),
153            TyKind::RawPtr(.., mutability) => match mutability {
154                rustc_ast_ir::Mutability::Mut => TyFingerprint::RawPtr(Mutability::Mut),
155                rustc_ast_ir::Mutability::Not => TyFingerprint::RawPtr(Mutability::Not),
156            },
157            TyKind::Foreign(def) => {
158                let SolverDefId::TypeAliasId(def) = def else { unreachable!() };
159                TyFingerprint::ForeignType(crate::to_foreign_def_id(def))
160            }
161            TyKind::Dynamic(bounds, _, _) => {
162                let trait_ref = bounds
163                    .as_slice()
164                    .iter()
165                    .map(|b| (*b).skip_binder())
166                    .filter_map(|b| match b {
167                        rustc_type_ir::ExistentialPredicate::Trait(t) => Some(t.def_id),
168                        _ => None,
169                    })
170                    .next()?;
171                let trait_id = match trait_ref {
172                    SolverDefId::TraitId(id) => id,
173                    _ => panic!("Bad GenericDefId in trait ref"),
174                };
175                TyFingerprint::Dyn(trait_id)
176            }
177            TyKind::Ref(_, _, mutability) => match mutability {
178                rustc_ast_ir::Mutability::Mut => TyFingerprint::Ref(Mutability::Mut),
179                rustc_ast_ir::Mutability::Not => TyFingerprint::Ref(Mutability::Not),
180            },
181            TyKind::Tuple(tys) => {
182                let first_ty = tys.as_slice().iter().next();
183                match first_ty {
184                    Some(ty) => return TyFingerprint::for_trait_impl_ns(ty),
185                    None => TyFingerprint::Unit,
186                }
187            }
188            TyKind::FnDef(_, _)
189            | TyKind::Closure(_, _)
190            | TyKind::Coroutine(..)
191            | TyKind::CoroutineWitness(..)
192            | TyKind::Pat(..)
193            | TyKind::CoroutineClosure(..) => TyFingerprint::Unnameable,
194            TyKind::FnPtr(sig, _) => {
195                TyFingerprint::Function(sig.inputs().skip_binder().len() as u32)
196            }
197            TyKind::Alias(..)
198            | TyKind::Placeholder(_)
199            | TyKind::Bound(..)
200            | TyKind::Infer(_)
201            | TyKind::Error(_)
202            | TyKind::Param(..)
203            | TyKind::UnsafeBinder(..) => return None,
204        };
205        Some(fp)
206    }
207}
208
209pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
210    TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
211    TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
212    TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
213    TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
214    TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
215    TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
216    TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
217    TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
218    TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
219    TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
220    TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
221    TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
222];
223
224pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 4] = [
225    TyFingerprint::Scalar(Scalar::Float(FloatTy::F16)),
226    TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
227    TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
228    TyFingerprint::Scalar(Scalar::Float(FloatTy::F128)),
229];
230
231type TraitFpMap = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Box<[ImplId]>>>;
232type TraitFpMapCollector = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>;
233
234/// Trait impls defined or available in some crate.
235#[derive(Debug, Eq, PartialEq)]
236pub struct TraitImpls {
237    // If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type.
238    map: TraitFpMap,
239}
240
241impl TraitImpls {
242    pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: Crate) -> Arc<Self> {
243        let _p = tracing::info_span!("trait_impls_in_crate_query", ?krate).entered();
244        let mut impls = FxHashMap::default();
245
246        Self::collect_def_map(db, &mut impls, crate_def_map(db, krate));
247
248        Arc::new(Self::finish(impls))
249    }
250
251    pub(crate) fn trait_impls_in_block_query(
252        db: &dyn HirDatabase,
253        block: BlockId,
254    ) -> Option<Arc<Self>> {
255        let _p = tracing::info_span!("trait_impls_in_block_query").entered();
256        let mut impls = FxHashMap::default();
257
258        Self::collect_def_map(db, &mut impls, block_def_map(db, block));
259
260        if impls.is_empty() { None } else { Some(Arc::new(Self::finish(impls))) }
261    }
262
263    pub(crate) fn trait_impls_in_deps_query(
264        db: &dyn HirDatabase,
265        krate: Crate,
266    ) -> Arc<[Arc<Self>]> {
267        let _p = tracing::info_span!("trait_impls_in_deps_query", ?krate).entered();
268        Arc::from_iter(
269            db.transitive_deps(krate).into_iter().map(|krate| db.trait_impls_in_crate(krate)),
270        )
271    }
272
273    fn finish(map: TraitFpMapCollector) -> TraitImpls {
274        TraitImpls {
275            map: map
276                .into_iter()
277                .map(|(k, v)| (k, v.into_iter().map(|(k, v)| (k, v.into_boxed_slice())).collect()))
278                .collect(),
279        }
280    }
281
282    fn collect_def_map(db: &dyn HirDatabase, map: &mut TraitFpMapCollector, def_map: &DefMap) {
283        for (_module_id, module_data) in def_map.modules() {
284            for impl_id in module_data.scope.impls() {
285                // Reservation impls should be ignored during trait resolution, so we never need
286                // them during type analysis. See rust-lang/rust#64631 for details.
287                //
288                // FIXME: Reservation impls should be considered during coherence checks. If we are
289                // (ever) to implement coherence checks, this filtering should be done by the trait
290                // solver.
291                if db.attrs(impl_id.into()).by_key(sym::rustc_reservation_impl).exists() {
292                    continue;
293                }
294                let target_trait = match db.impl_trait(impl_id) {
295                    Some(tr) => tr.skip_binders().hir_trait_id(),
296                    None => continue,
297                };
298                let self_ty = db.impl_self_ty(impl_id);
299                let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
300                map.entry(target_trait).or_default().entry(self_ty_fp).or_default().push(impl_id);
301            }
302
303            // To better support custom derives, collect impls in all unnamed const items.
304            // const _: () = { ... };
305            for konst in module_data.scope.unnamed_consts() {
306                let body = db.body(konst.into());
307                for (_, block_def_map) in body.blocks(db) {
308                    Self::collect_def_map(db, map, block_def_map);
309                }
310            }
311        }
312    }
313
314    /// Queries all trait impls for the given type.
315    pub fn for_self_ty_without_blanket_impls(
316        &self,
317        fp: TyFingerprint,
318    ) -> impl Iterator<Item = ImplId> + '_ {
319        self.map
320            .values()
321            .flat_map(move |impls| impls.get(&Some(fp)).into_iter())
322            .flat_map(|it| it.iter().copied())
323    }
324
325    /// Queries all impls of the given trait.
326    pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ {
327        self.map
328            .get(&trait_)
329            .into_iter()
330            .flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
331    }
332
333    /// Queries all impls of `trait_` that may apply to `self_ty`.
334    pub fn for_trait_and_self_ty(
335        &self,
336        trait_: TraitId,
337        self_ty: TyFingerprint,
338    ) -> impl Iterator<Item = ImplId> + '_ {
339        self.map
340            .get(&trait_)
341            .into_iter()
342            .flat_map(move |map| map.get(&Some(self_ty)).into_iter().chain(map.get(&None)))
343            .flat_map(|v| v.iter().copied())
344    }
345
346    /// Queries whether `self_ty` has potentially applicable implementations of `trait_`.
347    pub fn has_impls_for_trait_and_self_ty(&self, trait_: TraitId, self_ty: TyFingerprint) -> bool {
348        self.for_trait_and_self_ty(trait_, self_ty).next().is_some()
349    }
350
351    pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
352        self.map.values().flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
353    }
354}
355
356/// Inherent impls defined in some crate.
357///
358/// Inherent impls can only be defined in the crate that also defines the self type of the impl
359/// (note that some primitives are considered to be defined by both libcore and liballoc).
360///
361/// This makes inherent impl lookup easier than trait impl lookup since we only have to consider a
362/// single crate.
363#[derive(Debug, Eq, PartialEq)]
364pub struct InherentImpls {
365    map: FxHashMap<TyFingerprint, Vec<ImplId>>,
366    invalid_impls: Vec<ImplId>,
367}
368
369impl InherentImpls {
370    pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: Crate) -> Arc<Self> {
371        let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered();
372        let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() };
373
374        let crate_def_map = crate_def_map(db, krate);
375        impls.collect_def_map(db, crate_def_map);
376        impls.shrink_to_fit();
377
378        Arc::new(impls)
379    }
380
381    pub(crate) fn inherent_impls_in_block_query(
382        db: &dyn HirDatabase,
383        block: BlockId,
384    ) -> Option<Arc<Self>> {
385        let _p = tracing::info_span!("inherent_impls_in_block_query").entered();
386        let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() };
387
388        let block_def_map = block_def_map(db, block);
389        impls.collect_def_map(db, block_def_map);
390        impls.shrink_to_fit();
391
392        if impls.map.is_empty() && impls.invalid_impls.is_empty() {
393            None
394        } else {
395            Some(Arc::new(impls))
396        }
397    }
398
399    fn shrink_to_fit(&mut self) {
400        self.map.values_mut().for_each(Vec::shrink_to_fit);
401        self.map.shrink_to_fit();
402    }
403
404    fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
405        for (_module_id, module_data) in def_map.modules() {
406            for impl_id in module_data.scope.impls() {
407                let data = db.impl_signature(impl_id);
408                if data.target_trait.is_some() {
409                    continue;
410                }
411
412                let self_ty = db.impl_self_ty(impl_id);
413                let self_ty = self_ty.skip_binders();
414
415                match is_inherent_impl_coherent(db, def_map, impl_id, self_ty) {
416                    true => {
417                        // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
418                        if let Some(fp) = TyFingerprint::for_inherent_impl(self_ty) {
419                            self.map.entry(fp).or_default().push(impl_id);
420                        }
421                    }
422                    false => self.invalid_impls.push(impl_id),
423                }
424            }
425
426            // To better support custom derives, collect impls in all unnamed const items.
427            // const _: () = { ... };
428            for konst in module_data.scope.unnamed_consts() {
429                let body = db.body(konst.into());
430                for (_, block_def_map) in body.blocks(db) {
431                    self.collect_def_map(db, block_def_map);
432                }
433            }
434        }
435    }
436
437    pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
438        match TyFingerprint::for_inherent_impl(self_ty) {
439            Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
440            None => &[],
441        }
442    }
443
444    pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
445        self.map.values().flat_map(|v| v.iter().copied())
446    }
447
448    pub fn invalid_impls(&self) -> &[ImplId] {
449        &self.invalid_impls
450    }
451}
452
453pub(crate) fn incoherent_inherent_impl_crates(
454    db: &dyn HirDatabase,
455    krate: Crate,
456    fp: TyFingerprint,
457) -> SmallVec<[Crate; 2]> {
458    let _p = tracing::info_span!("incoherent_inherent_impl_crates").entered();
459    let mut res = SmallVec::new();
460
461    // should pass crate for finger print and do reverse deps
462
463    for krate in db.transitive_deps(krate) {
464        let impls = db.inherent_impls_in_crate(krate);
465        if impls.map.get(&fp).is_some_and(|v| !v.is_empty()) {
466            res.push(krate);
467        }
468    }
469
470    res
471}
472
473pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<SmallVec<[Crate; 2]>> {
474    match ty.kind(Interner) {
475        &TyKind::Adt(AdtId(def_id), _) => {
476            let rustc_has_incoherent_inherent_impls = match def_id {
477                hir_def::AdtId::StructId(id) => db
478                    .struct_signature(id)
479                    .flags
480                    .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
481                hir_def::AdtId::UnionId(id) => db
482                    .union_signature(id)
483                    .flags
484                    .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
485                hir_def::AdtId::EnumId(id) => db
486                    .enum_signature(id)
487                    .flags
488                    .contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
489            };
490            Some(if rustc_has_incoherent_inherent_impls {
491                db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Adt(def_id))
492            } else {
493                smallvec![def_id.module(db).krate()]
494            })
495        }
496        &TyKind::Foreign(id) => {
497            let alias = from_foreign_def_id(id);
498            Some(
499                if db
500                    .type_alias_signature(alias)
501                    .flags
502                    .contains(TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPL)
503                {
504                    db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(id))
505                } else {
506                    smallvec![alias.module(db).krate()]
507                },
508            )
509        }
510        TyKind::Dyn(_) => {
511            let trait_id = ty.dyn_trait()?;
512            Some(
513                if db
514                    .trait_signature(trait_id)
515                    .flags
516                    .contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
517                {
518                    db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Dyn(trait_id))
519                } else {
520                    smallvec![trait_id.module(db).krate()]
521                },
522            )
523        }
524        // for primitives, there may be impls in various places (core and alloc
525        // mostly). We just check the whole crate graph for crates with impls
526        // (cached behind a query).
527        TyKind::Scalar(_)
528        | TyKind::Str
529        | TyKind::Slice(_)
530        | TyKind::Array(..)
531        | TyKind::Raw(..) => Some(db.incoherent_inherent_impl_crates(
532            cur_crate,
533            TyFingerprint::for_inherent_impl(ty).expect("fingerprint for primitive"),
534        )),
535        _ => None,
536    }
537}
538
539/// Look up the method with the given name.
540pub(crate) fn lookup_method(
541    db: &dyn HirDatabase,
542    ty: &Canonical<Ty>,
543    env: Arc<TraitEnvironment>,
544    traits_in_scope: &FxHashSet<TraitId>,
545    visible_from_module: VisibleFromModule,
546    name: &Name,
547) -> Option<(ReceiverAdjustments, FunctionId, bool)> {
548    let mut not_visible = None;
549    let res = iterate_method_candidates(
550        ty,
551        db,
552        env,
553        traits_in_scope,
554        visible_from_module,
555        Some(name),
556        LookupMode::MethodCall,
557        |adjustments, f, visible| match f {
558            AssocItemId::FunctionId(f) if visible => Some((adjustments, f, true)),
559            AssocItemId::FunctionId(f) if not_visible.is_none() => {
560                not_visible = Some((adjustments, f, false));
561                None
562            }
563            _ => None,
564        },
565    );
566    res.or(not_visible)
567}
568
569/// Whether we're looking up a dotted method call (like `v.len()`) or a path
570/// (like `Vec::new`).
571#[derive(Copy, Clone, Debug, PartialEq, Eq)]
572pub enum LookupMode {
573    /// Looking up a method call like `v.len()`: We only consider candidates
574    /// that have a `self` parameter, and do autoderef.
575    MethodCall,
576    /// Looking up a path like `Vec::new` or `Vec::default`: We consider all
577    /// candidates including associated constants, but don't do autoderef.
578    Path,
579}
580
581#[derive(Clone, Copy)]
582pub enum VisibleFromModule {
583    /// Filter for results that are visible from the given module
584    Filter(ModuleId),
585    /// Include impls from the given block.
586    IncludeBlock(BlockId),
587    /// Do nothing special in regards visibility
588    None,
589}
590
591impl From<Option<ModuleId>> for VisibleFromModule {
592    fn from(module: Option<ModuleId>) -> Self {
593        match module {
594            Some(module) => Self::Filter(module),
595            None => Self::None,
596        }
597    }
598}
599
600impl From<Option<BlockId>> for VisibleFromModule {
601    fn from(block: Option<BlockId>) -> Self {
602        match block {
603            Some(block) => Self::IncludeBlock(block),
604            None => Self::None,
605        }
606    }
607}
608
609#[derive(Debug, Clone)]
610pub enum AutorefOrPtrAdjustment {
611    Autoref(Mutability),
612    ToConstPtr,
613}
614
615#[derive(Debug, Clone, Default)]
616pub struct ReceiverAdjustments {
617    autoref: Option<AutorefOrPtrAdjustment>,
618    autoderefs: usize,
619    unsize_array: bool,
620}
621
622impl ReceiverAdjustments {
623    pub(crate) fn apply(&self, table: &mut InferenceTable<'_>, ty: Ty) -> (Ty, Vec<Adjustment>) {
624        let mut ty = table.resolve_ty_shallow(&ty);
625        let mut adjust = Vec::new();
626        for _ in 0..self.autoderefs {
627            match autoderef::autoderef_step(table, ty.clone(), true, false) {
628                None => {
629                    never!("autoderef not possible for {:?}", ty);
630                    ty = TyKind::Error.intern(Interner);
631                    break;
632                }
633                Some((kind, new_ty)) => {
634                    ty = new_ty.clone();
635                    let mutbl = match self.autoref {
636                        Some(AutorefOrPtrAdjustment::Autoref(m)) => Some(m),
637                        Some(AutorefOrPtrAdjustment::ToConstPtr) => Some(Mutability::Not),
638                        // FIXME should we know the mutability here, when autoref is `None`?
639                        None => None,
640                    };
641                    adjust.push(Adjustment {
642                        kind: Adjust::Deref(match kind {
643                            AutoderefKind::Overloaded => Some(OverloadedDeref(mutbl)),
644                            AutoderefKind::Builtin => None,
645                        }),
646                        target: new_ty,
647                    });
648                }
649            }
650        }
651        if let Some(autoref) = &self.autoref {
652            let lt = table.new_lifetime_var();
653            match autoref {
654                AutorefOrPtrAdjustment::Autoref(m) => {
655                    let a = Adjustment::borrow(*m, ty, lt);
656                    ty = a.target.clone();
657                    adjust.push(a);
658                }
659                AutorefOrPtrAdjustment::ToConstPtr => {
660                    if let TyKind::Raw(Mutability::Mut, pointee) = ty.kind(Interner) {
661                        let a = Adjustment {
662                            kind: Adjust::Pointer(PointerCast::MutToConstPointer),
663                            target: TyKind::Raw(Mutability::Not, pointee.clone()).intern(Interner),
664                        };
665                        ty = a.target.clone();
666                        adjust.push(a);
667                    } else {
668                        never!("`ToConstPtr` target is not a raw mutable pointer");
669                    }
670                }
671            };
672        }
673        if self.unsize_array {
674            ty = 'it: {
675                if let TyKind::Ref(m, l, inner) = ty.kind(Interner)
676                    && let TyKind::Array(inner, _) = inner.kind(Interner)
677                {
678                    break 'it TyKind::Ref(
679                        *m,
680                        l.clone(),
681                        TyKind::Slice(inner.clone()).intern(Interner),
682                    )
683                    .intern(Interner);
684                }
685                // FIXME: report diagnostic if array unsizing happens without indirection.
686                ty
687            };
688            adjust.push(Adjustment {
689                kind: Adjust::Pointer(PointerCast::Unsize),
690                target: ty.clone(),
691            });
692        }
693        (ty, adjust)
694    }
695
696    fn with_autoref(&self, a: AutorefOrPtrAdjustment) -> ReceiverAdjustments {
697        Self { autoref: Some(a), ..*self }
698    }
699}
700
701// This would be nicer if it just returned an iterator, but that runs into
702// lifetime problems, because we need to borrow temp `CrateImplDefs`.
703// FIXME add a context type here?
704pub(crate) fn iterate_method_candidates<T>(
705    ty: &Canonical<Ty>,
706    db: &dyn HirDatabase,
707    env: Arc<TraitEnvironment>,
708    traits_in_scope: &FxHashSet<TraitId>,
709    visible_from_module: VisibleFromModule,
710    name: Option<&Name>,
711    mode: LookupMode,
712    mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option<T>,
713) -> Option<T> {
714    let mut slot = None;
715    _ = iterate_method_candidates_dyn(
716        ty,
717        db,
718        env,
719        traits_in_scope,
720        visible_from_module,
721        name,
722        mode,
723        &mut |adj, item, visible| {
724            assert!(slot.is_none());
725            if let Some(it) = callback(adj, item, visible) {
726                slot = Some(it);
727                return ControlFlow::Break(());
728            }
729            ControlFlow::Continue(())
730        },
731    );
732    slot
733}
734
735pub fn lookup_impl_const(
736    db: &dyn HirDatabase,
737    env: Arc<TraitEnvironment>,
738    const_id: ConstId,
739    subs: Substitution,
740) -> (ConstId, Substitution) {
741    let trait_id = match const_id.lookup(db).container {
742        ItemContainerId::TraitId(id) => id,
743        _ => return (const_id, subs),
744    };
745    let substitution = Substitution::from_iter(Interner, subs.iter(Interner));
746    let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution };
747
748    let const_signature = db.const_signature(const_id);
749    let name = match const_signature.name.as_ref() {
750        Some(name) => name,
751        None => return (const_id, subs),
752    };
753
754    lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name)
755        .and_then(
756            |assoc| if let (AssocItemId::ConstId(id), s) = assoc { Some((id, s)) } else { None },
757        )
758        .unwrap_or((const_id, subs))
759}
760
761/// Checks if the self parameter of `Trait` method is the `dyn Trait` and we should
762/// call the method using the vtable.
763pub fn is_dyn_method(
764    db: &dyn HirDatabase,
765    _env: Arc<TraitEnvironment>,
766    func: FunctionId,
767    fn_subst: Substitution,
768) -> Option<usize> {
769    let ItemContainerId::TraitId(trait_id) = func.lookup(db).container else {
770        return None;
771    };
772    let trait_params = db.generic_params(trait_id.into()).len();
773    let fn_params = fn_subst.len(Interner) - trait_params;
774    let trait_ref = TraitRef {
775        trait_id: to_chalk_trait_id(trait_id),
776        substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).take(trait_params)),
777    };
778    let self_ty = trait_ref.self_type_parameter(Interner);
779    if let TyKind::Dyn(d) = self_ty.kind(Interner) {
780        let is_my_trait_in_bounds = d
781            .bounds
782            .skip_binders()
783            .as_slice(Interner)
784            .iter()
785            .map(|it| it.skip_binders())
786            .flat_map(|it| match it {
787                WhereClause::Implemented(tr) => {
788                    all_super_traits(db, from_chalk_trait_id(tr.trait_id))
789                }
790                _ => smallvec![],
791            })
792            // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
793            // what the generics are, we are sure that the method is come from the vtable.
794            .any(|x| x == trait_id);
795        if is_my_trait_in_bounds {
796            return Some(fn_params);
797        }
798    }
799    None
800}
801
802/// Looks up the impl method that actually runs for the trait method `func`.
803///
804/// Returns `func` if it's not a method defined in a trait or the lookup failed.
805pub(crate) fn lookup_impl_method_query(
806    db: &dyn HirDatabase,
807    env: Arc<TraitEnvironment>,
808    func: FunctionId,
809    fn_subst: Substitution,
810) -> (FunctionId, Substitution) {
811    let ItemContainerId::TraitId(trait_id) = func.lookup(db).container else {
812        return (func, fn_subst);
813    };
814    let trait_params = db.generic_params(trait_id.into()).len();
815    let trait_ref = TraitRef {
816        trait_id: to_chalk_trait_id(trait_id),
817        substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).take(trait_params)),
818    };
819
820    let name = &db.function_signature(func).name;
821    let Some((impl_fn, impl_subst)) =
822        lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name).and_then(|assoc| {
823            if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None }
824        })
825    else {
826        return (func, fn_subst);
827    };
828
829    (
830        impl_fn,
831        Substitution::from_iter(
832            Interner,
833            impl_subst.iter(Interner).chain(fn_subst.iter(Interner).skip(trait_params)),
834        ),
835    )
836}
837
838fn lookup_impl_assoc_item_for_trait_ref(
839    trait_ref: TraitRef,
840    db: &dyn HirDatabase,
841    env: Arc<TraitEnvironment>,
842    name: &Name,
843) -> Option<(AssocItemId, Substitution)> {
844    let hir_trait_id = trait_ref.hir_trait_id();
845    let self_ty = trait_ref.self_type_parameter(Interner);
846    let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
847    let impls = db.trait_impls_in_deps(env.krate);
848
849    let trait_module = hir_trait_id.module(db);
850    let type_module = match self_ty_fp {
851        TyFingerprint::Adt(adt_id) => Some(adt_id.module(db)),
852        TyFingerprint::ForeignType(type_id) => Some(from_foreign_def_id(type_id).module(db)),
853        TyFingerprint::Dyn(trait_id) => Some(trait_id.module(db)),
854        _ => None,
855    };
856
857    let def_blocks: ArrayVec<_, 2> =
858        [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())]
859            .into_iter()
860            .flatten()
861            .filter_map(|block_id| db.trait_impls_in_block(block_id))
862            .collect();
863
864    let impls = impls
865        .iter()
866        .chain(&def_blocks)
867        .flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
868
869    let table = InferenceTable::new(db, env);
870
871    let (impl_data, impl_subst) = find_matching_impl(impls, table, trait_ref)?;
872    let item = impl_data.items.iter().find_map(|(n, it)| match *it {
873        AssocItemId::FunctionId(f) => (n == name).then_some(AssocItemId::FunctionId(f)),
874        AssocItemId::ConstId(c) => (n == name).then_some(AssocItemId::ConstId(c)),
875        AssocItemId::TypeAliasId(_) => None,
876    })?;
877    Some((item, impl_subst))
878}
879
880fn find_matching_impl(
881    mut impls: impl Iterator<Item = ImplId>,
882    mut table: InferenceTable<'_>,
883    actual_trait_ref: TraitRef,
884) -> Option<(&ImplItems, Substitution)> {
885    let db = table.db;
886    impls.find_map(|impl_| {
887        table.run_in_snapshot(|table| {
888            let impl_substs =
889                TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build();
890            let trait_ref = db
891                .impl_trait(impl_)
892                .expect("non-trait method in find_matching_impl")
893                .substitute(Interner, &impl_substs);
894
895            if !table.unify(&trait_ref, &actual_trait_ref) {
896                return None;
897            }
898
899            let wcs = crate::chalk_db::convert_where_clauses(db, impl_.into(), &impl_substs)
900                .into_iter()
901                .map(|b| -> Goal { b.cast(Interner) });
902            for goal in wcs {
903                if table.try_obligation(goal.clone()).no_solution() {
904                    return None;
905                }
906                table.register_obligation(goal);
907            }
908            Some((impl_.impl_items(db), table.resolve_completely(impl_substs)))
909        })
910    })
911}
912
913fn is_inherent_impl_coherent(
914    db: &dyn HirDatabase,
915    def_map: &DefMap,
916    impl_id: ImplId,
917    self_ty: &Ty,
918) -> bool {
919    let self_ty = self_ty.kind(Interner);
920    let impl_allowed = match self_ty {
921        TyKind::Tuple(_, _)
922        | TyKind::FnDef(_, _)
923        | TyKind::Array(_, _)
924        | TyKind::Never
925        | TyKind::Raw(_, _)
926        | TyKind::Ref(_, _, _)
927        | TyKind::Slice(_)
928        | TyKind::Str
929        | TyKind::Scalar(_) => def_map.is_rustc_coherence_is_core(),
930
931        &TyKind::Adt(AdtId(adt), _) => adt.module(db).krate() == def_map.krate(),
932        TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| {
933            from_chalk_trait_id(trait_id).module(db).krate() == def_map.krate()
934        }),
935
936        _ => true,
937    };
938    impl_allowed || {
939        let rustc_has_incoherent_inherent_impls = match self_ty {
940            TyKind::Tuple(_, _)
941            | TyKind::FnDef(_, _)
942            | TyKind::Array(_, _)
943            | TyKind::Never
944            | TyKind::Raw(_, _)
945            | TyKind::Ref(_, _, _)
946            | TyKind::Slice(_)
947            | TyKind::Str
948            | TyKind::Scalar(_) => true,
949
950            &TyKind::Adt(AdtId(adt), _) => match adt {
951                hir_def::AdtId::StructId(id) => db
952                    .struct_signature(id)
953                    .flags
954                    .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
955                hir_def::AdtId::UnionId(id) => db
956                    .union_signature(id)
957                    .flags
958                    .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
959                hir_def::AdtId::EnumId(it) => db
960                    .enum_signature(it)
961                    .flags
962                    .contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
963            },
964            TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| {
965                db.trait_signature(from_chalk_trait_id(trait_id))
966                    .flags
967                    .contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
968            }),
969
970            _ => false,
971        };
972        let items = impl_id.impl_items(db);
973        rustc_has_incoherent_inherent_impls
974            && !items.items.is_empty()
975            && items.items.iter().all(|&(_, assoc)| match assoc {
976                AssocItemId::FunctionId(it) => {
977                    db.function_signature(it).flags.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
978                }
979                AssocItemId::ConstId(it) => {
980                    db.const_signature(it).flags.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
981                }
982                AssocItemId::TypeAliasId(it) => db
983                    .type_alias_signature(it)
984                    .flags
985                    .contains(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL),
986            })
987    }
988}
989
990/// Checks whether the impl satisfies the orphan rules.
991///
992/// Given `impl<P1..=Pn> Trait<T1..=Tn> for T0`, an `impl`` is valid only if at least one of the following is true:
993/// - Trait is a local trait
994/// - All of
995///   - At least one of the types `T0..=Tn`` must be a local type. Let `Ti`` be the first such type.
996///   - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
997pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
998    let substs = TyBuilder::placeholder_subst(db, impl_);
999    let Some(impl_trait) = db.impl_trait(impl_) else {
1000        // not a trait impl
1001        return true;
1002    };
1003
1004    let local_crate = impl_.lookup(db).container.krate();
1005    let is_local = |tgt_crate| tgt_crate == local_crate;
1006
1007    let trait_ref = impl_trait.substitute(Interner, &substs);
1008    let trait_id = from_chalk_trait_id(trait_ref.trait_id);
1009    if is_local(trait_id.module(db).krate()) {
1010        // trait to be implemented is local
1011        return true;
1012    }
1013
1014    let unwrap_fundamental = |mut ty: Ty| {
1015        // Unwrap all layers of fundamental types with a loop.
1016        loop {
1017            match ty.kind(Interner) {
1018                TyKind::Ref(_, _, referenced) => ty = referenced.clone(),
1019                &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => {
1020                    let struct_signature = db.struct_signature(s);
1021                    if struct_signature.flags.contains(StructFlags::FUNDAMENTAL) {
1022                        let next = subs.type_parameters(Interner).next();
1023                        match next {
1024                            Some(it) => ty = it,
1025                            None => break ty,
1026                        }
1027                    } else {
1028                        break ty;
1029                    }
1030                }
1031                _ => break ty,
1032            }
1033        }
1034    };
1035    //   - At least one of the types `T0..=Tn`` must be a local type. Let `Ti`` be the first such type.
1036
1037    // FIXME: param coverage
1038    //   - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
1039    let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| {
1040        match unwrap_fundamental(ty).kind(Interner) {
1041            &TyKind::Adt(AdtId(id), _) => is_local(id.module(db).krate()),
1042            TyKind::Error => true,
1043            TyKind::Dyn(it) => it
1044                .principal_id()
1045                .is_some_and(|trait_id| is_local(from_chalk_trait_id(trait_id).module(db).krate())),
1046            _ => false,
1047        }
1048    });
1049    #[allow(clippy::let_and_return)]
1050    is_not_orphan
1051}
1052
1053pub fn iterate_path_candidates(
1054    ty: &Canonical<Ty>,
1055    db: &dyn HirDatabase,
1056    env: Arc<TraitEnvironment>,
1057    traits_in_scope: &FxHashSet<TraitId>,
1058    visible_from_module: VisibleFromModule,
1059    name: Option<&Name>,
1060    callback: &mut dyn MethodCandidateCallback,
1061) -> ControlFlow<()> {
1062    iterate_method_candidates_dyn(
1063        ty,
1064        db,
1065        env,
1066        traits_in_scope,
1067        visible_from_module,
1068        name,
1069        LookupMode::Path,
1070        // the adjustments are not relevant for path lookup
1071        callback,
1072    )
1073}
1074
1075pub fn iterate_method_candidates_dyn(
1076    ty: &Canonical<Ty>,
1077    db: &dyn HirDatabase,
1078    env: Arc<TraitEnvironment>,
1079    traits_in_scope: &FxHashSet<TraitId>,
1080    visible_from_module: VisibleFromModule,
1081    name: Option<&Name>,
1082    mode: LookupMode,
1083    callback: &mut dyn MethodCandidateCallback,
1084) -> ControlFlow<()> {
1085    let _p = tracing::info_span!(
1086        "iterate_method_candidates_dyn",
1087        ?mode,
1088        ?name,
1089        traits_in_scope_len = traits_in_scope.len()
1090    )
1091    .entered();
1092
1093    match mode {
1094        LookupMode::MethodCall => {
1095            // For method calls, rust first does any number of autoderef, and
1096            // then one autoref (i.e. when the method takes &self or &mut self).
1097            // Note that when we've got a receiver like &S, even if the method
1098            // we find in the end takes &self, we still do the autoderef step
1099            // (just as rustc does an autoderef and then autoref again).
1100
1101            // We have to be careful about the order we're looking at candidates
1102            // in here. Consider the case where we're resolving `it.clone()`
1103            // where `it: &Vec<_>`. This resolves to the clone method with self
1104            // type `Vec<_>`, *not* `&_`. I.e. we need to consider methods where
1105            // the receiver type exactly matches before cases where we have to
1106            // do autoref. But in the autoderef steps, the `&_` self type comes
1107            // up *before* the `Vec<_>` self type.
1108            //
1109            // On the other hand, we don't want to just pick any by-value method
1110            // before any by-autoref method; it's just that we need to consider
1111            // the methods by autoderef order of *receiver types*, not *self
1112            // types*.
1113
1114            let mut table = InferenceTable::new(db, env);
1115            let ty = table.instantiate_canonical(ty.clone());
1116            let deref_chain = autoderef_method_receiver(&mut table, ty);
1117
1118            deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| {
1119                iterate_method_candidates_with_autoref(
1120                    &mut table,
1121                    receiver_ty,
1122                    adj,
1123                    traits_in_scope,
1124                    visible_from_module,
1125                    name,
1126                    callback,
1127                )
1128            })
1129        }
1130        LookupMode::Path => {
1131            // No autoderef for path lookups
1132            iterate_method_candidates_for_self_ty(
1133                ty,
1134                db,
1135                env,
1136                traits_in_scope,
1137                visible_from_module,
1138                name,
1139                callback,
1140            )
1141        }
1142    }
1143}
1144
1145#[tracing::instrument(skip_all, fields(name = ?name))]
1146fn iterate_method_candidates_with_autoref(
1147    table: &mut InferenceTable<'_>,
1148    receiver_ty: Canonical<Ty>,
1149    first_adjustment: ReceiverAdjustments,
1150    traits_in_scope: &FxHashSet<TraitId>,
1151    visible_from_module: VisibleFromModule,
1152    name: Option<&Name>,
1153    callback: &mut dyn MethodCandidateCallback,
1154) -> ControlFlow<()> {
1155    if receiver_ty.value.is_general_var(Interner, &receiver_ty.binders) {
1156        // don't try to resolve methods on unknown types
1157        return ControlFlow::Continue(());
1158    }
1159
1160    let mut iterate_method_candidates_by_receiver = move |receiver_ty, first_adjustment| {
1161        iterate_method_candidates_by_receiver(
1162            table,
1163            receiver_ty,
1164            first_adjustment,
1165            traits_in_scope,
1166            visible_from_module,
1167            name,
1168            callback,
1169        )
1170    };
1171
1172    let mut maybe_reborrowed = first_adjustment.clone();
1173    if let Some((_, _, m)) = receiver_ty.value.as_reference() {
1174        // Prefer reborrow of references to move
1175        maybe_reborrowed.autoref = Some(AutorefOrPtrAdjustment::Autoref(m));
1176        maybe_reborrowed.autoderefs += 1;
1177    }
1178
1179    iterate_method_candidates_by_receiver(receiver_ty.clone(), maybe_reborrowed)?;
1180
1181    let refed = Canonical {
1182        value: TyKind::Ref(Mutability::Not, error_lifetime(), receiver_ty.value.clone())
1183            .intern(Interner),
1184        binders: receiver_ty.binders.clone(),
1185    };
1186
1187    iterate_method_candidates_by_receiver(
1188        refed,
1189        first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Not)),
1190    )?;
1191
1192    let ref_muted = Canonical {
1193        value: TyKind::Ref(Mutability::Mut, error_lifetime(), receiver_ty.value.clone())
1194            .intern(Interner),
1195        binders: receiver_ty.binders.clone(),
1196    };
1197
1198    iterate_method_candidates_by_receiver(
1199        ref_muted,
1200        first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Mut)),
1201    )?;
1202
1203    if let Some((ty, Mutability::Mut)) = receiver_ty.value.as_raw_ptr() {
1204        let const_ptr_ty = Canonical {
1205            value: TyKind::Raw(Mutability::Not, ty.clone()).intern(Interner),
1206            binders: receiver_ty.binders,
1207        };
1208        iterate_method_candidates_by_receiver(
1209            const_ptr_ty,
1210            first_adjustment.with_autoref(AutorefOrPtrAdjustment::ToConstPtr),
1211        )?;
1212    }
1213
1214    ControlFlow::Continue(())
1215}
1216
1217pub trait MethodCandidateCallback {
1218    fn on_inherent_method(
1219        &mut self,
1220        adjustments: ReceiverAdjustments,
1221        item: AssocItemId,
1222        is_visible: bool,
1223    ) -> ControlFlow<()>;
1224
1225    fn on_trait_method(
1226        &mut self,
1227        adjustments: ReceiverAdjustments,
1228        item: AssocItemId,
1229        is_visible: bool,
1230    ) -> ControlFlow<()>;
1231}
1232
1233impl<F> MethodCandidateCallback for F
1234where
1235    F: FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1236{
1237    fn on_inherent_method(
1238        &mut self,
1239        adjustments: ReceiverAdjustments,
1240        item: AssocItemId,
1241        is_visible: bool,
1242    ) -> ControlFlow<()> {
1243        self(adjustments, item, is_visible)
1244    }
1245
1246    fn on_trait_method(
1247        &mut self,
1248        adjustments: ReceiverAdjustments,
1249        item: AssocItemId,
1250        is_visible: bool,
1251    ) -> ControlFlow<()> {
1252        self(adjustments, item, is_visible)
1253    }
1254}
1255
1256#[tracing::instrument(skip_all, fields(name = ?name))]
1257fn iterate_method_candidates_by_receiver(
1258    table: &mut InferenceTable<'_>,
1259    receiver_ty: Canonical<Ty>,
1260    receiver_adjustments: ReceiverAdjustments,
1261    traits_in_scope: &FxHashSet<TraitId>,
1262    visible_from_module: VisibleFromModule,
1263    name: Option<&Name>,
1264    callback: &mut dyn MethodCandidateCallback,
1265) -> ControlFlow<()> {
1266    let receiver_ty = table.instantiate_canonical(receiver_ty);
1267    // We're looking for methods with *receiver* type receiver_ty. These could
1268    // be found in any of the derefs of receiver_ty, so we have to go through
1269    // that, including raw derefs.
1270    table.run_in_snapshot(|table| {
1271        let mut autoderef =
1272            autoderef::Autoderef::new_no_tracking(table, receiver_ty.clone(), true, true);
1273        while let Some((self_ty, _)) = autoderef.next() {
1274            iterate_inherent_methods(
1275                &self_ty,
1276                autoderef.table,
1277                name,
1278                Some(&receiver_ty),
1279                Some(receiver_adjustments.clone()),
1280                visible_from_module,
1281                &mut |adjustments, item, is_visible| {
1282                    callback.on_inherent_method(adjustments, item, is_visible)
1283                },
1284            )?
1285        }
1286        ControlFlow::Continue(())
1287    })?;
1288    table.run_in_snapshot(|table| {
1289        let mut autoderef =
1290            autoderef::Autoderef::new_no_tracking(table, receiver_ty.clone(), true, true);
1291        while let Some((self_ty, _)) = autoderef.next() {
1292            if matches!(self_ty.kind(Interner), TyKind::InferenceVar(_, TyVariableKind::General)) {
1293                // don't try to resolve methods on unknown types
1294                return ControlFlow::Continue(());
1295            }
1296
1297            iterate_trait_method_candidates(
1298                &self_ty,
1299                autoderef.table,
1300                traits_in_scope,
1301                name,
1302                Some(&receiver_ty),
1303                Some(receiver_adjustments.clone()),
1304                &mut |adjustments, item, is_visible| {
1305                    callback.on_trait_method(adjustments, item, is_visible)
1306                },
1307            )?
1308        }
1309        ControlFlow::Continue(())
1310    })
1311}
1312
1313#[tracing::instrument(skip_all, fields(name = ?name))]
1314fn iterate_method_candidates_for_self_ty(
1315    self_ty: &Canonical<Ty>,
1316    db: &dyn HirDatabase,
1317    env: Arc<TraitEnvironment>,
1318    traits_in_scope: &FxHashSet<TraitId>,
1319    visible_from_module: VisibleFromModule,
1320    name: Option<&Name>,
1321    callback: &mut dyn MethodCandidateCallback,
1322) -> ControlFlow<()> {
1323    let mut table = InferenceTable::new(db, env);
1324    let self_ty = table.instantiate_canonical(self_ty.clone());
1325    iterate_inherent_methods(
1326        &self_ty,
1327        &mut table,
1328        name,
1329        None,
1330        None,
1331        visible_from_module,
1332        &mut |adjustments, item, is_visible| {
1333            callback.on_inherent_method(adjustments, item, is_visible)
1334        },
1335    )?;
1336    iterate_trait_method_candidates(
1337        &self_ty,
1338        &mut table,
1339        traits_in_scope,
1340        name,
1341        None,
1342        None,
1343        &mut |adjustments, item, is_visible| {
1344            callback.on_trait_method(adjustments, item, is_visible)
1345        },
1346    )
1347}
1348
1349#[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1350fn iterate_trait_method_candidates(
1351    self_ty: &Ty,
1352    table: &mut InferenceTable<'_>,
1353    traits_in_scope: &FxHashSet<TraitId>,
1354    name: Option<&Name>,
1355    receiver_ty: Option<&Ty>,
1356    receiver_adjustments: Option<ReceiverAdjustments>,
1357    callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1358) -> ControlFlow<()> {
1359    let db = table.db;
1360
1361    let canonical_self_ty = table.canonicalize(self_ty.clone());
1362    let TraitEnvironment { krate, block, .. } = *table.trait_env;
1363
1364    'traits: for &t in traits_in_scope {
1365        let data = db.trait_signature(t);
1366
1367        // Traits annotated with `#[rustc_skip_during_method_dispatch]` are skipped during
1368        // method resolution, if the receiver is an array, and we're compiling for editions before
1369        // 2021.
1370        // This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for
1371        // arrays.
1372        if data.flags.contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH)
1373            && matches!(self_ty.kind(Interner), TyKind::Array(..))
1374        {
1375            // FIXME: this should really be using the edition of the method name's span, in case it
1376            // comes from a macro
1377            if !krate.data(db).edition.at_least_2021() {
1378                continue;
1379            }
1380        }
1381        if data.flags.contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH)
1382            && matches!(
1383                self_ty.kind(Interner), TyKind::Adt(AdtId(def), subst)
1384                if is_box(table.db, *def)
1385                    && matches!(subst.at(Interner, 0).assert_ty_ref(Interner).kind(Interner), TyKind::Slice(..))
1386            )
1387        {
1388            // FIXME: this should really be using the edition of the method name's span, in case it
1389            // comes from a macro
1390            if !krate.data(db).edition.at_least_2024() {
1391                continue;
1392            }
1393        }
1394
1395        // we'll be lazy about checking whether the type implements the
1396        // trait, but if we find out it doesn't, we'll skip the rest of the
1397        // iteration
1398        let mut known_implemented = false;
1399        for &(_, item) in t.trait_items(db).items.iter() {
1400            // Don't pass a `visible_from_module` down to `is_valid_candidate`,
1401            // since only inherent methods should be included into visibility checking.
1402            let visible =
1403                match is_valid_trait_method_candidate(table, t, name, receiver_ty, item, self_ty) {
1404                    IsValidCandidate::Yes => true,
1405                    IsValidCandidate::NotVisible => false,
1406                    IsValidCandidate::No => continue,
1407                };
1408            if !known_implemented {
1409                let goal = generic_implements_goal(db, &table.trait_env, t, &canonical_self_ty);
1410                if db.trait_solve(krate, block, goal.cast(Interner)).no_solution() {
1411                    continue 'traits;
1412                }
1413            }
1414            known_implemented = true;
1415            callback(receiver_adjustments.clone().unwrap_or_default(), item, visible)?;
1416        }
1417    }
1418    ControlFlow::Continue(())
1419}
1420
1421#[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1422fn iterate_inherent_methods(
1423    self_ty: &Ty,
1424    table: &mut InferenceTable<'_>,
1425    name: Option<&Name>,
1426    receiver_ty: Option<&Ty>,
1427    receiver_adjustments: Option<ReceiverAdjustments>,
1428    visible_from_module: VisibleFromModule,
1429    callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1430) -> ControlFlow<()> {
1431    let db = table.db;
1432    let env = table.trait_env.clone();
1433
1434    // For trait object types and placeholder types with trait bounds, the methods of the trait and
1435    // its super traits are considered inherent methods. This matters because these methods have
1436    // higher priority than the other traits' methods, which would be considered in
1437    // `iterate_trait_method_candidates()` only after this function.
1438    match self_ty.kind(Interner) {
1439        TyKind::Placeholder(_) => {
1440            let env = table.trait_env.clone();
1441            let traits = env
1442                .traits_in_scope_from_clauses(self_ty.clone())
1443                .flat_map(|t| all_super_traits(db, t));
1444            iterate_inherent_trait_methods(
1445                self_ty,
1446                table,
1447                name,
1448                receiver_ty,
1449                receiver_adjustments.clone(),
1450                callback,
1451                traits,
1452            )?;
1453        }
1454        TyKind::Dyn(_) => {
1455            if let Some(principal_trait) = self_ty.dyn_trait() {
1456                let traits = all_super_traits(db, principal_trait);
1457                iterate_inherent_trait_methods(
1458                    self_ty,
1459                    table,
1460                    name,
1461                    receiver_ty,
1462                    receiver_adjustments.clone(),
1463                    callback,
1464                    traits.into_iter(),
1465                )?;
1466            }
1467        }
1468        _ => {}
1469    }
1470
1471    let def_crates = match def_crates(db, self_ty, env.krate) {
1472        Some(k) => k,
1473        None => return ControlFlow::Continue(()),
1474    };
1475
1476    let (module, mut block) = match visible_from_module {
1477        VisibleFromModule::Filter(module) => (Some(module), module.containing_block()),
1478        VisibleFromModule::IncludeBlock(block) => (None, Some(block)),
1479        VisibleFromModule::None => (None, None),
1480    };
1481
1482    while let Some(block_id) = block {
1483        if let Some(impls) = db.inherent_impls_in_block(block_id) {
1484            impls_for_self_ty(
1485                &impls,
1486                self_ty,
1487                table,
1488                name,
1489                receiver_ty,
1490                receiver_adjustments.clone(),
1491                module,
1492                callback,
1493            )?;
1494        }
1495
1496        block = block_def_map(db, block_id).parent().and_then(|module| module.containing_block());
1497    }
1498
1499    for krate in def_crates {
1500        let impls = db.inherent_impls_in_crate(krate);
1501        impls_for_self_ty(
1502            &impls,
1503            self_ty,
1504            table,
1505            name,
1506            receiver_ty,
1507            receiver_adjustments.clone(),
1508            module,
1509            callback,
1510        )?;
1511    }
1512    return ControlFlow::Continue(());
1513
1514    #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1515    fn iterate_inherent_trait_methods(
1516        self_ty: &Ty,
1517        table: &mut InferenceTable<'_>,
1518        name: Option<&Name>,
1519        receiver_ty: Option<&Ty>,
1520        receiver_adjustments: Option<ReceiverAdjustments>,
1521        callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1522        traits: impl Iterator<Item = TraitId>,
1523    ) -> ControlFlow<()> {
1524        let db = table.db;
1525        for t in traits {
1526            let data = t.trait_items(db);
1527            for &(_, item) in data.items.iter() {
1528                // We don't pass `visible_from_module` as all trait items should be visible.
1529                let visible = match is_valid_trait_method_candidate(
1530                    table,
1531                    t,
1532                    name,
1533                    receiver_ty,
1534                    item,
1535                    self_ty,
1536                ) {
1537                    IsValidCandidate::Yes => true,
1538                    IsValidCandidate::NotVisible => false,
1539                    IsValidCandidate::No => continue,
1540                };
1541                callback(receiver_adjustments.clone().unwrap_or_default(), item, visible)?;
1542            }
1543        }
1544        ControlFlow::Continue(())
1545    }
1546
1547    #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1548    fn impls_for_self_ty(
1549        impls: &InherentImpls,
1550        self_ty: &Ty,
1551        table: &mut InferenceTable<'_>,
1552        name: Option<&Name>,
1553        receiver_ty: Option<&Ty>,
1554        receiver_adjustments: Option<ReceiverAdjustments>,
1555        visible_from_module: Option<ModuleId>,
1556        callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1557    ) -> ControlFlow<()> {
1558        for &impl_id in impls.for_self_ty(self_ty) {
1559            for &(ref item_name, item) in impl_id.impl_items(table.db).items.iter() {
1560                let visible = match is_valid_impl_method_candidate(
1561                    table,
1562                    self_ty,
1563                    receiver_ty,
1564                    visible_from_module,
1565                    name,
1566                    impl_id,
1567                    item,
1568                    item_name,
1569                ) {
1570                    IsValidCandidate::Yes => true,
1571                    IsValidCandidate::NotVisible => false,
1572                    IsValidCandidate::No => continue,
1573                };
1574                callback(receiver_adjustments.clone().unwrap_or_default(), item, visible)?;
1575            }
1576        }
1577        ControlFlow::Continue(())
1578    }
1579}
1580
1581/// Returns the receiver type for the index trait call.
1582pub(crate) fn resolve_indexing_op(
1583    db: &dyn HirDatabase,
1584    env: Arc<TraitEnvironment>,
1585    ty: Canonical<Ty>,
1586    index_trait: TraitId,
1587) -> Option<ReceiverAdjustments> {
1588    let mut table = InferenceTable::new(db, env);
1589    let ty = table.instantiate_canonical(ty);
1590    let deref_chain = autoderef_method_receiver(&mut table, ty);
1591    for (ty, adj) in deref_chain {
1592        let goal = generic_implements_goal(db, &table.trait_env, index_trait, &ty);
1593        if !db
1594            .trait_solve(table.trait_env.krate, table.trait_env.block, goal.cast(Interner))
1595            .no_solution()
1596        {
1597            return Some(adj);
1598        }
1599    }
1600    None
1601}
1602
1603// FIXME: Replace this with a `Try` impl once stable
1604macro_rules! check_that {
1605    ($cond:expr) => {
1606        if !$cond {
1607            return IsValidCandidate::No;
1608        }
1609    };
1610}
1611
1612#[derive(Debug)]
1613enum IsValidCandidate {
1614    Yes,
1615    No,
1616    NotVisible,
1617}
1618
1619#[tracing::instrument(skip_all, fields(name))]
1620fn is_valid_impl_method_candidate(
1621    table: &mut InferenceTable<'_>,
1622    self_ty: &Ty,
1623    receiver_ty: Option<&Ty>,
1624    visible_from_module: Option<ModuleId>,
1625    name: Option<&Name>,
1626    impl_id: ImplId,
1627    item: AssocItemId,
1628    item_name: &Name,
1629) -> IsValidCandidate {
1630    match item {
1631        AssocItemId::FunctionId(f) => is_valid_impl_fn_candidate(
1632            table,
1633            impl_id,
1634            f,
1635            name,
1636            receiver_ty,
1637            self_ty,
1638            visible_from_module,
1639            item_name,
1640        ),
1641        AssocItemId::ConstId(c) => {
1642            let db = table.db;
1643            check_that!(receiver_ty.is_none());
1644            check_that!(name.is_none_or(|n| n == item_name));
1645
1646            if let Some(from_module) = visible_from_module
1647                && !db.assoc_visibility(c.into()).is_visible_from(db, from_module)
1648            {
1649                cov_mark::hit!(const_candidate_not_visible);
1650                return IsValidCandidate::NotVisible;
1651            }
1652            let self_ty_matches = table.run_in_snapshot(|table| {
1653                let expected_self_ty =
1654                    TyBuilder::impl_self_ty(db, impl_id).fill_with_inference_vars(table).build();
1655                table.unify(&expected_self_ty, self_ty)
1656            });
1657            if !self_ty_matches {
1658                cov_mark::hit!(const_candidate_self_type_mismatch);
1659                return IsValidCandidate::No;
1660            }
1661            IsValidCandidate::Yes
1662        }
1663        _ => IsValidCandidate::No,
1664    }
1665}
1666
1667/// Checks whether a given `AssocItemId` is applicable for `receiver_ty`.
1668#[tracing::instrument(skip_all, fields(name))]
1669fn is_valid_trait_method_candidate(
1670    table: &mut InferenceTable<'_>,
1671    trait_id: TraitId,
1672    name: Option<&Name>,
1673    receiver_ty: Option<&Ty>,
1674    item: AssocItemId,
1675    self_ty: &Ty,
1676) -> IsValidCandidate {
1677    let db = table.db;
1678    match item {
1679        AssocItemId::FunctionId(fn_id) => {
1680            let data = db.function_signature(fn_id);
1681
1682            check_that!(name.is_none_or(|n| n == &data.name));
1683
1684            table.run_in_snapshot(|table| {
1685                let impl_subst = TyBuilder::subst_for_def(db, trait_id, None)
1686                    .fill_with_inference_vars(table)
1687                    .build();
1688                let expect_self_ty = impl_subst.at(Interner, 0).assert_ty_ref(Interner).clone();
1689
1690                check_that!(table.unify(&expect_self_ty, self_ty));
1691
1692                if let Some(receiver_ty) = receiver_ty {
1693                    check_that!(data.has_self_param());
1694
1695                    let fn_subst = TyBuilder::subst_for_def(db, fn_id, Some(impl_subst))
1696                        .fill_with_inference_vars(table)
1697                        .build();
1698
1699                    let sig = db.callable_item_signature(fn_id.into());
1700                    let expected_receiver =
1701                        sig.map(|s| s.params()[0].clone()).substitute(Interner, &fn_subst);
1702
1703                    check_that!(table.unify(receiver_ty, &expected_receiver));
1704                }
1705
1706                IsValidCandidate::Yes
1707            })
1708        }
1709        AssocItemId::ConstId(c) => {
1710            check_that!(receiver_ty.is_none());
1711            check_that!(name.is_none_or(|n| db.const_signature(c).name.as_ref() == Some(n)));
1712
1713            IsValidCandidate::Yes
1714        }
1715        _ => IsValidCandidate::No,
1716    }
1717}
1718
1719#[tracing::instrument(skip_all, fields(name))]
1720fn is_valid_impl_fn_candidate(
1721    table: &mut InferenceTable<'_>,
1722    impl_id: ImplId,
1723    fn_id: FunctionId,
1724    name: Option<&Name>,
1725    receiver_ty: Option<&Ty>,
1726    self_ty: &Ty,
1727    visible_from_module: Option<ModuleId>,
1728    item_name: &Name,
1729) -> IsValidCandidate {
1730    check_that!(name.is_none_or(|n| n == item_name));
1731
1732    let db = table.db;
1733    let data = db.function_signature(fn_id);
1734
1735    if let Some(from_module) = visible_from_module
1736        && !db.assoc_visibility(fn_id.into()).is_visible_from(db, from_module)
1737    {
1738        cov_mark::hit!(autoderef_candidate_not_visible);
1739        return IsValidCandidate::NotVisible;
1740    }
1741    table.run_in_snapshot(|table| {
1742        let _p = tracing::info_span!("subst_for_def").entered();
1743        let impl_subst =
1744            TyBuilder::subst_for_def(db, impl_id, None).fill_with_inference_vars(table).build();
1745        let expect_self_ty = db.impl_self_ty(impl_id).substitute(Interner, &impl_subst);
1746
1747        check_that!(table.unify(&expect_self_ty, self_ty));
1748
1749        if let Some(receiver_ty) = receiver_ty {
1750            let _p = tracing::info_span!("check_receiver_ty").entered();
1751            check_that!(data.has_self_param());
1752
1753            let fn_subst = TyBuilder::subst_for_def(db, fn_id, Some(impl_subst.clone()))
1754                .fill_with_inference_vars(table)
1755                .build();
1756
1757            let sig = db.callable_item_signature(fn_id.into());
1758            let expected_receiver =
1759                sig.map(|s| s.params()[0].clone()).substitute(Interner, &fn_subst);
1760
1761            check_that!(table.unify(receiver_ty, &expected_receiver));
1762        }
1763
1764        // We need to consider the bounds on the impl to distinguish functions of the same name
1765        // for a type.
1766        let predicates = db.generic_predicates(impl_id.into());
1767        let goals = predicates.iter().map(|p| {
1768            let (p, b) = p
1769                .clone()
1770                .substitute(Interner, &impl_subst)
1771                // Skipping the inner binders is ok, as we don't handle quantified where
1772                // clauses yet.
1773                .into_value_and_skipped_binders();
1774            stdx::always!(b.len(Interner) == 0);
1775
1776            p.cast::<Goal>(Interner)
1777        });
1778
1779        for goal in goals.clone() {
1780            let in_env = InEnvironment::new(&table.trait_env.env, goal);
1781            let canonicalized = table.canonicalize_with_free_vars(in_env);
1782            let solution = table.db.trait_solve(
1783                table.trait_env.krate,
1784                table.trait_env.block,
1785                canonicalized.value.clone(),
1786            );
1787
1788            match solution {
1789                NextTraitSolveResult::Certain(canonical_subst) => {
1790                    canonicalized.apply_solution(
1791                        table,
1792                        Canonical {
1793                            binders: canonical_subst.binders,
1794                            value: canonical_subst.value.subst,
1795                        },
1796                    );
1797                }
1798                NextTraitSolveResult::Uncertain(..) => {}
1799                NextTraitSolveResult::NoSolution => return IsValidCandidate::No,
1800            }
1801        }
1802
1803        for goal in goals {
1804            if table.try_obligation(goal).no_solution() {
1805                return IsValidCandidate::No;
1806            }
1807        }
1808
1809        IsValidCandidate::Yes
1810    })
1811}
1812
1813pub fn implements_trait(
1814    ty: &Canonical<Ty>,
1815    db: &dyn HirDatabase,
1816    env: &TraitEnvironment,
1817    trait_: TraitId,
1818) -> bool {
1819    let goal = generic_implements_goal(db, env, trait_, ty);
1820    !db.trait_solve(env.krate, env.block, goal.cast(Interner)).no_solution()
1821}
1822
1823pub fn implements_trait_unique(
1824    ty: &Canonical<Ty>,
1825    db: &dyn HirDatabase,
1826    env: &TraitEnvironment,
1827    trait_: TraitId,
1828) -> bool {
1829    let goal = generic_implements_goal(db, env, trait_, ty);
1830    db.trait_solve(env.krate, env.block, goal.cast(Interner)).certain()
1831}
1832
1833/// This creates Substs for a trait with the given Self type and type variables
1834/// for all other parameters, to query Chalk with it.
1835#[tracing::instrument(skip_all)]
1836fn generic_implements_goal(
1837    db: &dyn HirDatabase,
1838    env: &TraitEnvironment,
1839    trait_: TraitId,
1840    self_ty: &Canonical<Ty>,
1841) -> Canonical<InEnvironment<super::DomainGoal>> {
1842    let binders = self_ty.binders.interned();
1843    let trait_ref = TyBuilder::trait_ref(db, trait_)
1844        .push(self_ty.value.clone())
1845        .fill_with_bound_vars(DebruijnIndex::INNERMOST, binders.len())
1846        .build();
1847
1848    let kinds =
1849        binders.iter().cloned().chain(trait_ref.substitution.iter(Interner).skip(1).map(|it| {
1850            let vk = match it.data(Interner) {
1851                GenericArgData::Ty(_) => VariableKind::Ty(chalk_ir::TyVariableKind::General),
1852                GenericArgData::Lifetime(_) => VariableKind::Lifetime,
1853                GenericArgData::Const(c) => VariableKind::Const(c.data(Interner).ty.clone()),
1854            };
1855            WithKind::new(vk, UniverseIndex::ROOT)
1856        }));
1857    let binders = CanonicalVarKinds::from_iter(Interner, kinds);
1858
1859    let obligation = trait_ref.cast(Interner);
1860    let value = InEnvironment::new(&env.env, obligation);
1861    Canonical { binders, value }
1862}
1863
1864fn autoderef_method_receiver(
1865    table: &mut InferenceTable<'_>,
1866    ty: Ty,
1867) -> Vec<(Canonical<Ty>, ReceiverAdjustments)> {
1868    let mut deref_chain: Vec<_> = Vec::new();
1869    let mut autoderef = autoderef::Autoderef::new_no_tracking(table, ty, false, true);
1870    while let Some((ty, derefs)) = autoderef.next() {
1871        deref_chain.push((
1872            autoderef.table.canonicalize(ty),
1873            ReceiverAdjustments { autoref: None, autoderefs: derefs, unsize_array: false },
1874        ));
1875    }
1876    // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
1877    if let Some((TyKind::Array(parameters, _), binders, adj)) =
1878        deref_chain.last().map(|(ty, adj)| (ty.value.kind(Interner), ty.binders.clone(), adj))
1879    {
1880        let unsized_ty = TyKind::Slice(parameters.clone()).intern(Interner);
1881        deref_chain.push((
1882            Canonical { value: unsized_ty, binders },
1883            ReceiverAdjustments { unsize_array: true, ..adj.clone() },
1884        ));
1885    }
1886    deref_chain
1887}