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