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