• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
5 use std::ops::ControlFlow;
6 
7 use base_db::{CrateId, Edition};
8 use chalk_ir::{cast::Cast, Mutability, TyKind, UniverseIndex, WhereClause};
9 use hir_def::{
10     data::{adt::StructFlags, ImplData},
11     item_scope::ItemScope,
12     nameres::DefMap,
13     AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup,
14     ModuleDefId, ModuleId, TraitId,
15 };
16 use hir_expand::name::Name;
17 use rustc_hash::{FxHashMap, FxHashSet};
18 use smallvec::{smallvec, SmallVec};
19 use stdx::never;
20 use triomphe::Arc;
21 
22 use crate::{
23     autoderef::{self, AutoderefKind},
24     db::HirDatabase,
25     from_chalk_trait_id, from_foreign_def_id,
26     infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast},
27     primitive::{FloatTy, IntTy, UintTy},
28     static_lifetime, to_chalk_trait_id,
29     utils::all_super_traits,
30     AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, InEnvironment,
31     Interner, Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt,
32 };
33 
34 /// This is used as a key for indexing impls.
35 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
36 pub enum TyFingerprint {
37     // These are lang item impls:
38     Str,
39     Slice,
40     Array,
41     Never,
42     RawPtr(Mutability),
43     Scalar(Scalar),
44     // These can have user-defined impls:
45     Adt(hir_def::AdtId),
46     Dyn(TraitId),
47     ForeignType(ForeignDefId),
48     // These only exist for trait impls
49     Unit,
50     Unnameable,
51     Function(u32),
52 }
53 
54 impl TyFingerprint {
55     /// Creates a TyFingerprint for looking up an inherent impl. Only certain
56     /// types can have inherent impls: if we have some `struct S`, we can have
57     /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
58     /// reference types and such.
for_inherent_impl(ty: &Ty) -> Option<TyFingerprint>59     pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
60         let fp = match ty.kind(Interner) {
61             TyKind::Str => TyFingerprint::Str,
62             TyKind::Never => TyFingerprint::Never,
63             TyKind::Slice(..) => TyFingerprint::Slice,
64             TyKind::Array(..) => TyFingerprint::Array,
65             TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
66             TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
67             TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
68             TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
69             TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
70             _ => return None,
71         };
72         Some(fp)
73     }
74 
75     /// Creates a TyFingerprint for looking up a trait impl.
for_trait_impl(ty: &Ty) -> Option<TyFingerprint>76     pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> {
77         let fp = match ty.kind(Interner) {
78             TyKind::Str => TyFingerprint::Str,
79             TyKind::Never => TyFingerprint::Never,
80             TyKind::Slice(..) => TyFingerprint::Slice,
81             TyKind::Array(..) => TyFingerprint::Array,
82             TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
83             TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
84             TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
85             TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
86             TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
87             TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty),
88             TyKind::Tuple(_, subst) => {
89                 let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(Interner));
90                 match first_ty {
91                     Some(ty) => return TyFingerprint::for_trait_impl(ty),
92                     None => TyFingerprint::Unit,
93                 }
94             }
95             TyKind::AssociatedType(_, _)
96             | TyKind::OpaqueType(_, _)
97             | TyKind::FnDef(_, _)
98             | TyKind::Closure(_, _)
99             | TyKind::Generator(..)
100             | TyKind::GeneratorWitness(..) => TyFingerprint::Unnameable,
101             TyKind::Function(fn_ptr) => {
102                 TyFingerprint::Function(fn_ptr.substitution.0.len(Interner) as u32)
103             }
104             TyKind::Alias(_)
105             | TyKind::Placeholder(_)
106             | TyKind::BoundVar(_)
107             | TyKind::InferenceVar(_, _)
108             | TyKind::Error => return None,
109         };
110         Some(fp)
111     }
112 }
113 
114 pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
115     TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
116     TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
117     TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
118     TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
119     TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
120     TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
121     TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
122     TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
123     TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
124     TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
125     TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
126     TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
127 ];
128 
129 pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
130     TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
131     TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
132 ];
133 
134 /// Trait impls defined or available in some crate.
135 #[derive(Debug, Eq, PartialEq)]
136 pub struct TraitImpls {
137     // If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type.
138     map: FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>,
139 }
140 
141 impl TraitImpls {
trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self>142     pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
143         let _p = profile::span("trait_impls_in_crate_query").detail(|| format!("{krate:?}"));
144         let mut impls = Self { map: FxHashMap::default() };
145 
146         let crate_def_map = db.crate_def_map(krate);
147         impls.collect_def_map(db, &crate_def_map);
148         impls.shrink_to_fit();
149 
150         Arc::new(impls)
151     }
152 
trait_impls_in_block_query(db: &dyn HirDatabase, block: BlockId) -> Arc<Self>153     pub(crate) fn trait_impls_in_block_query(db: &dyn HirDatabase, block: BlockId) -> Arc<Self> {
154         let _p = profile::span("trait_impls_in_block_query");
155         let mut impls = Self { map: FxHashMap::default() };
156 
157         let block_def_map = db.block_def_map(block);
158         impls.collect_def_map(db, &block_def_map);
159         impls.shrink_to_fit();
160 
161         Arc::new(impls)
162     }
163 
trait_impls_in_deps_query( db: &dyn HirDatabase, krate: CrateId, ) -> Arc<[Arc<Self>]>164     pub(crate) fn trait_impls_in_deps_query(
165         db: &dyn HirDatabase,
166         krate: CrateId,
167     ) -> Arc<[Arc<Self>]> {
168         let _p = profile::span("trait_impls_in_deps_query").detail(|| format!("{krate:?}"));
169         let crate_graph = db.crate_graph();
170         // FIXME: use `Arc::from_iter` when it becomes available
171         Arc::from(
172             crate_graph
173                 .transitive_deps(krate)
174                 .map(|krate| db.trait_impls_in_crate(krate))
175                 .collect::<Vec<_>>(),
176         )
177     }
178 
shrink_to_fit(&mut self)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 
collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap)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                 // Reservation impls should be ignored during trait resolution, so we never need
191                 // them during type analysis. See rust-lang/rust#64631 for details.
192                 //
193                 // FIXME: Reservation impls should be considered during coherence checks. If we are
194                 // (ever) to implement coherence checks, this filtering should be done by the trait
195                 // solver.
196                 if db.attrs(impl_id.into()).by_key("rustc_reservation_impl").exists() {
197                     continue;
198                 }
199                 let target_trait = match db.impl_trait(impl_id) {
200                     Some(tr) => tr.skip_binders().hir_trait_id(),
201                     None => continue,
202                 };
203                 let self_ty = db.impl_self_ty(impl_id);
204                 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
205                 self.map
206                     .entry(target_trait)
207                     .or_default()
208                     .entry(self_ty_fp)
209                     .or_default()
210                     .push(impl_id);
211             }
212 
213             // To better support custom derives, collect impls in all unnamed const items.
214             // const _: () = { ... };
215             for konst in collect_unnamed_consts(db, &module_data.scope) {
216                 let body = db.body(konst.into());
217                 for (_, block_def_map) in body.blocks(db.upcast()) {
218                     self.collect_def_map(db, &block_def_map);
219                 }
220             }
221         }
222     }
223 
224     /// Queries all trait impls for the given type.
for_self_ty_without_blanket_impls( &self, fp: TyFingerprint, ) -> impl Iterator<Item = ImplId> + '_225     pub fn for_self_ty_without_blanket_impls(
226         &self,
227         fp: TyFingerprint,
228     ) -> impl Iterator<Item = ImplId> + '_ {
229         self.map
230             .values()
231             .flat_map(move |impls| impls.get(&Some(fp)).into_iter())
232             .flat_map(|it| it.iter().copied())
233     }
234 
235     /// Queries all impls of the given trait.
for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_236     pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ {
237         self.map
238             .get(&trait_)
239             .into_iter()
240             .flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
241     }
242 
243     /// Queries all impls of `trait_` that may apply to `self_ty`.
for_trait_and_self_ty( &self, trait_: TraitId, self_ty: TyFingerprint, ) -> impl Iterator<Item = ImplId> + '_244     pub fn for_trait_and_self_ty(
245         &self,
246         trait_: TraitId,
247         self_ty: TyFingerprint,
248     ) -> impl Iterator<Item = ImplId> + '_ {
249         self.map
250             .get(&trait_)
251             .into_iter()
252             .flat_map(move |map| map.get(&Some(self_ty)).into_iter().chain(map.get(&None)))
253             .flat_map(|v| v.iter().copied())
254     }
255 
all_impls(&self) -> impl Iterator<Item = ImplId> + '_256     pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
257         self.map.values().flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
258     }
259 }
260 
261 /// Inherent impls defined in some crate.
262 ///
263 /// Inherent impls can only be defined in the crate that also defines the self type of the impl
264 /// (note that some primitives are considered to be defined by both libcore and liballoc).
265 ///
266 /// This makes inherent impl lookup easier than trait impl lookup since we only have to consider a
267 /// single crate.
268 #[derive(Debug, Eq, PartialEq)]
269 pub struct InherentImpls {
270     map: FxHashMap<TyFingerprint, Vec<ImplId>>,
271     invalid_impls: Vec<ImplId>,
272 }
273 
274 impl InherentImpls {
inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self>275     pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
276         let _p = profile::span("inherent_impls_in_crate_query").detail(|| format!("{krate:?}"));
277         let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() };
278 
279         let crate_def_map = db.crate_def_map(krate);
280         impls.collect_def_map(db, &crate_def_map);
281         impls.shrink_to_fit();
282 
283         Arc::new(impls)
284     }
285 
inherent_impls_in_block_query(db: &dyn HirDatabase, block: BlockId) -> Arc<Self>286     pub(crate) fn inherent_impls_in_block_query(db: &dyn HirDatabase, block: BlockId) -> Arc<Self> {
287         let _p = profile::span("inherent_impls_in_block_query");
288         let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() };
289 
290         let block_def_map = db.block_def_map(block);
291         impls.collect_def_map(db, &block_def_map);
292         impls.shrink_to_fit();
293 
294         Arc::new(impls)
295     }
296 
shrink_to_fit(&mut self)297     fn shrink_to_fit(&mut self) {
298         self.map.values_mut().for_each(Vec::shrink_to_fit);
299         self.map.shrink_to_fit();
300     }
301 
collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap)302     fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
303         for (_module_id, module_data) in def_map.modules() {
304             for impl_id in module_data.scope.impls() {
305                 let data = db.impl_data(impl_id);
306                 if data.target_trait.is_some() {
307                     continue;
308                 }
309 
310                 let self_ty = db.impl_self_ty(impl_id);
311                 let self_ty = self_ty.skip_binders();
312 
313                 match is_inherent_impl_coherent(db, def_map, &data, self_ty) {
314                     true => {
315                         // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
316                         if let Some(fp) = TyFingerprint::for_inherent_impl(self_ty) {
317                             self.map.entry(fp).or_default().push(impl_id);
318                         }
319                     }
320                     false => self.invalid_impls.push(impl_id),
321                 }
322             }
323 
324             // To better support custom derives, collect impls in all unnamed const items.
325             // const _: () = { ... };
326             for konst in collect_unnamed_consts(db, &module_data.scope) {
327                 let body = db.body(konst.into());
328                 for (_, block_def_map) in body.blocks(db.upcast()) {
329                     self.collect_def_map(db, &block_def_map);
330                 }
331             }
332         }
333     }
334 
for_self_ty(&self, self_ty: &Ty) -> &[ImplId]335     pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
336         match TyFingerprint::for_inherent_impl(self_ty) {
337             Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
338             None => &[],
339         }
340     }
341 
all_impls(&self) -> impl Iterator<Item = ImplId> + '_342     pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
343         self.map.values().flat_map(|v| v.iter().copied())
344     }
345 
invalid_impls(&self) -> &[ImplId]346     pub fn invalid_impls(&self) -> &[ImplId] {
347         &self.invalid_impls
348     }
349 }
350 
incoherent_inherent_impl_crates( db: &dyn HirDatabase, krate: CrateId, fp: TyFingerprint, ) -> SmallVec<[CrateId; 2]>351 pub(crate) fn incoherent_inherent_impl_crates(
352     db: &dyn HirDatabase,
353     krate: CrateId,
354     fp: TyFingerprint,
355 ) -> SmallVec<[CrateId; 2]> {
356     let _p = profile::span("inherent_impl_crates_query");
357     let mut res = SmallVec::new();
358     let crate_graph = db.crate_graph();
359 
360     // should pass crate for finger print and do reverse deps
361 
362     for krate in crate_graph.transitive_deps(krate) {
363         let impls = db.inherent_impls_in_crate(krate);
364         if impls.map.get(&fp).map_or(false, |v| !v.is_empty()) {
365             res.push(krate);
366         }
367     }
368 
369     res
370 }
371 
collect_unnamed_consts<'a>( db: &'a dyn HirDatabase, scope: &'a ItemScope, ) -> impl Iterator<Item = ConstId> + 'a372 fn collect_unnamed_consts<'a>(
373     db: &'a dyn HirDatabase,
374     scope: &'a ItemScope,
375 ) -> impl Iterator<Item = ConstId> + 'a {
376     let unnamed_consts = scope.unnamed_consts();
377 
378     // FIXME: Also treat consts named `_DERIVE_*` as unnamed, since synstructure generates those.
379     // Should be removed once synstructure stops doing that.
380     let synstructure_hack_consts = scope.values().filter_map(|(item, _)| match item {
381         ModuleDefId::ConstId(id) => {
382             let loc = id.lookup(db.upcast());
383             let item_tree = loc.id.item_tree(db.upcast());
384             if item_tree[loc.id.value]
385                 .name
386                 .as_ref()
387                 .map_or(false, |n| n.to_smol_str().starts_with("_DERIVE_"))
388             {
389                 Some(id)
390             } else {
391                 None
392             }
393         }
394         _ => None,
395     });
396 
397     unnamed_consts.chain(synstructure_hack_consts)
398 }
399 
def_crates( db: &dyn HirDatabase, ty: &Ty, cur_crate: CrateId, ) -> Option<SmallVec<[CrateId; 2]>>400 pub fn def_crates(
401     db: &dyn HirDatabase,
402     ty: &Ty,
403     cur_crate: CrateId,
404 ) -> Option<SmallVec<[CrateId; 2]>> {
405     match ty.kind(Interner) {
406         &TyKind::Adt(AdtId(def_id), _) => {
407             let rustc_has_incoherent_inherent_impls = match def_id {
408                 hir_def::AdtId::StructId(id) => db
409                     .struct_data(id)
410                     .flags
411                     .contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
412                 hir_def::AdtId::UnionId(id) => db
413                     .union_data(id)
414                     .flags
415                     .contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
416                 hir_def::AdtId::EnumId(id) => db.enum_data(id).rustc_has_incoherent_inherent_impls,
417             };
418             Some(if rustc_has_incoherent_inherent_impls {
419                 db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Adt(def_id))
420             } else {
421                 smallvec![def_id.module(db.upcast()).krate()]
422             })
423         }
424         &TyKind::Foreign(id) => {
425             let alias = from_foreign_def_id(id);
426             Some(if db.type_alias_data(alias).rustc_has_incoherent_inherent_impls {
427                 db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(id))
428             } else {
429                 smallvec![alias.module(db.upcast()).krate()]
430             })
431         }
432         TyKind::Dyn(_) => {
433             let trait_id = ty.dyn_trait()?;
434             Some(if db.trait_data(trait_id).rustc_has_incoherent_inherent_impls {
435                 db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Dyn(trait_id))
436             } else {
437                 smallvec![trait_id.module(db.upcast()).krate()]
438             })
439         }
440         // for primitives, there may be impls in various places (core and alloc
441         // mostly). We just check the whole crate graph for crates with impls
442         // (cached behind a query).
443         TyKind::Scalar(_)
444         | TyKind::Str
445         | TyKind::Slice(_)
446         | TyKind::Array(..)
447         | TyKind::Raw(..) => Some(db.incoherent_inherent_impl_crates(
448             cur_crate,
449             TyFingerprint::for_inherent_impl(ty).expect("fingerprint for primitive"),
450         )),
451         _ => None,
452     }
453 }
454 
455 /// Look up the method with the given name.
lookup_method( db: &dyn HirDatabase, ty: &Canonical<Ty>, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: &Name, ) -> Option<(ReceiverAdjustments, FunctionId, bool)>456 pub(crate) fn lookup_method(
457     db: &dyn HirDatabase,
458     ty: &Canonical<Ty>,
459     env: Arc<TraitEnvironment>,
460     traits_in_scope: &FxHashSet<TraitId>,
461     visible_from_module: VisibleFromModule,
462     name: &Name,
463 ) -> Option<(ReceiverAdjustments, FunctionId, bool)> {
464     let mut not_visible = None;
465     let res = iterate_method_candidates(
466         ty,
467         db,
468         env,
469         traits_in_scope,
470         visible_from_module,
471         Some(name),
472         LookupMode::MethodCall,
473         |adjustments, f, visible| match f {
474             AssocItemId::FunctionId(f) if visible => Some((adjustments, f, true)),
475             AssocItemId::FunctionId(f) if not_visible.is_none() => {
476                 not_visible = Some((adjustments, f, false));
477                 None
478             }
479             _ => None,
480         },
481     );
482     res.or(not_visible)
483 }
484 
485 /// Whether we're looking up a dotted method call (like `v.len()`) or a path
486 /// (like `Vec::new`).
487 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
488 pub enum LookupMode {
489     /// Looking up a method call like `v.len()`: We only consider candidates
490     /// that have a `self` parameter, and do autoderef.
491     MethodCall,
492     /// Looking up a path like `Vec::new` or `Vec::default`: We consider all
493     /// candidates including associated constants, but don't do autoderef.
494     Path,
495 }
496 
497 #[derive(Clone, Copy)]
498 pub enum VisibleFromModule {
499     /// Filter for results that are visible from the given module
500     Filter(ModuleId),
501     /// Include impls from the given block.
502     IncludeBlock(BlockId),
503     /// Do nothing special in regards visibility
504     None,
505 }
506 
507 impl From<Option<ModuleId>> for VisibleFromModule {
from(module: Option<ModuleId>) -> Self508     fn from(module: Option<ModuleId>) -> Self {
509         match module {
510             Some(module) => Self::Filter(module),
511             None => Self::None,
512         }
513     }
514 }
515 
516 impl From<Option<BlockId>> for VisibleFromModule {
from(block: Option<BlockId>) -> Self517     fn from(block: Option<BlockId>) -> Self {
518         match block {
519             Some(block) => Self::IncludeBlock(block),
520             None => Self::None,
521         }
522     }
523 }
524 
525 #[derive(Debug, Clone, Default)]
526 pub struct ReceiverAdjustments {
527     autoref: Option<Mutability>,
528     autoderefs: usize,
529     unsize_array: bool,
530 }
531 
532 impl ReceiverAdjustments {
apply(&self, table: &mut InferenceTable<'_>, ty: Ty) -> (Ty, Vec<Adjustment>)533     pub(crate) fn apply(&self, table: &mut InferenceTable<'_>, ty: Ty) -> (Ty, Vec<Adjustment>) {
534         let mut ty = table.resolve_ty_shallow(&ty);
535         let mut adjust = Vec::new();
536         for _ in 0..self.autoderefs {
537             match autoderef::autoderef_step(table, ty.clone()) {
538                 None => {
539                     never!("autoderef not possible for {:?}", ty);
540                     ty = TyKind::Error.intern(Interner);
541                     break;
542                 }
543                 Some((kind, new_ty)) => {
544                     ty = new_ty.clone();
545                     adjust.push(Adjustment {
546                         kind: Adjust::Deref(match kind {
547                             // FIXME should we know the mutability here, when autoref is `None`?
548                             AutoderefKind::Overloaded => Some(OverloadedDeref(self.autoref)),
549                             AutoderefKind::Builtin => None,
550                         }),
551                         target: new_ty,
552                     });
553                 }
554             }
555         }
556         if let Some(m) = self.autoref {
557             let a = Adjustment::borrow(m, ty);
558             ty = a.target.clone();
559             adjust.push(a);
560         }
561         if self.unsize_array {
562             ty = 'x: {
563                 if let TyKind::Ref(m, l, inner) = ty.kind(Interner) {
564                     if let TyKind::Array(inner, _) = inner.kind(Interner) {
565                         break 'x TyKind::Ref(
566                             m.clone(),
567                             l.clone(),
568                             TyKind::Slice(inner.clone()).intern(Interner),
569                         )
570                         .intern(Interner);
571                     }
572                 }
573                 // FIXME: report diagnostic if array unsizing happens without indirection.
574                 ty
575             };
576             adjust.push(Adjustment {
577                 kind: Adjust::Pointer(PointerCast::Unsize),
578                 target: ty.clone(),
579             });
580         }
581         (ty, adjust)
582     }
583 
with_autoref(&self, m: Mutability) -> ReceiverAdjustments584     fn with_autoref(&self, m: Mutability) -> ReceiverAdjustments {
585         Self { autoref: Some(m), ..*self }
586     }
587 }
588 
589 // This would be nicer if it just returned an iterator, but that runs into
590 // lifetime problems, because we need to borrow temp `CrateImplDefs`.
591 // FIXME add a context type here?
iterate_method_candidates<T>( ty: &Canonical<Ty>, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, mode: LookupMode, mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option<T>, ) -> Option<T>592 pub(crate) fn iterate_method_candidates<T>(
593     ty: &Canonical<Ty>,
594     db: &dyn HirDatabase,
595     env: Arc<TraitEnvironment>,
596     traits_in_scope: &FxHashSet<TraitId>,
597     visible_from_module: VisibleFromModule,
598     name: Option<&Name>,
599     mode: LookupMode,
600     mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option<T>,
601 ) -> Option<T> {
602     let mut slot = None;
603     iterate_method_candidates_dyn(
604         ty,
605         db,
606         env,
607         traits_in_scope,
608         visible_from_module,
609         name,
610         mode,
611         &mut |adj, item, visible| {
612             assert!(slot.is_none());
613             if let Some(it) = callback(adj, item, visible) {
614                 slot = Some(it);
615                 return ControlFlow::Break(());
616             }
617             ControlFlow::Continue(())
618         },
619     );
620     slot
621 }
622 
lookup_impl_const( db: &dyn HirDatabase, env: Arc<TraitEnvironment>, const_id: ConstId, subs: Substitution, ) -> (ConstId, Substitution)623 pub fn lookup_impl_const(
624     db: &dyn HirDatabase,
625     env: Arc<TraitEnvironment>,
626     const_id: ConstId,
627     subs: Substitution,
628 ) -> (ConstId, Substitution) {
629     let trait_id = match const_id.lookup(db.upcast()).container {
630         ItemContainerId::TraitId(id) => id,
631         _ => return (const_id, subs),
632     };
633     let substitution = Substitution::from_iter(Interner, subs.iter(Interner));
634     let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution };
635 
636     let const_data = db.const_data(const_id);
637     let name = match const_data.name.as_ref() {
638         Some(name) => name,
639         None => return (const_id, subs),
640     };
641 
642     lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name)
643         .and_then(
644             |assoc| if let (AssocItemId::ConstId(id), s) = assoc { Some((id, s)) } else { None },
645         )
646         .unwrap_or((const_id, subs))
647 }
648 
649 /// Checks if the self parameter of `Trait` method is the `dyn Trait` and we should
650 /// call the method using the vtable.
is_dyn_method( db: &dyn HirDatabase, _env: Arc<TraitEnvironment>, func: FunctionId, fn_subst: Substitution, ) -> Option<usize>651 pub fn is_dyn_method(
652     db: &dyn HirDatabase,
653     _env: Arc<TraitEnvironment>,
654     func: FunctionId,
655     fn_subst: Substitution,
656 ) -> Option<usize> {
657     let ItemContainerId::TraitId(trait_id) = func.lookup(db.upcast()).container else {
658         return None;
659     };
660     let trait_params = db.generic_params(trait_id.into()).type_or_consts.len();
661     let fn_params = fn_subst.len(Interner) - trait_params;
662     let trait_ref = TraitRef {
663         trait_id: to_chalk_trait_id(trait_id),
664         substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).skip(fn_params)),
665     };
666     let self_ty = trait_ref.self_type_parameter(Interner);
667     if let TyKind::Dyn(d) = self_ty.kind(Interner) {
668         let is_my_trait_in_bounds =
669             d.bounds.skip_binders().as_slice(Interner).iter().any(|x| match x.skip_binders() {
670                 // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
671                 // what the generics are, we are sure that the method is come from the vtable.
672                 WhereClause::Implemented(tr) => tr.trait_id == trait_ref.trait_id,
673                 _ => false,
674             });
675         if is_my_trait_in_bounds {
676             return Some(fn_params);
677         }
678     }
679     None
680 }
681 
682 /// Looks up the impl method that actually runs for the trait method `func`.
683 ///
684 /// Returns `func` if it's not a method defined in a trait or the lookup failed.
lookup_impl_method( db: &dyn HirDatabase, env: Arc<TraitEnvironment>, func: FunctionId, fn_subst: Substitution, ) -> (FunctionId, Substitution)685 pub fn lookup_impl_method(
686     db: &dyn HirDatabase,
687     env: Arc<TraitEnvironment>,
688     func: FunctionId,
689     fn_subst: Substitution,
690 ) -> (FunctionId, Substitution) {
691     let ItemContainerId::TraitId(trait_id) = func.lookup(db.upcast()).container else {
692         return (func, fn_subst)
693     };
694     let trait_params = db.generic_params(trait_id.into()).type_or_consts.len();
695     let fn_params = fn_subst.len(Interner) - trait_params;
696     let trait_ref = TraitRef {
697         trait_id: to_chalk_trait_id(trait_id),
698         substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).skip(fn_params)),
699     };
700 
701     let name = &db.function_data(func).name;
702     let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name)
703         .and_then(|assoc| {
704             if let (AssocItemId::FunctionId(id), subst) = assoc {
705                 Some((id, subst))
706             } else {
707                 None
708             }
709         })
710     else {
711         return (func, fn_subst);
712     };
713     (
714         impl_fn,
715         Substitution::from_iter(
716             Interner,
717             fn_subst.iter(Interner).take(fn_params).chain(impl_subst.iter(Interner)),
718         ),
719     )
720 }
721 
lookup_impl_assoc_item_for_trait_ref( trait_ref: TraitRef, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, name: &Name, ) -> Option<(AssocItemId, Substitution)>722 fn lookup_impl_assoc_item_for_trait_ref(
723     trait_ref: TraitRef,
724     db: &dyn HirDatabase,
725     env: Arc<TraitEnvironment>,
726     name: &Name,
727 ) -> Option<(AssocItemId, Substitution)> {
728     let hir_trait_id = trait_ref.hir_trait_id();
729     let self_ty = trait_ref.self_type_parameter(Interner);
730     let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
731     let impls = db.trait_impls_in_deps(env.krate);
732     let self_impls = match self_ty.kind(Interner) {
733         TyKind::Adt(id, _) => {
734             id.0.module(db.upcast()).containing_block().map(|x| db.trait_impls_in_block(x))
735         }
736         _ => None,
737     };
738     let impls = impls
739         .iter()
740         .chain(self_impls.as_ref())
741         .flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
742 
743     let table = InferenceTable::new(db, env);
744 
745     let (impl_data, impl_subst) = find_matching_impl(impls, table, trait_ref)?;
746     let item = impl_data.items.iter().find_map(|&it| match it {
747         AssocItemId::FunctionId(f) => {
748             (db.function_data(f).name == *name).then_some(AssocItemId::FunctionId(f))
749         }
750         AssocItemId::ConstId(c) => db
751             .const_data(c)
752             .name
753             .as_ref()
754             .map(|n| n == name)
755             .and_then(|result| if result { Some(AssocItemId::ConstId(c)) } else { None }),
756         AssocItemId::TypeAliasId(_) => None,
757     })?;
758     Some((item, impl_subst))
759 }
760 
find_matching_impl( mut impls: impl Iterator<Item = ImplId>, mut table: InferenceTable<'_>, actual_trait_ref: TraitRef, ) -> Option<(Arc<ImplData>, Substitution)>761 fn find_matching_impl(
762     mut impls: impl Iterator<Item = ImplId>,
763     mut table: InferenceTable<'_>,
764     actual_trait_ref: TraitRef,
765 ) -> Option<(Arc<ImplData>, Substitution)> {
766     let db = table.db;
767     impls.find_map(|impl_| {
768         table.run_in_snapshot(|table| {
769             let impl_data = db.impl_data(impl_);
770             let impl_substs =
771                 TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build();
772             let trait_ref = db
773                 .impl_trait(impl_)
774                 .expect("non-trait method in find_matching_impl")
775                 .substitute(Interner, &impl_substs);
776 
777             if !table.unify(&trait_ref, &actual_trait_ref) {
778                 return None;
779             }
780 
781             let wcs = crate::chalk_db::convert_where_clauses(db, impl_.into(), &impl_substs)
782                 .into_iter()
783                 .map(|b| b.cast(Interner));
784             let goal = crate::Goal::all(Interner, wcs);
785             table.try_obligation(goal.clone())?;
786             table.register_obligation(goal);
787             Some((impl_data, table.resolve_completely(impl_substs)))
788         })
789     })
790 }
791 
is_inherent_impl_coherent( db: &dyn HirDatabase, def_map: &DefMap, impl_data: &ImplData, self_ty: &Ty, ) -> bool792 fn is_inherent_impl_coherent(
793     db: &dyn HirDatabase,
794     def_map: &DefMap,
795     impl_data: &ImplData,
796     self_ty: &Ty,
797 ) -> bool {
798     let self_ty = self_ty.kind(Interner);
799     let impl_allowed = match self_ty {
800         TyKind::Tuple(_, _)
801         | TyKind::FnDef(_, _)
802         | TyKind::Array(_, _)
803         | TyKind::Never
804         | TyKind::Raw(_, _)
805         | TyKind::Ref(_, _, _)
806         | TyKind::Slice(_)
807         | TyKind::Str
808         | TyKind::Scalar(_) => def_map.is_rustc_coherence_is_core(),
809 
810         &TyKind::Adt(AdtId(adt), _) => adt.module(db.upcast()).krate() == def_map.krate(),
811         TyKind::Dyn(it) => it.principal().map_or(false, |trait_ref| {
812             from_chalk_trait_id(trait_ref.trait_id).module(db.upcast()).krate() == def_map.krate()
813         }),
814 
815         _ => true,
816     };
817     impl_allowed || {
818         let rustc_has_incoherent_inherent_impls = match self_ty {
819             TyKind::Tuple(_, _)
820             | TyKind::FnDef(_, _)
821             | TyKind::Array(_, _)
822             | TyKind::Never
823             | TyKind::Raw(_, _)
824             | TyKind::Ref(_, _, _)
825             | TyKind::Slice(_)
826             | TyKind::Str
827             | TyKind::Scalar(_) => true,
828 
829             &TyKind::Adt(AdtId(adt), _) => match adt {
830                 hir_def::AdtId::StructId(id) => db
831                     .struct_data(id)
832                     .flags
833                     .contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
834                 hir_def::AdtId::UnionId(id) => db
835                     .union_data(id)
836                     .flags
837                     .contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
838                 hir_def::AdtId::EnumId(it) => db.enum_data(it).rustc_has_incoherent_inherent_impls,
839             },
840             TyKind::Dyn(it) => it.principal().map_or(false, |trait_ref| {
841                 db.trait_data(from_chalk_trait_id(trait_ref.trait_id))
842                     .rustc_has_incoherent_inherent_impls
843             }),
844 
845             _ => false,
846         };
847         rustc_has_incoherent_inherent_impls
848             && !impl_data.items.is_empty()
849             && impl_data.items.iter().copied().all(|assoc| match assoc {
850                 AssocItemId::FunctionId(it) => db.function_data(it).rustc_allow_incoherent_impl,
851                 AssocItemId::ConstId(it) => db.const_data(it).rustc_allow_incoherent_impl,
852                 AssocItemId::TypeAliasId(it) => db.type_alias_data(it).rustc_allow_incoherent_impl,
853             })
854     }
855 }
856 
iterate_path_candidates( ty: &Canonical<Ty>, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>, ) -> ControlFlow<()>857 pub fn iterate_path_candidates(
858     ty: &Canonical<Ty>,
859     db: &dyn HirDatabase,
860     env: Arc<TraitEnvironment>,
861     traits_in_scope: &FxHashSet<TraitId>,
862     visible_from_module: VisibleFromModule,
863     name: Option<&Name>,
864     callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>,
865 ) -> ControlFlow<()> {
866     iterate_method_candidates_dyn(
867         ty,
868         db,
869         env,
870         traits_in_scope,
871         visible_from_module,
872         name,
873         LookupMode::Path,
874         // the adjustments are not relevant for path lookup
875         &mut |_, id, _| callback(id),
876     )
877 }
878 
iterate_method_candidates_dyn( ty: &Canonical<Ty>, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, mode: LookupMode, callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()>879 pub fn iterate_method_candidates_dyn(
880     ty: &Canonical<Ty>,
881     db: &dyn HirDatabase,
882     env: Arc<TraitEnvironment>,
883     traits_in_scope: &FxHashSet<TraitId>,
884     visible_from_module: VisibleFromModule,
885     name: Option<&Name>,
886     mode: LookupMode,
887     callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
888 ) -> ControlFlow<()> {
889     match mode {
890         LookupMode::MethodCall => {
891             // For method calls, rust first does any number of autoderef, and
892             // then one autoref (i.e. when the method takes &self or &mut self).
893             // Note that when we've got a receiver like &S, even if the method
894             // we find in the end takes &self, we still do the autoderef step
895             // (just as rustc does an autoderef and then autoref again).
896 
897             // We have to be careful about the order we're looking at candidates
898             // in here. Consider the case where we're resolving `x.clone()`
899             // where `x: &Vec<_>`. This resolves to the clone method with self
900             // type `Vec<_>`, *not* `&_`. I.e. we need to consider methods where
901             // the receiver type exactly matches before cases where we have to
902             // do autoref. But in the autoderef steps, the `&_` self type comes
903             // up *before* the `Vec<_>` self type.
904             //
905             // On the other hand, we don't want to just pick any by-value method
906             // before any by-autoref method; it's just that we need to consider
907             // the methods by autoderef order of *receiver types*, not *self
908             // types*.
909 
910             let mut table = InferenceTable::new(db, env.clone());
911             let ty = table.instantiate_canonical(ty.clone());
912             let deref_chain = autoderef_method_receiver(&mut table, ty);
913 
914             let result = deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| {
915                 iterate_method_candidates_with_autoref(
916                     &receiver_ty,
917                     adj,
918                     db,
919                     env.clone(),
920                     traits_in_scope,
921                     visible_from_module,
922                     name,
923                     callback,
924                 )
925             });
926             result
927         }
928         LookupMode::Path => {
929             // No autoderef for path lookups
930             iterate_method_candidates_for_self_ty(
931                 ty,
932                 db,
933                 env,
934                 traits_in_scope,
935                 visible_from_module,
936                 name,
937                 callback,
938             )
939         }
940     }
941 }
942 
iterate_method_candidates_with_autoref( receiver_ty: &Canonical<Ty>, first_adjustment: ReceiverAdjustments, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()>943 fn iterate_method_candidates_with_autoref(
944     receiver_ty: &Canonical<Ty>,
945     first_adjustment: ReceiverAdjustments,
946     db: &dyn HirDatabase,
947     env: Arc<TraitEnvironment>,
948     traits_in_scope: &FxHashSet<TraitId>,
949     visible_from_module: VisibleFromModule,
950     name: Option<&Name>,
951     mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
952 ) -> ControlFlow<()> {
953     if receiver_ty.value.is_general_var(Interner, &receiver_ty.binders) {
954         // don't try to resolve methods on unknown types
955         return ControlFlow::Continue(());
956     }
957 
958     let mut iterate_method_candidates_by_receiver = move |receiver_ty, first_adjustment| {
959         iterate_method_candidates_by_receiver(
960             receiver_ty,
961             first_adjustment,
962             db,
963             env.clone(),
964             traits_in_scope,
965             visible_from_module,
966             name,
967             &mut callback,
968         )
969     };
970 
971     let mut maybe_reborrowed = first_adjustment.clone();
972     if let Some((_, _, m)) = receiver_ty.value.as_reference() {
973         // Prefer reborrow of references to move
974         maybe_reborrowed.autoref = Some(m);
975         maybe_reborrowed.autoderefs += 1;
976     }
977 
978     iterate_method_candidates_by_receiver(receiver_ty, maybe_reborrowed)?;
979 
980     let refed = Canonical {
981         value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone())
982             .intern(Interner),
983         binders: receiver_ty.binders.clone(),
984     };
985 
986     iterate_method_candidates_by_receiver(&refed, first_adjustment.with_autoref(Mutability::Not))?;
987 
988     let ref_muted = Canonical {
989         value: TyKind::Ref(Mutability::Mut, static_lifetime(), receiver_ty.value.clone())
990             .intern(Interner),
991         binders: receiver_ty.binders.clone(),
992     };
993 
994     iterate_method_candidates_by_receiver(
995         &ref_muted,
996         first_adjustment.with_autoref(Mutability::Mut),
997     )
998 }
999 
iterate_method_candidates_by_receiver( receiver_ty: &Canonical<Ty>, receiver_adjustments: ReceiverAdjustments, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()>1000 fn iterate_method_candidates_by_receiver(
1001     receiver_ty: &Canonical<Ty>,
1002     receiver_adjustments: ReceiverAdjustments,
1003     db: &dyn HirDatabase,
1004     env: Arc<TraitEnvironment>,
1005     traits_in_scope: &FxHashSet<TraitId>,
1006     visible_from_module: VisibleFromModule,
1007     name: Option<&Name>,
1008     mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1009 ) -> ControlFlow<()> {
1010     let mut table = InferenceTable::new(db, env);
1011     let receiver_ty = table.instantiate_canonical(receiver_ty.clone());
1012     let snapshot = table.snapshot();
1013     // We're looking for methods with *receiver* type receiver_ty. These could
1014     // be found in any of the derefs of receiver_ty, so we have to go through
1015     // that.
1016     let mut autoderef = autoderef::Autoderef::new(&mut table, receiver_ty.clone());
1017     while let Some((self_ty, _)) = autoderef.next() {
1018         iterate_inherent_methods(
1019             &self_ty,
1020             autoderef.table,
1021             name,
1022             Some(&receiver_ty),
1023             Some(receiver_adjustments.clone()),
1024             visible_from_module,
1025             &mut callback,
1026         )?
1027     }
1028 
1029     table.rollback_to(snapshot);
1030 
1031     let mut autoderef = autoderef::Autoderef::new(&mut table, receiver_ty.clone());
1032     while let Some((self_ty, _)) = autoderef.next() {
1033         iterate_trait_method_candidates(
1034             &self_ty,
1035             autoderef.table,
1036             traits_in_scope,
1037             name,
1038             Some(&receiver_ty),
1039             Some(receiver_adjustments.clone()),
1040             &mut callback,
1041         )?
1042     }
1043 
1044     ControlFlow::Continue(())
1045 }
1046 
iterate_method_candidates_for_self_ty( self_ty: &Canonical<Ty>, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()>1047 fn iterate_method_candidates_for_self_ty(
1048     self_ty: &Canonical<Ty>,
1049     db: &dyn HirDatabase,
1050     env: Arc<TraitEnvironment>,
1051     traits_in_scope: &FxHashSet<TraitId>,
1052     visible_from_module: VisibleFromModule,
1053     name: Option<&Name>,
1054     mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1055 ) -> ControlFlow<()> {
1056     let mut table = InferenceTable::new(db, env);
1057     let self_ty = table.instantiate_canonical(self_ty.clone());
1058     iterate_inherent_methods(
1059         &self_ty,
1060         &mut table,
1061         name,
1062         None,
1063         None,
1064         visible_from_module,
1065         &mut callback,
1066     )?;
1067     iterate_trait_method_candidates(
1068         &self_ty,
1069         &mut table,
1070         traits_in_scope,
1071         name,
1072         None,
1073         None,
1074         callback,
1075     )
1076 }
1077 
iterate_trait_method_candidates( self_ty: &Ty, table: &mut InferenceTable<'_>, traits_in_scope: &FxHashSet<TraitId>, name: Option<&Name>, receiver_ty: Option<&Ty>, receiver_adjustments: Option<ReceiverAdjustments>, callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()>1078 fn iterate_trait_method_candidates(
1079     self_ty: &Ty,
1080     table: &mut InferenceTable<'_>,
1081     traits_in_scope: &FxHashSet<TraitId>,
1082     name: Option<&Name>,
1083     receiver_ty: Option<&Ty>,
1084     receiver_adjustments: Option<ReceiverAdjustments>,
1085     callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1086 ) -> ControlFlow<()> {
1087     let db = table.db;
1088     let env = table.trait_env.clone();
1089     let self_is_array = matches!(self_ty.kind(Interner), chalk_ir::TyKind::Array(..));
1090 
1091     let canonical_self_ty = table.canonicalize(self_ty.clone()).value;
1092 
1093     'traits: for &t in traits_in_scope {
1094         let data = db.trait_data(t);
1095 
1096         // Traits annotated with `#[rustc_skip_array_during_method_dispatch]` are skipped during
1097         // method resolution, if the receiver is an array, and we're compiling for editions before
1098         // 2021.
1099         // This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for
1100         // arrays.
1101         if data.skip_array_during_method_dispatch && self_is_array {
1102             // FIXME: this should really be using the edition of the method name's span, in case it
1103             // comes from a macro
1104             if db.crate_graph()[env.krate].edition < Edition::Edition2021 {
1105                 continue;
1106             }
1107         }
1108 
1109         // we'll be lazy about checking whether the type implements the
1110         // trait, but if we find out it doesn't, we'll skip the rest of the
1111         // iteration
1112         let mut known_implemented = false;
1113         for &(_, item) in data.items.iter() {
1114             // Don't pass a `visible_from_module` down to `is_valid_candidate`,
1115             // since only inherent methods should be included into visibility checking.
1116             let visible = match is_valid_candidate(table, name, receiver_ty, item, self_ty, None) {
1117                 IsValidCandidate::Yes => true,
1118                 IsValidCandidate::NotVisible => false,
1119                 IsValidCandidate::No => continue,
1120             };
1121             if !known_implemented {
1122                 let goal = generic_implements_goal(db, env.clone(), t, &canonical_self_ty);
1123                 if db.trait_solve(env.krate, env.block, goal.cast(Interner)).is_none() {
1124                     continue 'traits;
1125                 }
1126             }
1127             known_implemented = true;
1128             callback(receiver_adjustments.clone().unwrap_or_default(), item, visible)?;
1129         }
1130     }
1131     ControlFlow::Continue(())
1132 }
1133 
iterate_inherent_methods( self_ty: &Ty, table: &mut InferenceTable<'_>, name: Option<&Name>, receiver_ty: Option<&Ty>, receiver_adjustments: Option<ReceiverAdjustments>, visible_from_module: VisibleFromModule, callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()>1134 fn iterate_inherent_methods(
1135     self_ty: &Ty,
1136     table: &mut InferenceTable<'_>,
1137     name: Option<&Name>,
1138     receiver_ty: Option<&Ty>,
1139     receiver_adjustments: Option<ReceiverAdjustments>,
1140     visible_from_module: VisibleFromModule,
1141     callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1142 ) -> ControlFlow<()> {
1143     let db = table.db;
1144     let env = table.trait_env.clone();
1145 
1146     // For trait object types and placeholder types with trait bounds, the methods of the trait and
1147     // its super traits are considered inherent methods. This matters because these methods have
1148     // higher priority than the other traits' methods, which would be considered in
1149     // `iterate_trait_method_candidates()` only after this function.
1150     match self_ty.kind(Interner) {
1151         TyKind::Placeholder(_) => {
1152             let env = table.trait_env.clone();
1153             let traits = env
1154                 .traits_in_scope_from_clauses(self_ty.clone())
1155                 .flat_map(|t| all_super_traits(db.upcast(), t));
1156             iterate_inherent_trait_methods(
1157                 self_ty,
1158                 table,
1159                 name,
1160                 receiver_ty,
1161                 receiver_adjustments.clone(),
1162                 callback,
1163                 traits,
1164             )?;
1165         }
1166         TyKind::Dyn(_) => {
1167             if let Some(principal_trait) = self_ty.dyn_trait() {
1168                 let traits = all_super_traits(db.upcast(), principal_trait);
1169                 iterate_inherent_trait_methods(
1170                     self_ty,
1171                     table,
1172                     name,
1173                     receiver_ty,
1174                     receiver_adjustments.clone(),
1175                     callback,
1176                     traits.into_iter(),
1177                 )?;
1178             }
1179         }
1180         _ => {}
1181     }
1182 
1183     let def_crates = match def_crates(db, self_ty, env.krate) {
1184         Some(k) => k,
1185         None => return ControlFlow::Continue(()),
1186     };
1187 
1188     let (module, mut block) = match visible_from_module {
1189         VisibleFromModule::Filter(module) => (Some(module), module.containing_block()),
1190         VisibleFromModule::IncludeBlock(block) => (None, Some(block)),
1191         VisibleFromModule::None => (None, None),
1192     };
1193 
1194     while let Some(block_id) = block {
1195         let impls = db.inherent_impls_in_block(block_id);
1196         impls_for_self_ty(
1197             &impls,
1198             self_ty,
1199             table,
1200             name,
1201             receiver_ty,
1202             receiver_adjustments.clone(),
1203             module,
1204             callback,
1205         )?;
1206 
1207         block = db.block_def_map(block_id).parent().and_then(|module| module.containing_block());
1208     }
1209 
1210     for krate in def_crates {
1211         let impls = db.inherent_impls_in_crate(krate);
1212         impls_for_self_ty(
1213             &impls,
1214             self_ty,
1215             table,
1216             name,
1217             receiver_ty,
1218             receiver_adjustments.clone(),
1219             module,
1220             callback,
1221         )?;
1222     }
1223     return ControlFlow::Continue(());
1224 
1225     fn iterate_inherent_trait_methods(
1226         self_ty: &Ty,
1227         table: &mut InferenceTable<'_>,
1228         name: Option<&Name>,
1229         receiver_ty: Option<&Ty>,
1230         receiver_adjustments: Option<ReceiverAdjustments>,
1231         callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1232         traits: impl Iterator<Item = TraitId>,
1233     ) -> ControlFlow<()> {
1234         let db = table.db;
1235         for t in traits {
1236             let data = db.trait_data(t);
1237             for &(_, item) in data.items.iter() {
1238                 // We don't pass `visible_from_module` as all trait items should be visible.
1239                 let visible =
1240                     match is_valid_candidate(table, name, receiver_ty, item, self_ty, None) {
1241                         IsValidCandidate::Yes => true,
1242                         IsValidCandidate::NotVisible => false,
1243                         IsValidCandidate::No => continue,
1244                     };
1245                 callback(receiver_adjustments.clone().unwrap_or_default(), item, visible)?;
1246             }
1247         }
1248         ControlFlow::Continue(())
1249     }
1250 
1251     fn impls_for_self_ty(
1252         impls: &InherentImpls,
1253         self_ty: &Ty,
1254         table: &mut InferenceTable<'_>,
1255         name: Option<&Name>,
1256         receiver_ty: Option<&Ty>,
1257         receiver_adjustments: Option<ReceiverAdjustments>,
1258         visible_from_module: Option<ModuleId>,
1259         callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
1260     ) -> ControlFlow<()> {
1261         let db = table.db;
1262         let impls_for_self_ty = impls.for_self_ty(self_ty);
1263         for &impl_def in impls_for_self_ty {
1264             for &item in &db.impl_data(impl_def).items {
1265                 let visible = match is_valid_candidate(
1266                     table,
1267                     name,
1268                     receiver_ty,
1269                     item,
1270                     self_ty,
1271                     visible_from_module,
1272                 ) {
1273                     IsValidCandidate::Yes => true,
1274                     IsValidCandidate::NotVisible => false,
1275                     IsValidCandidate::No => continue,
1276                 };
1277                 callback(receiver_adjustments.clone().unwrap_or_default(), item, visible)?;
1278             }
1279         }
1280         ControlFlow::Continue(())
1281     }
1282 }
1283 
1284 /// Returns the receiver type for the index trait call.
resolve_indexing_op( db: &dyn HirDatabase, env: Arc<TraitEnvironment>, ty: Canonical<Ty>, index_trait: TraitId, ) -> Option<ReceiverAdjustments>1285 pub(crate) fn resolve_indexing_op(
1286     db: &dyn HirDatabase,
1287     env: Arc<TraitEnvironment>,
1288     ty: Canonical<Ty>,
1289     index_trait: TraitId,
1290 ) -> Option<ReceiverAdjustments> {
1291     let mut table = InferenceTable::new(db, env.clone());
1292     let ty = table.instantiate_canonical(ty);
1293     let deref_chain = autoderef_method_receiver(&mut table, ty);
1294     for (ty, adj) in deref_chain {
1295         let goal = generic_implements_goal(db, table.trait_env.clone(), index_trait, &ty);
1296         if db
1297             .trait_solve(table.trait_env.krate, table.trait_env.block, goal.cast(Interner))
1298             .is_some()
1299         {
1300             return Some(adj);
1301         }
1302     }
1303     None
1304 }
1305 
1306 macro_rules! check_that {
1307     ($cond:expr) => {
1308         if !$cond {
1309             return IsValidCandidate::No;
1310         }
1311     };
1312 }
1313 
is_valid_candidate( table: &mut InferenceTable<'_>, name: Option<&Name>, receiver_ty: Option<&Ty>, item: AssocItemId, self_ty: &Ty, visible_from_module: Option<ModuleId>, ) -> IsValidCandidate1314 fn is_valid_candidate(
1315     table: &mut InferenceTable<'_>,
1316     name: Option<&Name>,
1317     receiver_ty: Option<&Ty>,
1318     item: AssocItemId,
1319     self_ty: &Ty,
1320     visible_from_module: Option<ModuleId>,
1321 ) -> IsValidCandidate {
1322     let db = table.db;
1323     match item {
1324         AssocItemId::FunctionId(f) => {
1325             is_valid_fn_candidate(table, f, name, receiver_ty, self_ty, visible_from_module)
1326         }
1327         AssocItemId::ConstId(c) => {
1328             check_that!(receiver_ty.is_none());
1329             check_that!(name.map_or(true, |n| db.const_data(c).name.as_ref() == Some(n)));
1330 
1331             if let Some(from_module) = visible_from_module {
1332                 if !db.const_visibility(c).is_visible_from(db.upcast(), from_module) {
1333                     cov_mark::hit!(const_candidate_not_visible);
1334                     return IsValidCandidate::NotVisible;
1335                 }
1336             }
1337             if let ItemContainerId::ImplId(impl_id) = c.lookup(db.upcast()).container {
1338                 let self_ty_matches = table.run_in_snapshot(|table| {
1339                     let expected_self_ty = TyBuilder::impl_self_ty(db, impl_id)
1340                         .fill_with_inference_vars(table)
1341                         .build();
1342                     table.unify(&expected_self_ty, self_ty)
1343                 });
1344                 if !self_ty_matches {
1345                     cov_mark::hit!(const_candidate_self_type_mismatch);
1346                     return IsValidCandidate::No;
1347                 }
1348             }
1349             IsValidCandidate::Yes
1350         }
1351         _ => IsValidCandidate::No,
1352     }
1353 }
1354 
1355 enum IsValidCandidate {
1356     Yes,
1357     No,
1358     NotVisible,
1359 }
1360 
is_valid_fn_candidate( table: &mut InferenceTable<'_>, fn_id: FunctionId, name: Option<&Name>, receiver_ty: Option<&Ty>, self_ty: &Ty, visible_from_module: Option<ModuleId>, ) -> IsValidCandidate1361 fn is_valid_fn_candidate(
1362     table: &mut InferenceTable<'_>,
1363     fn_id: FunctionId,
1364     name: Option<&Name>,
1365     receiver_ty: Option<&Ty>,
1366     self_ty: &Ty,
1367     visible_from_module: Option<ModuleId>,
1368 ) -> IsValidCandidate {
1369     let db = table.db;
1370     let data = db.function_data(fn_id);
1371 
1372     check_that!(name.map_or(true, |n| n == &data.name));
1373     if let Some(from_module) = visible_from_module {
1374         if !db.function_visibility(fn_id).is_visible_from(db.upcast(), from_module) {
1375             cov_mark::hit!(autoderef_candidate_not_visible);
1376             return IsValidCandidate::NotVisible;
1377         }
1378     }
1379     table.run_in_snapshot(|table| {
1380         let container = fn_id.lookup(db.upcast()).container;
1381         let (impl_subst, expect_self_ty) = match container {
1382             ItemContainerId::ImplId(it) => {
1383                 let subst =
1384                     TyBuilder::subst_for_def(db, it, None).fill_with_inference_vars(table).build();
1385                 let self_ty = db.impl_self_ty(it).substitute(Interner, &subst);
1386                 (subst, self_ty)
1387             }
1388             ItemContainerId::TraitId(it) => {
1389                 let subst =
1390                     TyBuilder::subst_for_def(db, it, None).fill_with_inference_vars(table).build();
1391                 let self_ty = subst.at(Interner, 0).assert_ty_ref(Interner).clone();
1392                 (subst, self_ty)
1393             }
1394             _ => unreachable!(),
1395         };
1396 
1397         let fn_subst = TyBuilder::subst_for_def(db, fn_id, Some(impl_subst.clone()))
1398             .fill_with_inference_vars(table)
1399             .build();
1400 
1401         check_that!(table.unify(&expect_self_ty, self_ty));
1402 
1403         if let Some(receiver_ty) = receiver_ty {
1404             check_that!(data.has_self_param());
1405 
1406             let sig = db.callable_item_signature(fn_id.into());
1407             let expected_receiver =
1408                 sig.map(|s| s.params()[0].clone()).substitute(Interner, &fn_subst);
1409 
1410             check_that!(table.unify(receiver_ty, &expected_receiver));
1411         }
1412 
1413         if let ItemContainerId::ImplId(impl_id) = container {
1414             // We need to consider the bounds on the impl to distinguish functions of the same name
1415             // for a type.
1416             let predicates = db.generic_predicates(impl_id.into());
1417             let valid = predicates
1418                 .iter()
1419                 .map(|predicate| {
1420                     let (p, b) = predicate
1421                         .clone()
1422                         .substitute(Interner, &impl_subst)
1423                         // Skipping the inner binders is ok, as we don't handle quantified where
1424                         // clauses yet.
1425                         .into_value_and_skipped_binders();
1426                     stdx::always!(b.len(Interner) == 0);
1427                     p
1428                 })
1429                 // It's ok to get ambiguity here, as we may not have enough information to prove
1430                 // obligations. We'll check if the user is calling the selected method properly
1431                 // later anyway.
1432                 .all(|p| table.try_obligation(p.cast(Interner)).is_some());
1433             match valid {
1434                 true => IsValidCandidate::Yes,
1435                 false => IsValidCandidate::No,
1436             }
1437         } else {
1438             // For `ItemContainerId::TraitId`, we check if `self_ty` implements the trait in
1439             // `iterate_trait_method_candidates()`.
1440             // For others, this function shouldn't be called.
1441             IsValidCandidate::Yes
1442         }
1443     })
1444 }
1445 
implements_trait( ty: &Canonical<Ty>, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, trait_: TraitId, ) -> bool1446 pub fn implements_trait(
1447     ty: &Canonical<Ty>,
1448     db: &dyn HirDatabase,
1449     env: Arc<TraitEnvironment>,
1450     trait_: TraitId,
1451 ) -> bool {
1452     let goal = generic_implements_goal(db, env.clone(), trait_, ty);
1453     let solution = db.trait_solve(env.krate, env.block, goal.cast(Interner));
1454 
1455     solution.is_some()
1456 }
1457 
implements_trait_unique( ty: &Canonical<Ty>, db: &dyn HirDatabase, env: Arc<TraitEnvironment>, trait_: TraitId, ) -> bool1458 pub fn implements_trait_unique(
1459     ty: &Canonical<Ty>,
1460     db: &dyn HirDatabase,
1461     env: Arc<TraitEnvironment>,
1462     trait_: TraitId,
1463 ) -> bool {
1464     let goal = generic_implements_goal(db, env.clone(), trait_, ty);
1465     let solution = db.trait_solve(env.krate, env.block, goal.cast(Interner));
1466 
1467     matches!(solution, Some(crate::Solution::Unique(_)))
1468 }
1469 
1470 /// This creates Substs for a trait with the given Self type and type variables
1471 /// for all other parameters, to query Chalk with it.
generic_implements_goal( db: &dyn HirDatabase, env: Arc<TraitEnvironment>, trait_: TraitId, self_ty: &Canonical<Ty>, ) -> Canonical<InEnvironment<super::DomainGoal>>1472 fn generic_implements_goal(
1473     db: &dyn HirDatabase,
1474     env: Arc<TraitEnvironment>,
1475     trait_: TraitId,
1476     self_ty: &Canonical<Ty>,
1477 ) -> Canonical<InEnvironment<super::DomainGoal>> {
1478     let mut kinds = self_ty.binders.interned().to_vec();
1479     let trait_ref = TyBuilder::trait_ref(db, trait_)
1480         .push(self_ty.value.clone())
1481         .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
1482         .build();
1483     kinds.extend(trait_ref.substitution.iter(Interner).skip(1).map(|x| {
1484         let vk = match x.data(Interner) {
1485             chalk_ir::GenericArgData::Ty(_) => {
1486                 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
1487             }
1488             chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
1489             chalk_ir::GenericArgData::Const(c) => {
1490                 chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
1491             }
1492         };
1493         chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
1494     }));
1495     let obligation = trait_ref.cast(Interner);
1496     Canonical {
1497         binders: CanonicalVarKinds::from_iter(Interner, kinds),
1498         value: InEnvironment::new(&env.env, obligation),
1499     }
1500 }
1501 
autoderef_method_receiver( table: &mut InferenceTable<'_>, ty: Ty, ) -> Vec<(Canonical<Ty>, ReceiverAdjustments)>1502 fn autoderef_method_receiver(
1503     table: &mut InferenceTable<'_>,
1504     ty: Ty,
1505 ) -> Vec<(Canonical<Ty>, ReceiverAdjustments)> {
1506     let mut deref_chain: Vec<_> = Vec::new();
1507     let mut autoderef = autoderef::Autoderef::new(table, ty);
1508     while let Some((ty, derefs)) = autoderef.next() {
1509         deref_chain.push((
1510             autoderef.table.canonicalize(ty).value,
1511             ReceiverAdjustments { autoref: None, autoderefs: derefs, unsize_array: false },
1512         ));
1513     }
1514     // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
1515     if let Some((TyKind::Array(parameters, _), binders, adj)) =
1516         deref_chain.last().map(|(ty, adj)| (ty.value.kind(Interner), ty.binders.clone(), adj))
1517     {
1518         let unsized_ty = TyKind::Slice(parameters.clone()).intern(Interner);
1519         deref_chain.push((
1520             Canonical { value: unsized_ty, binders },
1521             ReceiverAdjustments { unsize_array: true, ..adj.clone() },
1522         ));
1523     }
1524     deref_chain
1525 }
1526