]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/method_resolution.rs
Add Lifetime to TyKind::Ref
[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, sync::Arc};
6
7 use arrayvec::ArrayVec;
8 use base_db::CrateId;
9 use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
10 use hir_def::{
11     lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
12     ImplId, Lookup, ModuleId, TraitId,
13 };
14 use hir_expand::name::Name;
15 use rustc_hash::{FxHashMap, FxHashSet};
16
17 use crate::{
18     autoderef,
19     db::HirDatabase,
20     from_foreign_def_id,
21     primitive::{self, FloatTy, IntTy, UintTy},
22     utils::all_super_traits,
23     AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
24     InEnvironment, Interner, LifetimeData, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder,
25     TyKind, TypeWalk,
26 };
27
28 /// This is used as a key for indexing impls.
29 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
30 pub enum TyFingerprint {
31     Str,
32     Slice,
33     Array,
34     Never,
35     RawPtr(Mutability),
36     Scalar(Scalar),
37     Adt(hir_def::AdtId),
38     Dyn(TraitId),
39     Tuple(usize),
40     ForeignType(ForeignDefId),
41     FnPtr(usize, FnSig),
42 }
43
44 impl TyFingerprint {
45     /// Creates a TyFingerprint for looking up an impl. Only certain types can
46     /// have impls: if we have some `struct S`, we can have an `impl S`, but not
47     /// `impl &S`. Hence, this will return `None` for reference types and such.
48     pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
49         let fp = match ty.kind(&Interner) {
50             TyKind::Str => TyFingerprint::Str,
51             TyKind::Never => TyFingerprint::Never,
52             TyKind::Slice(..) => TyFingerprint::Slice,
53             TyKind::Array(..) => TyFingerprint::Array,
54             TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
55             TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
56             TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(*cardinality),
57             TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
58             TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
59             TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
60                 TyFingerprint::FnPtr(substs.0.len(&Interner) - 1, *sig)
61             }
62             TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
63             _ => return None,
64         };
65         Some(fp)
66     }
67 }
68
69 pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
70     TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
71     TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
72     TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
73     TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
74     TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
75     TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
76     TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
77     TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
78     TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
79     TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
80     TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
81     TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
82 ];
83
84 pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
85     TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
86     TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
87 ];
88
89 /// Trait impls defined or available in some crate.
90 #[derive(Debug, Eq, PartialEq)]
91 pub struct TraitImpls {
92     // If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type.
93     map: FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>,
94 }
95
96 impl TraitImpls {
97     pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
98         let _p = profile::span("trait_impls_in_crate_query");
99         let mut impls = Self { map: FxHashMap::default() };
100
101         let crate_def_map = db.crate_def_map(krate);
102         for (_module_id, module_data) in crate_def_map.modules() {
103             for impl_id in module_data.scope.impls() {
104                 let target_trait = match db.impl_trait(impl_id) {
105                     Some(tr) => tr.skip_binders().hir_trait_id(),
106                     None => continue,
107                 };
108                 let self_ty = db.impl_self_ty(impl_id);
109                 let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders());
110                 impls
111                     .map
112                     .entry(target_trait)
113                     .or_default()
114                     .entry(self_ty_fp)
115                     .or_default()
116                     .push(impl_id);
117             }
118         }
119
120         Arc::new(impls)
121     }
122
123     pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
124         let _p = profile::span("trait_impls_in_deps_query");
125         let crate_graph = db.crate_graph();
126         let mut res = Self { map: FxHashMap::default() };
127
128         for krate in crate_graph.transitive_deps(krate) {
129             res.merge(&db.trait_impls_in_crate(krate));
130         }
131
132         Arc::new(res)
133     }
134
135     fn merge(&mut self, other: &Self) {
136         for (trait_, other_map) in &other.map {
137             let map = self.map.entry(*trait_).or_default();
138             for (fp, impls) in other_map {
139                 let vec = map.entry(*fp).or_default();
140                 vec.extend(impls);
141             }
142         }
143     }
144
145     /// Queries all trait impls for the given type.
146     pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ {
147         self.map
148             .values()
149             .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp))))
150             .flat_map(|it| it.iter().copied())
151     }
152
153     /// Queries all impls of the given trait.
154     pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ {
155         self.map
156             .get(&trait_)
157             .into_iter()
158             .flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
159     }
160
161     /// Queries all impls of `trait_` that may apply to `self_ty`.
162     pub fn for_trait_and_self_ty(
163         &self,
164         trait_: TraitId,
165         self_ty: TyFingerprint,
166     ) -> impl Iterator<Item = ImplId> + '_ {
167         self.map
168             .get(&trait_)
169             .into_iter()
170             .flat_map(move |map| map.get(&None).into_iter().chain(map.get(&Some(self_ty))))
171             .flat_map(|v| v.iter().copied())
172     }
173
174     pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
175         self.map.values().flat_map(|map| map.values().flat_map(|v| v.iter().copied()))
176     }
177 }
178
179 /// Inherent impls defined in some crate.
180 ///
181 /// Inherent impls can only be defined in the crate that also defines the self type of the impl
182 /// (note that some primitives are considered to be defined by both libcore and liballoc).
183 ///
184 /// This makes inherent impl lookup easier than trait impl lookup since we only have to consider a
185 /// single crate.
186 #[derive(Debug, Eq, PartialEq)]
187 pub struct InherentImpls {
188     map: FxHashMap<TyFingerprint, Vec<ImplId>>,
189 }
190
191 impl InherentImpls {
192     pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
193         let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default();
194
195         let crate_def_map = db.crate_def_map(krate);
196         for (_module_id, module_data) in crate_def_map.modules() {
197             for impl_id in module_data.scope.impls() {
198                 let data = db.impl_data(impl_id);
199                 if data.target_trait.is_some() {
200                     continue;
201                 }
202
203                 let self_ty = db.impl_self_ty(impl_id);
204                 if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) {
205                     map.entry(fp).or_default().push(impl_id);
206                 }
207             }
208         }
209
210         Arc::new(Self { map })
211     }
212
213     pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
214         match TyFingerprint::for_impl(self_ty) {
215             Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
216             None => &[],
217         }
218     }
219
220     pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
221         self.map.values().flat_map(|v| v.iter().copied())
222     }
223 }
224
225 impl Ty {
226     pub fn def_crates(
227         &self,
228         db: &dyn HirDatabase,
229         cur_crate: CrateId,
230     ) -> Option<ArrayVec<CrateId, 2>> {
231         // Types like slice can have inherent impls in several crates, (core and alloc).
232         // The corresponding impls are marked with lang items, so we can use them to find the required crates.
233         macro_rules! lang_item_crate {
234             ($($name:expr),+ $(,)?) => {{
235                 let mut v = ArrayVec::<LangItemTarget, 2>::new();
236                 $(
237                     v.extend(db.lang_item(cur_crate, $name.into()));
238                 )+
239                 v
240             }};
241         }
242
243         let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
244
245         let lang_item_targets = match self.kind(&Interner) {
246             TyKind::Adt(AdtId(def_id), _) => {
247                 return mod_to_crate_ids(def_id.module(db.upcast()));
248             }
249             TyKind::Foreign(id) => {
250                 return mod_to_crate_ids(
251                     from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
252                 );
253             }
254             TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
255             TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
256             TyKind::Scalar(Scalar::Float(f)) => match f {
257                 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
258                 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
259                 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
260             },
261             &TyKind::Scalar(Scalar::Int(t)) => {
262                 lang_item_crate!(primitive::int_ty_to_string(t))
263             }
264             &TyKind::Scalar(Scalar::Uint(t)) => {
265                 lang_item_crate!(primitive::uint_ty_to_string(t))
266             }
267             TyKind::Str => lang_item_crate!("str_alloc", "str"),
268             TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
269             TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
270             TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
271             TyKind::Dyn(_) => {
272                 return self.dyn_trait().and_then(|trait_| {
273                     mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
274                 });
275             }
276             _ => return None,
277         };
278         let res = lang_item_targets
279             .into_iter()
280             .filter_map(|it| match it {
281                 LangItemTarget::ImplDefId(it) => Some(it),
282                 _ => None,
283             })
284             .map(|it| it.lookup(db.upcast()).container.krate())
285             .collect();
286         Some(res)
287     }
288 }
289
290 /// Look up the method with the given name, returning the actual autoderefed
291 /// receiver type (but without autoref applied yet).
292 pub(crate) fn lookup_method(
293     ty: &Canonical<Ty>,
294     db: &dyn HirDatabase,
295     env: Arc<TraitEnvironment>,
296     krate: CrateId,
297     traits_in_scope: &FxHashSet<TraitId>,
298     visible_from_module: Option<ModuleId>,
299     name: &Name,
300 ) -> Option<(Ty, FunctionId)> {
301     iterate_method_candidates(
302         ty,
303         db,
304         env,
305         krate,
306         &traits_in_scope,
307         visible_from_module,
308         Some(name),
309         LookupMode::MethodCall,
310         |ty, f| match f {
311             AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
312             _ => None,
313         },
314     )
315 }
316
317 /// Whether we're looking up a dotted method call (like `v.len()`) or a path
318 /// (like `Vec::new`).
319 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
320 pub enum LookupMode {
321     /// Looking up a method call like `v.len()`: We only consider candidates
322     /// that have a `self` parameter, and do autoderef.
323     MethodCall,
324     /// Looking up a path like `Vec::new` or `Vec::default`: We consider all
325     /// candidates including associated constants, but don't do autoderef.
326     Path,
327 }
328
329 // This would be nicer if it just returned an iterator, but that runs into
330 // lifetime problems, because we need to borrow temp `CrateImplDefs`.
331 // FIXME add a context type here?
332 pub fn iterate_method_candidates<T>(
333     ty: &Canonical<Ty>,
334     db: &dyn HirDatabase,
335     env: Arc<TraitEnvironment>,
336     krate: CrateId,
337     traits_in_scope: &FxHashSet<TraitId>,
338     visible_from_module: Option<ModuleId>,
339     name: Option<&Name>,
340     mode: LookupMode,
341     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
342 ) -> Option<T> {
343     let mut slot = None;
344     iterate_method_candidates_impl(
345         ty,
346         db,
347         env,
348         krate,
349         traits_in_scope,
350         visible_from_module,
351         name,
352         mode,
353         &mut |ty, item| {
354             assert!(slot.is_none());
355             slot = callback(ty, item);
356             slot.is_some()
357         },
358     );
359     slot
360 }
361
362 fn iterate_method_candidates_impl(
363     ty: &Canonical<Ty>,
364     db: &dyn HirDatabase,
365     env: Arc<TraitEnvironment>,
366     krate: CrateId,
367     traits_in_scope: &FxHashSet<TraitId>,
368     visible_from_module: Option<ModuleId>,
369     name: Option<&Name>,
370     mode: LookupMode,
371     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
372 ) -> bool {
373     match mode {
374         LookupMode::MethodCall => {
375             // For method calls, rust first does any number of autoderef, and then one
376             // autoref (i.e. when the method takes &self or &mut self). We just ignore
377             // the autoref currently -- when we find a method matching the given name,
378             // we assume it fits.
379
380             // Also note that when we've got a receiver like &S, even if the method we
381             // find in the end takes &self, we still do the autoderef step (just as
382             // rustc does an autoderef and then autoref again).
383             let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
384
385             // We have to be careful about the order we're looking at candidates
386             // in here. Consider the case where we're resolving `x.clone()`
387             // where `x: &Vec<_>`. This resolves to the clone method with self
388             // type `Vec<_>`, *not* `&_`. I.e. we need to consider methods where
389             // the receiver type exactly matches before cases where we have to
390             // do autoref. But in the autoderef steps, the `&_` self type comes
391             // up *before* the `Vec<_>` self type.
392             //
393             // On the other hand, we don't want to just pick any by-value method
394             // before any by-autoref method; it's just that we need to consider
395             // the methods by autoderef order of *receiver types*, not *self
396             // types*.
397
398             let deref_chain = autoderef_method_receiver(db, krate, ty);
399             for i in 0..deref_chain.len() {
400                 if iterate_method_candidates_with_autoref(
401                     &deref_chain[i..],
402                     db,
403                     env.clone(),
404                     krate,
405                     traits_in_scope,
406                     visible_from_module,
407                     name,
408                     callback,
409                 ) {
410                     return true;
411                 }
412             }
413             false
414         }
415         LookupMode::Path => {
416             // No autoderef for path lookups
417             iterate_method_candidates_for_self_ty(
418                 &ty,
419                 db,
420                 env,
421                 krate,
422                 traits_in_scope,
423                 visible_from_module,
424                 name,
425                 callback,
426             )
427         }
428     }
429 }
430
431 fn iterate_method_candidates_with_autoref(
432     deref_chain: &[Canonical<Ty>],
433     db: &dyn HirDatabase,
434     env: Arc<TraitEnvironment>,
435     krate: CrateId,
436     traits_in_scope: &FxHashSet<TraitId>,
437     visible_from_module: Option<ModuleId>,
438     name: Option<&Name>,
439     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
440 ) -> bool {
441     if iterate_method_candidates_by_receiver(
442         &deref_chain[0],
443         &deref_chain[1..],
444         db,
445         env.clone(),
446         krate,
447         &traits_in_scope,
448         visible_from_module,
449         name,
450         &mut callback,
451     ) {
452         return true;
453     }
454     let refed = Canonical {
455         binders: deref_chain[0].binders.clone(),
456         value: TyKind::Ref(
457             Mutability::Not,
458             LifetimeData::Static.intern(&Interner),
459             deref_chain[0].value.clone(),
460         )
461         .intern(&Interner),
462     };
463     if iterate_method_candidates_by_receiver(
464         &refed,
465         deref_chain,
466         db,
467         env.clone(),
468         krate,
469         &traits_in_scope,
470         visible_from_module,
471         name,
472         &mut callback,
473     ) {
474         return true;
475     }
476     let ref_muted = Canonical {
477         binders: deref_chain[0].binders.clone(),
478         value: TyKind::Ref(
479             Mutability::Mut,
480             LifetimeData::Static.intern(&Interner),
481             deref_chain[0].value.clone(),
482         )
483         .intern(&Interner),
484     };
485     if iterate_method_candidates_by_receiver(
486         &ref_muted,
487         deref_chain,
488         db,
489         env,
490         krate,
491         &traits_in_scope,
492         visible_from_module,
493         name,
494         &mut callback,
495     ) {
496         return true;
497     }
498     false
499 }
500
501 fn iterate_method_candidates_by_receiver(
502     receiver_ty: &Canonical<Ty>,
503     rest_of_deref_chain: &[Canonical<Ty>],
504     db: &dyn HirDatabase,
505     env: Arc<TraitEnvironment>,
506     krate: CrateId,
507     traits_in_scope: &FxHashSet<TraitId>,
508     visible_from_module: Option<ModuleId>,
509     name: Option<&Name>,
510     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
511 ) -> bool {
512     // We're looking for methods with *receiver* type receiver_ty. These could
513     // be found in any of the derefs of receiver_ty, so we have to go through
514     // that.
515     for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
516         if iterate_inherent_methods(
517             self_ty,
518             db,
519             name,
520             Some(receiver_ty),
521             krate,
522             visible_from_module,
523             &mut callback,
524         ) {
525             return true;
526         }
527     }
528     for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
529         if iterate_trait_method_candidates(
530             self_ty,
531             db,
532             env.clone(),
533             krate,
534             &traits_in_scope,
535             name,
536             Some(receiver_ty),
537             &mut callback,
538         ) {
539             return true;
540         }
541     }
542     false
543 }
544
545 fn iterate_method_candidates_for_self_ty(
546     self_ty: &Canonical<Ty>,
547     db: &dyn HirDatabase,
548     env: Arc<TraitEnvironment>,
549     krate: CrateId,
550     traits_in_scope: &FxHashSet<TraitId>,
551     visible_from_module: Option<ModuleId>,
552     name: Option<&Name>,
553     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
554 ) -> bool {
555     if iterate_inherent_methods(self_ty, db, name, None, krate, visible_from_module, &mut callback)
556     {
557         return true;
558     }
559     iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
560 }
561
562 fn iterate_trait_method_candidates(
563     self_ty: &Canonical<Ty>,
564     db: &dyn HirDatabase,
565     env: Arc<TraitEnvironment>,
566     krate: CrateId,
567     traits_in_scope: &FxHashSet<TraitId>,
568     name: Option<&Name>,
569     receiver_ty: Option<&Canonical<Ty>>,
570     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
571 ) -> bool {
572     // if ty is `dyn Trait`, the trait doesn't need to be in scope
573     let inherent_trait =
574         self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
575     let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) {
576         // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
577         env.traits_in_scope_from_clauses(&self_ty.value)
578             .flat_map(|t| all_super_traits(db.upcast(), t))
579             .collect()
580     } else {
581         Vec::new()
582     };
583     let traits =
584         inherent_trait.chain(env_traits.into_iter()).chain(traits_in_scope.iter().copied());
585     'traits: for t in traits {
586         let data = db.trait_data(t);
587
588         // we'll be lazy about checking whether the type implements the
589         // trait, but if we find out it doesn't, we'll skip the rest of the
590         // iteration
591         let mut known_implemented = false;
592         for (_name, item) in data.items.iter() {
593             // Don't pass a `visible_from_module` down to `is_valid_candidate`,
594             // since only inherent methods should be included into visibility checking.
595             if !is_valid_candidate(db, name, receiver_ty, *item, self_ty, None) {
596                 continue;
597             }
598             if !known_implemented {
599                 let goal = generic_implements_goal(db, env.clone(), t, self_ty.clone());
600                 if db.trait_solve(krate, goal).is_none() {
601                     continue 'traits;
602                 }
603             }
604             known_implemented = true;
605             if callback(&self_ty.value, *item) {
606                 return true;
607             }
608         }
609     }
610     false
611 }
612
613 fn iterate_inherent_methods(
614     self_ty: &Canonical<Ty>,
615     db: &dyn HirDatabase,
616     name: Option<&Name>,
617     receiver_ty: Option<&Canonical<Ty>>,
618     krate: CrateId,
619     visible_from_module: Option<ModuleId>,
620     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
621 ) -> bool {
622     let def_crates = match self_ty.value.def_crates(db, krate) {
623         Some(k) => k,
624         None => return false,
625     };
626     for krate in def_crates {
627         let impls = db.inherent_impls_in_crate(krate);
628
629         for &impl_def in impls.for_self_ty(&self_ty.value) {
630             for &item in db.impl_data(impl_def).items.iter() {
631                 if !is_valid_candidate(db, name, receiver_ty, item, self_ty, visible_from_module) {
632                     continue;
633                 }
634                 // we have to check whether the self type unifies with the type
635                 // that the impl is for. If we have a receiver type, this
636                 // already happens in `is_valid_candidate` above; if not, we
637                 // check it here
638                 if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() {
639                     cov_mark::hit!(impl_self_type_match_without_receiver);
640                     continue;
641                 }
642                 if callback(&self_ty.value, item) {
643                     return true;
644                 }
645             }
646         }
647     }
648     false
649 }
650
651 /// Returns the self type for the index trait call.
652 pub fn resolve_indexing_op(
653     db: &dyn HirDatabase,
654     ty: &Canonical<Ty>,
655     env: Arc<TraitEnvironment>,
656     krate: CrateId,
657     index_trait: TraitId,
658 ) -> Option<Canonical<Ty>> {
659     let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
660     let deref_chain = autoderef_method_receiver(db, krate, ty);
661     for ty in deref_chain {
662         let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
663         if db.trait_solve(krate, goal).is_some() {
664             return Some(ty);
665         }
666     }
667     None
668 }
669
670 fn is_valid_candidate(
671     db: &dyn HirDatabase,
672     name: Option<&Name>,
673     receiver_ty: Option<&Canonical<Ty>>,
674     item: AssocItemId,
675     self_ty: &Canonical<Ty>,
676     visible_from_module: Option<ModuleId>,
677 ) -> bool {
678     match item {
679         AssocItemId::FunctionId(m) => {
680             let data = db.function_data(m);
681             if let Some(name) = name {
682                 if &data.name != name {
683                     return false;
684                 }
685             }
686             if let Some(receiver_ty) = receiver_ty {
687                 if !data.has_self_param() {
688                     return false;
689                 }
690                 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
691                     Some(ty) => ty,
692                     None => return false,
693                 };
694                 if transformed_receiver_ty != receiver_ty.value {
695                     return false;
696                 }
697             }
698             if let Some(from_module) = visible_from_module {
699                 if !db.function_visibility(m).is_visible_from(db.upcast(), from_module) {
700                     cov_mark::hit!(autoderef_candidate_not_visible);
701                     return false;
702                 }
703             }
704
705             true
706         }
707         AssocItemId::ConstId(c) => {
708             let data = db.const_data(c);
709             name.map_or(true, |name| data.name.as_ref() == Some(name)) && receiver_ty.is_none()
710         }
711         _ => false,
712     }
713 }
714
715 pub(crate) fn inherent_impl_substs(
716     db: &dyn HirDatabase,
717     impl_id: ImplId,
718     self_ty: &Canonical<Ty>,
719 ) -> Option<Substitution> {
720     // we create a var for each type parameter of the impl; we need to keep in
721     // mind here that `self_ty` might have vars of its own
722     let self_ty_vars = self_ty.binders.len(&Interner);
723     let vars = TyBuilder::subst_for_def(db, impl_id)
724         .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
725         .build();
726     let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars);
727     let mut kinds = self_ty.binders.interned().to_vec();
728     kinds.extend(
729         iter::repeat(chalk_ir::WithKind::new(
730             chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
731             UniverseIndex::ROOT,
732         ))
733         .take(vars.len(&Interner)),
734     );
735     let tys = Canonical {
736         binders: CanonicalVarKinds::from_iter(&Interner, kinds),
737         value: (self_ty_with_vars, self_ty.value.clone()),
738     };
739     let substs = super::infer::unify(&tys)?;
740     // We only want the substs for the vars we added, not the ones from self_ty.
741     // Also, if any of the vars we added are still in there, we replace them by
742     // Unknown. I think this can only really happen if self_ty contained
743     // Unknown, and in that case we want the result to contain Unknown in those
744     // places again.
745     let suffix =
746         Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars));
747     Some(fallback_bound_vars(suffix, self_ty_vars))
748 }
749
750 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
751 /// num_vars_to_keep) by `TyKind::Unknown`.
752 fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
753     s.fold_binders(
754         &mut |ty, binders| {
755             if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
756                 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
757                     TyKind::Error.intern(&Interner)
758                 } else {
759                     ty
760                 }
761             } else {
762                 ty
763             }
764         },
765         DebruijnIndex::INNERMOST,
766     )
767 }
768
769 fn transform_receiver_ty(
770     db: &dyn HirDatabase,
771     function_id: FunctionId,
772     self_ty: &Canonical<Ty>,
773 ) -> Option<Ty> {
774     let substs = match function_id.lookup(db.upcast()).container {
775         AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
776             .push(self_ty.value.clone())
777             .fill_with_unknown()
778             .build(),
779         AssocContainerId::ImplId(impl_id) => {
780             let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
781             TyBuilder::subst_for_def(db, function_id)
782                 .use_parent_substs(&impl_substs)
783                 .fill_with_unknown()
784                 .build()
785         }
786         AssocContainerId::ModuleId(_) => unreachable!(),
787     };
788     let sig = db.callable_item_signature(function_id.into());
789     Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs))
790 }
791
792 pub fn implements_trait(
793     ty: &Canonical<Ty>,
794     db: &dyn HirDatabase,
795     env: Arc<TraitEnvironment>,
796     krate: CrateId,
797     trait_: TraitId,
798 ) -> bool {
799     let goal = generic_implements_goal(db, env, trait_, ty.clone());
800     let solution = db.trait_solve(krate, goal);
801
802     solution.is_some()
803 }
804
805 pub fn implements_trait_unique(
806     ty: &Canonical<Ty>,
807     db: &dyn HirDatabase,
808     env: Arc<TraitEnvironment>,
809     krate: CrateId,
810     trait_: TraitId,
811 ) -> bool {
812     let goal = generic_implements_goal(db, env, trait_, ty.clone());
813     let solution = db.trait_solve(krate, goal);
814
815     matches!(solution, Some(crate::Solution::Unique(_)))
816 }
817
818 /// This creates Substs for a trait with the given Self type and type variables
819 /// for all other parameters, to query Chalk with it.
820 fn generic_implements_goal(
821     db: &dyn HirDatabase,
822     env: Arc<TraitEnvironment>,
823     trait_: TraitId,
824     self_ty: Canonical<Ty>,
825 ) -> Canonical<InEnvironment<super::DomainGoal>> {
826     let mut kinds = self_ty.binders.interned().to_vec();
827     let trait_ref = TyBuilder::trait_ref(db, trait_)
828         .push(self_ty.value)
829         .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
830         .build();
831     kinds.extend(
832         iter::repeat(chalk_ir::WithKind::new(
833             chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
834             UniverseIndex::ROOT,
835         ))
836         .take(trait_ref.substitution.len(&Interner) - 1),
837     );
838     let obligation = trait_ref.cast(&Interner);
839     Canonical {
840         binders: CanonicalVarKinds::from_iter(&Interner, kinds),
841         value: InEnvironment::new(env.env.clone(), obligation),
842     }
843 }
844
845 fn autoderef_method_receiver(
846     db: &dyn HirDatabase,
847     krate: CrateId,
848     ty: InEnvironment<Canonical<Ty>>,
849 ) -> Vec<Canonical<Ty>> {
850     let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
851     // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
852     if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) {
853         let kinds = deref_chain.last().unwrap().binders.clone();
854         let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
855         deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
856     }
857     deref_chain
858 }