]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/method_resolution.rs
6c34982a1892d70b55fcb53452e0dcec108f5b9d
[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};
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     to_chalk_trait_id,
23     utils::all_super_traits,
24     AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
25     Scalar, Substitution, TraitEnvironment, TraitRef, Ty, 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.interned(&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::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
59             TyKind::Function(FnPointer { num_args, sig, .. }) => {
60                 TyFingerprint::FnPtr(num_args, 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.value.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.value);
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.value) {
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.interned(&Interner) {
246             TyKind::Adt(AdtId(def_id), _) => {
247                 return mod_to_crate_ids(def_id.module(db.upcast()));
248             }
249             TyKind::ForeignType(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 { value: ty.clone(), environment: 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                 name,
424                 callback,
425             )
426         }
427     }
428 }
429
430 fn iterate_method_candidates_with_autoref(
431     deref_chain: &[Canonical<Ty>],
432     db: &dyn HirDatabase,
433     env: Arc<TraitEnvironment>,
434     krate: CrateId,
435     traits_in_scope: &FxHashSet<TraitId>,
436     visible_from_module: Option<ModuleId>,
437     name: Option<&Name>,
438     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
439 ) -> bool {
440     if iterate_method_candidates_by_receiver(
441         &deref_chain[0],
442         &deref_chain[1..],
443         db,
444         env.clone(),
445         krate,
446         &traits_in_scope,
447         visible_from_module,
448         name,
449         &mut callback,
450     ) {
451         return true;
452     }
453     let refed = Canonical {
454         kinds: deref_chain[0].kinds.clone(),
455         value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner),
456     };
457     if iterate_method_candidates_by_receiver(
458         &refed,
459         deref_chain,
460         db,
461         env.clone(),
462         krate,
463         &traits_in_scope,
464         visible_from_module,
465         name,
466         &mut callback,
467     ) {
468         return true;
469     }
470     let ref_muted = Canonical {
471         kinds: deref_chain[0].kinds.clone(),
472         value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner),
473     };
474     if iterate_method_candidates_by_receiver(
475         &ref_muted,
476         deref_chain,
477         db,
478         env,
479         krate,
480         &traits_in_scope,
481         visible_from_module,
482         name,
483         &mut callback,
484     ) {
485         return true;
486     }
487     false
488 }
489
490 fn iterate_method_candidates_by_receiver(
491     receiver_ty: &Canonical<Ty>,
492     rest_of_deref_chain: &[Canonical<Ty>],
493     db: &dyn HirDatabase,
494     env: Arc<TraitEnvironment>,
495     krate: CrateId,
496     traits_in_scope: &FxHashSet<TraitId>,
497     visible_from_module: Option<ModuleId>,
498     name: Option<&Name>,
499     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
500 ) -> bool {
501     // We're looking for methods with *receiver* type receiver_ty. These could
502     // be found in any of the derefs of receiver_ty, so we have to go through
503     // that.
504     for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
505         if iterate_inherent_methods(
506             self_ty,
507             db,
508             name,
509             Some(receiver_ty),
510             krate,
511             visible_from_module,
512             &mut callback,
513         ) {
514             return true;
515         }
516     }
517     for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
518         if iterate_trait_method_candidates(
519             self_ty,
520             db,
521             env.clone(),
522             krate,
523             &traits_in_scope,
524             name,
525             Some(receiver_ty),
526             &mut callback,
527         ) {
528             return true;
529         }
530     }
531     false
532 }
533
534 fn iterate_method_candidates_for_self_ty(
535     self_ty: &Canonical<Ty>,
536     db: &dyn HirDatabase,
537     env: Arc<TraitEnvironment>,
538     krate: CrateId,
539     traits_in_scope: &FxHashSet<TraitId>,
540     name: Option<&Name>,
541     mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
542 ) -> bool {
543     if iterate_inherent_methods(self_ty, db, name, None, krate, None, &mut callback) {
544         return true;
545     }
546     iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
547 }
548
549 fn iterate_trait_method_candidates(
550     self_ty: &Canonical<Ty>,
551     db: &dyn HirDatabase,
552     env: Arc<TraitEnvironment>,
553     krate: CrateId,
554     traits_in_scope: &FxHashSet<TraitId>,
555     name: Option<&Name>,
556     receiver_ty: Option<&Canonical<Ty>>,
557     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
558 ) -> bool {
559     // if ty is `dyn Trait`, the trait doesn't need to be in scope
560     let inherent_trait =
561         self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
562     let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) {
563         // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
564         env.traits_in_scope_from_clauses(&self_ty.value)
565             .flat_map(|t| all_super_traits(db.upcast(), t))
566             .collect()
567     } else {
568         Vec::new()
569     };
570     let traits =
571         inherent_trait.chain(env_traits.into_iter()).chain(traits_in_scope.iter().copied());
572     'traits: for t in traits {
573         let data = db.trait_data(t);
574
575         // we'll be lazy about checking whether the type implements the
576         // trait, but if we find out it doesn't, we'll skip the rest of the
577         // iteration
578         let mut known_implemented = false;
579         for (_name, item) in data.items.iter() {
580             if !is_valid_candidate(db, name, receiver_ty, *item, self_ty, None) {
581                 continue;
582             }
583             if !known_implemented {
584                 let goal = generic_implements_goal(db, env.clone(), t, self_ty.clone());
585                 if db.trait_solve(krate, goal).is_none() {
586                     continue 'traits;
587                 }
588             }
589             known_implemented = true;
590             if callback(&self_ty.value, *item) {
591                 return true;
592             }
593         }
594     }
595     false
596 }
597
598 fn iterate_inherent_methods(
599     self_ty: &Canonical<Ty>,
600     db: &dyn HirDatabase,
601     name: Option<&Name>,
602     receiver_ty: Option<&Canonical<Ty>>,
603     krate: CrateId,
604     visible_from_module: Option<ModuleId>,
605     callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
606 ) -> bool {
607     let def_crates = match self_ty.value.def_crates(db, krate) {
608         Some(k) => k,
609         None => return false,
610     };
611     for krate in def_crates {
612         let impls = db.inherent_impls_in_crate(krate);
613
614         for &impl_def in impls.for_self_ty(&self_ty.value) {
615             for &item in db.impl_data(impl_def).items.iter() {
616                 if !is_valid_candidate(db, name, receiver_ty, item, self_ty, visible_from_module) {
617                     continue;
618                 }
619                 // we have to check whether the self type unifies with the type
620                 // that the impl is for. If we have a receiver type, this
621                 // already happens in `is_valid_candidate` above; if not, we
622                 // check it here
623                 if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() {
624                     cov_mark::hit!(impl_self_type_match_without_receiver);
625                     continue;
626                 }
627                 if callback(&self_ty.value, item) {
628                     return true;
629                 }
630             }
631         }
632     }
633     false
634 }
635
636 /// Returns the self type for the index trait call.
637 pub fn resolve_indexing_op(
638     db: &dyn HirDatabase,
639     ty: &Canonical<Ty>,
640     env: Arc<TraitEnvironment>,
641     krate: CrateId,
642     index_trait: TraitId,
643 ) -> Option<Canonical<Ty>> {
644     let ty = InEnvironment { value: ty.clone(), environment: env.clone() };
645     let deref_chain = autoderef_method_receiver(db, krate, ty);
646     for ty in deref_chain {
647         let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
648         if db.trait_solve(krate, goal).is_some() {
649             return Some(ty);
650         }
651     }
652     None
653 }
654
655 fn is_valid_candidate(
656     db: &dyn HirDatabase,
657     name: Option<&Name>,
658     receiver_ty: Option<&Canonical<Ty>>,
659     item: AssocItemId,
660     self_ty: &Canonical<Ty>,
661     visible_from_module: Option<ModuleId>,
662 ) -> bool {
663     match item {
664         AssocItemId::FunctionId(m) => {
665             let data = db.function_data(m);
666             if let Some(name) = name {
667                 if &data.name != name {
668                     return false;
669                 }
670             }
671             if let Some(receiver_ty) = receiver_ty {
672                 if !data.has_self_param {
673                     return false;
674                 }
675                 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
676                     Some(ty) => ty,
677                     None => return false,
678                 };
679                 if transformed_receiver_ty != receiver_ty.value {
680                     return false;
681                 }
682             }
683             if let Some(from_module) = visible_from_module {
684                 if !db.fn_visibility(m).is_visible_from(db.upcast(), from_module) {
685                     return false;
686                 }
687             }
688
689             true
690         }
691         AssocItemId::ConstId(c) => {
692             let data = db.const_data(c);
693             name.map_or(true, |name| data.name.as_ref() == Some(name)) && receiver_ty.is_none()
694         }
695         _ => false,
696     }
697 }
698
699 pub(crate) fn inherent_impl_substs(
700     db: &dyn HirDatabase,
701     impl_id: ImplId,
702     self_ty: &Canonical<Ty>,
703 ) -> Option<Substitution> {
704     // we create a var for each type parameter of the impl; we need to keep in
705     // mind here that `self_ty` might have vars of its own
706     let vars = Substitution::build_for_def(db, impl_id)
707         .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len())
708         .build();
709     let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
710     let mut kinds = self_ty.kinds.to_vec();
711     kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len()));
712     let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) };
713     let substs = super::infer::unify(&tys);
714     // We only want the substs for the vars we added, not the ones from self_ty.
715     // Also, if any of the vars we added are still in there, we replace them by
716     // Unknown. I think this can only really happen if self_ty contained
717     // Unknown, and in that case we want the result to contain Unknown in those
718     // places again.
719     substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len()))
720 }
721
722 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
723 /// num_vars_to_keep) by `TyKind::Unknown`.
724 fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
725     s.fold_binders(
726         &mut |ty, binders| {
727             if let TyKind::BoundVar(bound) = ty.interned(&Interner) {
728                 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
729                     TyKind::Unknown.intern(&Interner)
730                 } else {
731                     ty
732                 }
733             } else {
734                 ty
735             }
736         },
737         DebruijnIndex::INNERMOST,
738     )
739 }
740
741 fn transform_receiver_ty(
742     db: &dyn HirDatabase,
743     function_id: FunctionId,
744     self_ty: &Canonical<Ty>,
745 ) -> Option<Ty> {
746     let substs = match function_id.lookup(db.upcast()).container {
747         AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id)
748             .push(self_ty.value.clone())
749             .fill_with_unknown()
750             .build(),
751         AssocContainerId::ImplId(impl_id) => {
752             let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
753             Substitution::build_for_def(db, function_id)
754                 .use_parent_substs(&impl_substs)
755                 .fill_with_unknown()
756                 .build()
757         }
758         AssocContainerId::ModuleId(_) => unreachable!(),
759     };
760     let sig = db.callable_item_signature(function_id.into());
761     Some(sig.value.params()[0].clone().subst_bound_vars(&substs))
762 }
763
764 pub fn implements_trait(
765     ty: &Canonical<Ty>,
766     db: &dyn HirDatabase,
767     env: Arc<TraitEnvironment>,
768     krate: CrateId,
769     trait_: TraitId,
770 ) -> bool {
771     let goal = generic_implements_goal(db, env, trait_, ty.clone());
772     let solution = db.trait_solve(krate, goal);
773
774     solution.is_some()
775 }
776
777 pub fn implements_trait_unique(
778     ty: &Canonical<Ty>,
779     db: &dyn HirDatabase,
780     env: Arc<TraitEnvironment>,
781     krate: CrateId,
782     trait_: TraitId,
783 ) -> bool {
784     let goal = generic_implements_goal(db, env, trait_, ty.clone());
785     let solution = db.trait_solve(krate, goal);
786
787     matches!(solution, Some(crate::traits::Solution::Unique(_)))
788 }
789
790 /// This creates Substs for a trait with the given Self type and type variables
791 /// for all other parameters, to query Chalk with it.
792 fn generic_implements_goal(
793     db: &dyn HirDatabase,
794     env: Arc<TraitEnvironment>,
795     trait_: TraitId,
796     self_ty: Canonical<Ty>,
797 ) -> Canonical<InEnvironment<super::DomainGoal>> {
798     let mut kinds = self_ty.kinds.to_vec();
799     let substs = super::Substitution::build_for_def(db, trait_)
800         .push(self_ty.value)
801         .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
802         .build();
803     kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
804     let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
805     let obligation = trait_ref.cast(&Interner);
806     Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
807 }
808
809 fn autoderef_method_receiver(
810     db: &dyn HirDatabase,
811     krate: CrateId,
812     ty: InEnvironment<Canonical<Ty>>,
813 ) -> Vec<Canonical<Ty>> {
814     let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
815     // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
816     if let Some(TyKind::Array(parameters)) =
817         deref_chain.last().map(|ty| ty.value.interned(&Interner))
818     {
819         let kinds = deref_chain.last().unwrap().kinds.clone();
820         let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
821         deref_chain.push(Canonical { value: unsized_ty, kinds })
822     }
823     deref_chain
824 }