1use std::{cell::RefCell, convert::Infallible, ops::ControlFlow};
5
6use base_db::FxIndexMap;
7use hir_def::{
8 AssocItemId, FunctionId, GenericParamId, ImplId, ItemContainerId, TraitId,
9 hir::generics::GenericParams,
10 signatures::{FunctionSignature, TraitFlags, TraitSignature},
11};
12use hir_expand::name::Name;
13use rustc_ast_ir::Mutability;
14use rustc_hash::FxHashSet;
15use rustc_type_ir::{
16 InferTy, TypeVisitableExt, Upcast, Variance,
17 elaborate::{self, supertrait_def_ids},
18 fast_reject::{DeepRejectCtxt, TreatParams, simplify_type},
19 inherent::{BoundExistentialPredicates as _, IntoKind, Ty as _},
20};
21use smallvec::{SmallVec, smallvec};
22use tracing::{debug, instrument};
23
24use self::CandidateKind::*;
25pub(super) use self::PickKind::*;
26use crate::{
27 autoderef::Autoderef,
28 db::HirDatabase,
29 lower::GenericPredicates,
30 method_resolution::{
31 CandidateId, CandidateSource, InherentImpls, MethodError, MethodResolutionContext,
32 simplified_type_module, with_incoherent_inherent_impls,
33 },
34 next_solver::{
35 Binder, Canonical, ClauseKind, DbInterner, FnSig, GenericArg, GenericArgs, Goal, ParamEnv,
36 PolyTraitRef, Predicate, Region, SimplifiedType, TraitRef, Ty, TyKind, Unnormalized,
37 infer::{
38 BoundRegionConversionTime, InferCtxt, InferOk,
39 canonical::{QueryResponse, canonicalizer::OriginalQueryValues},
40 select::{ImplSource, Selection, SelectionResult},
41 traits::{Obligation, ObligationCause, PredicateObligation},
42 },
43 obligation_ctxt::ObligationCtxt,
44 util::clauses_as_obligations,
45 },
46};
47
48struct ProbeContext<'a, 'db, Choice> {
49 ctx: &'a MethodResolutionContext<'a, 'db>,
50 mode: Mode,
51
52 orig_steps_var_values: &'a OriginalQueryValues<'db>,
55 steps: &'a [CandidateStep<'db>],
56
57 inherent_candidates: Vec<Candidate<'db>>,
58 extension_candidates: Vec<Candidate<'db>>,
59 impl_dups: FxHashSet<ImplId>,
60
61 private_candidates: Vec<Candidate<'db>>,
64
65 static_candidates: Vec<CandidateSource>,
68
69 choice: Choice,
70}
71
72#[derive(Debug)]
73pub struct CandidateWithPrivate<'db> {
74 pub candidate: Candidate<'db>,
75 pub is_visible: bool,
76}
77
78#[derive(Debug, Clone)]
79pub struct Candidate<'db> {
80 pub item: CandidateId,
81 pub kind: CandidateKind<'db>,
82}
83
84#[derive(Debug, Clone)]
85pub enum CandidateKind<'db> {
86 InherentImplCandidate { impl_def_id: ImplId, receiver_steps: usize },
87 ObjectCandidate(PolyTraitRef<'db>),
88 TraitCandidate(PolyTraitRef<'db>),
89 WhereClauseCandidate(PolyTraitRef<'db>),
90}
91
92#[derive(Debug, PartialEq, Eq, Copy, Clone)]
93enum ProbeResult {
94 NoMatch,
95 Match,
96}
97
98#[derive(Debug, PartialEq, Copy, Clone)]
111pub enum AutorefOrPtrAdjustment {
112 Autoref {
115 mutbl: Mutability,
116
117 unsize: bool,
120 },
121 ToConstPtr,
123}
124
125impl AutorefOrPtrAdjustment {
126 fn get_unsize(&self) -> bool {
127 match self {
128 AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize,
129 AutorefOrPtrAdjustment::ToConstPtr => false,
130 }
131 }
132}
133
134#[derive(Debug)]
138struct PickConstraintsForShadowed {
139 autoderefs: usize,
140 receiver_steps: Option<usize>,
141 def_id: CandidateId,
142}
143
144impl PickConstraintsForShadowed {
145 fn may_shadow_based_on_autoderefs(&self, autoderefs: usize) -> bool {
146 autoderefs == self.autoderefs
147 }
148
149 fn candidate_may_shadow(&self, candidate: &Candidate<'_>) -> bool {
150 candidate.item != self.def_id
152 && match candidate.kind {
156 CandidateKind::InherentImplCandidate { receiver_steps, .. } => match self.receiver_steps {
157 Some(shadowed_receiver_steps) => receiver_steps > shadowed_receiver_steps,
158 _ => false
159 },
160 _ => false
161 }
162 }
163}
164
165#[derive(Debug, Clone)]
166pub struct Pick<'db> {
167 pub item: CandidateId,
168 pub kind: PickKind<'db>,
169
170 pub autoderefs: usize,
175
176 pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment>,
179 pub self_ty: Ty<'db>,
180
181 pub receiver_steps: Option<usize>,
185
186 pub shadowed_candidates: Vec<CandidateId>,
188}
189
190#[derive(Clone, Debug, PartialEq, Eq)]
191pub enum PickKind<'db> {
192 InherentImplPick(ImplId),
193 ObjectPick(TraitId),
194 TraitPick(TraitId),
195 WhereClausePick(
196 PolyTraitRef<'db>,
198 ),
199}
200
201pub(crate) type PickResult<'db> = Result<Pick<'db>, MethodError<'db>>;
202
203#[derive(PartialEq, Eq, Copy, Clone, Debug)]
204pub enum Mode {
205 MethodCall,
209 Path,
213}
214
215#[derive(Debug, Clone)]
216pub struct CandidateStep<'db> {
217 pub self_ty: Canonical<'db, QueryResponse<'db, Ty<'db>>>,
218 pub self_ty_is_opaque: bool,
219 pub autoderefs: usize,
220 pub from_unsafe_deref: bool,
226 pub unsize: bool,
227 pub reachable_via_deref: bool,
236}
237
238#[derive(Clone, Debug)]
239struct MethodAutoderefStepsResult<'db> {
240 pub steps: SmallVec<[CandidateStep<'db>; 3]>,
243 pub opt_bad_ty: Option<MethodAutoderefBadTy<'db>>,
245 pub reached_recursion_limit: bool,
248}
249
250#[derive(Debug, Clone)]
251struct MethodAutoderefBadTy<'db> {
252 pub reached_raw_pointer: bool,
253 pub ty: Canonical<'db, QueryResponse<'db, Ty<'db>>>,
254}
255
256impl<'a, 'db> MethodResolutionContext<'a, 'db> {
257 #[instrument(level = "debug", skip(self))]
258 pub fn probe_for_name(&self, mode: Mode, item_name: Name, self_ty: Ty<'db>) -> PickResult<'db> {
259 self.probe_op(mode, self_ty, ProbeForNameChoice { private_candidate: None, item_name })
260 }
261
262 #[instrument(level = "debug", skip(self))]
263 pub fn probe_all(
264 &self,
265 mode: Mode,
266 self_ty: Ty<'db>,
267 ) -> impl Iterator<Item = CandidateWithPrivate<'db>> {
268 self.probe_op(mode, self_ty, ProbeAllChoice::new()).candidates.into_inner().into_values()
269 }
270
271 fn probe_op<Choice: ProbeChoice<'db>>(
272 &self,
273 mode: Mode,
274 self_ty: Ty<'db>,
275 choice: Choice,
276 ) -> Choice::FinalChoice {
277 let mut orig_values = OriginalQueryValues::default();
278 let query_input = self.infcx.canonicalize_query(self_ty, &mut orig_values);
279 let steps = match mode {
280 Mode::MethodCall => self.method_autoderef_steps(&query_input),
281 Mode::Path => self.infcx.probe(|_| {
282 let infcx = self.infcx;
288 let (self_ty, var_values) =
289 infcx.instantiate_canonical(self.call_span, &query_input);
290 debug!(?self_ty, ?query_input, "probe_op: Mode::Path");
291 let prev_opaque_entries =
292 self.infcx.inner.borrow_mut().opaque_types().num_entries();
293 MethodAutoderefStepsResult {
294 steps: smallvec![CandidateStep {
295 self_ty: self.infcx.make_query_response_ignoring_pending_obligations(
296 var_values,
297 self_ty,
298 prev_opaque_entries
299 ),
300 self_ty_is_opaque: false,
301 autoderefs: 0,
302 from_unsafe_deref: false,
303 unsize: false,
304 reachable_via_deref: true,
305 }],
306 opt_bad_ty: None,
307 reached_recursion_limit: false,
308 }
309 }),
310 };
311
312 if steps.reached_recursion_limit {
313 }
315
316 if let Some(bad_ty) = &steps.opt_bad_ty {
319 if bad_ty.reached_raw_pointer
320 && !self.features.arbitrary_self_types_pointers
321 && self.edition.at_least_2018()
322 {
323 } else {
336 let ty = &bad_ty.ty;
340 let ty = self
341 .infcx
342 .instantiate_query_response_and_region_obligations(
343 &ObligationCause::new(self.receiver_span),
344 self.param_env,
345 &orig_values,
346 ty,
347 )
348 .unwrap_or_else(|_| panic!("instantiating {:?} failed?", ty));
349 let ty = self.infcx.resolve_vars_if_possible(ty.value);
350 match ty.kind() {
351 TyKind::Infer(InferTy::TyVar(_)) => {
352 }
354 TyKind::Error(_) => {}
355 _ => panic!("unexpected bad final type in method autoderef"),
356 };
357 return Choice::final_choice_from_err(MethodError::ErrorReported);
358 }
359 }
360
361 debug!("ProbeContext: steps for self_ty={:?} are {:?}", self_ty, steps);
362
363 self.infcx.probe(|_| {
366 let mut probe_cx = ProbeContext::new(self, mode, &orig_values, &steps.steps, choice);
367
368 probe_cx.assemble_inherent_candidates();
369 probe_cx.assemble_extension_candidates_for_traits_in_scope();
370 Choice::choose(probe_cx)
371 })
372 }
373
374 fn method_autoderef_steps(
375 &self,
376 self_ty: &Canonical<'db, Ty<'db>>,
377 ) -> MethodAutoderefStepsResult<'db> {
378 self.infcx.probe(|_| {
379 debug!("method_autoderef_steps({:?})", self_ty);
380
381 let infcx = self.infcx;
385 let (self_ty, inference_vars) =
386 infcx.instantiate_canonical(self.receiver_span, self_ty);
387 let prev_opaque_entries = infcx.inner.borrow_mut().opaque_types().num_entries();
388
389 let self_ty_is_opaque = |ty: Ty<'_>| {
390 if let TyKind::Infer(InferTy::TyVar(vid)) = ty.kind() {
391 infcx.has_opaques_with_sub_unified_hidden_type(vid)
392 } else {
393 false
394 }
395 };
396
397 let mut autoderef_via_deref =
407 Autoderef::new(infcx, self.param_env, self_ty, self.receiver_span)
408 .include_raw_pointers();
409
410 let mut reached_raw_pointer = false;
411 let arbitrary_self_types_enabled =
412 self.features.arbitrary_self_types || self.features.arbitrary_self_types_pointers;
413 let (mut steps, reached_recursion_limit) = if arbitrary_self_types_enabled {
414 let reachable_via_deref =
415 autoderef_via_deref.by_ref().map(|_| true).chain(std::iter::repeat(false));
416
417 let mut autoderef_via_receiver =
418 Autoderef::new(infcx, self.param_env, self_ty, self.receiver_span)
419 .include_raw_pointers()
420 .use_receiver_trait();
421 let steps = autoderef_via_receiver
422 .by_ref()
423 .zip(reachable_via_deref)
424 .map(|((ty, d), reachable_via_deref)| {
425 let step = CandidateStep {
426 self_ty: infcx.make_query_response_ignoring_pending_obligations(
427 inference_vars,
428 ty,
429 prev_opaque_entries,
430 ),
431 self_ty_is_opaque: self_ty_is_opaque(ty),
432 autoderefs: d,
433 from_unsafe_deref: reached_raw_pointer,
434 unsize: false,
435 reachable_via_deref,
436 };
437 if ty.is_raw_ptr() {
438 reached_raw_pointer = true;
440 }
441 step
442 })
443 .collect::<SmallVec<[_; _]>>();
444 (steps, autoderef_via_receiver.reached_recursion_limit())
445 } else {
446 let steps = autoderef_via_deref
447 .by_ref()
448 .map(|(ty, d)| {
449 let step = CandidateStep {
450 self_ty: infcx.make_query_response_ignoring_pending_obligations(
451 inference_vars,
452 ty,
453 prev_opaque_entries,
454 ),
455 self_ty_is_opaque: self_ty_is_opaque(ty),
456 autoderefs: d,
457 from_unsafe_deref: reached_raw_pointer,
458 unsize: false,
459 reachable_via_deref: true,
460 };
461 if ty.is_raw_ptr() {
462 reached_raw_pointer = true;
464 }
465 step
466 })
467 .collect();
468 (steps, autoderef_via_deref.reached_recursion_limit())
469 };
470 let final_ty = autoderef_via_deref.final_ty();
471 let opt_bad_ty = match final_ty.kind() {
472 TyKind::Infer(InferTy::TyVar(_)) if !self_ty_is_opaque(final_ty) => {
473 Some(MethodAutoderefBadTy {
474 reached_raw_pointer,
475 ty: infcx.make_query_response_ignoring_pending_obligations(
476 inference_vars,
477 final_ty,
478 prev_opaque_entries,
479 ),
480 })
481 }
482 TyKind::Error(_) => Some(MethodAutoderefBadTy {
483 reached_raw_pointer,
484 ty: infcx.make_query_response_ignoring_pending_obligations(
485 inference_vars,
486 final_ty,
487 prev_opaque_entries,
488 ),
489 }),
490 TyKind::Array(elem_ty, _) => {
491 let autoderefs = steps.iter().filter(|s| s.reachable_via_deref).count() - 1;
492 steps.push(CandidateStep {
493 self_ty: infcx.make_query_response_ignoring_pending_obligations(
494 inference_vars,
495 Ty::new_slice(infcx.interner, elem_ty),
496 prev_opaque_entries,
497 ),
498 self_ty_is_opaque: false,
499 autoderefs,
500 from_unsafe_deref: reached_raw_pointer,
503 unsize: true,
504 reachable_via_deref: true, });
507
508 None
509 }
510 _ => None,
511 };
512
513 debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty);
514 MethodAutoderefStepsResult { steps, opt_bad_ty, reached_recursion_limit }
515 })
516 }
517}
518
519trait ProbeChoice<'db>: Sized {
520 type Choice;
521 type FinalChoice;
522
523 fn with_impl_or_trait_item<'a>(
527 this: &mut ProbeContext<'a, 'db, Self>,
528 items: &[(Name, AssocItemId)],
529 callback: impl FnMut(&mut ProbeContext<'a, 'db, Self>, CandidateId),
530 );
531
532 fn consider_candidates(
533 this: &ProbeContext<'_, 'db, Self>,
534 self_ty: Ty<'db>,
535 candidates: Vec<&Candidate<'db>>,
536 ) -> ControlFlow<Self::Choice>;
537
538 fn consider_private_candidates(
539 this: &mut ProbeContext<'_, 'db, Self>,
540 self_ty: Ty<'db>,
541 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
542 );
543
544 fn map_choice_pick(
545 choice: Self::Choice,
546 f: impl FnOnce(Pick<'db>) -> Pick<'db>,
547 ) -> Self::Choice;
548
549 fn check_by_value_method_shadowing(
550 this: &mut ProbeContext<'_, 'db, Self>,
551 by_value_pick: &Self::Choice,
552 step: &CandidateStep<'db>,
553 self_ty: Ty<'db>,
554 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
555 ) -> ControlFlow<Self::Choice>;
556
557 fn check_autorefed_method_shadowing(
558 this: &mut ProbeContext<'_, 'db, Self>,
559 autoref_pick: &Self::Choice,
560 step: &CandidateStep<'db>,
561 self_ty: Ty<'db>,
562 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
563 ) -> ControlFlow<Self::Choice>;
564
565 fn final_choice_from_err(err: MethodError<'db>) -> Self::FinalChoice;
566
567 fn choose(this: ProbeContext<'_, 'db, Self>) -> Self::FinalChoice;
568}
569
570#[derive(Debug)]
571struct ProbeForNameChoice<'db> {
572 item_name: Name,
573
574 private_candidate: Option<Pick<'db>>,
576}
577
578impl<'db> ProbeChoice<'db> for ProbeForNameChoice<'db> {
579 type Choice = PickResult<'db>;
580 type FinalChoice = PickResult<'db>;
581
582 fn with_impl_or_trait_item<'a>(
583 this: &mut ProbeContext<'a, 'db, Self>,
584 items: &[(Name, AssocItemId)],
585 mut callback: impl FnMut(&mut ProbeContext<'a, 'db, Self>, CandidateId),
586 ) {
587 let item = items
588 .iter()
589 .filter_map(|(name, id)| {
590 let id = match *id {
591 AssocItemId::FunctionId(id) => id.into(),
592 AssocItemId::ConstId(id) => id.into(),
593 AssocItemId::TypeAliasId(_) => return None,
594 };
595 Some((name, id))
596 })
597 .find(|(name, _)| **name == this.choice.item_name)
598 .map(|(_, id)| id)
599 .filter(|id| this.mode == Mode::Path || matches!(id, CandidateId::FunctionId(_)));
600 if let Some(item) = item {
601 callback(this, item);
602 }
603 }
604
605 fn consider_candidates(
606 this: &ProbeContext<'_, 'db, Self>,
607 self_ty: Ty<'db>,
608 mut applicable_candidates: Vec<&Candidate<'db>>,
609 ) -> ControlFlow<Self::Choice> {
610 if applicable_candidates.len() > 1
611 && let Some(pick) =
612 this.collapse_candidates_to_trait_pick(self_ty, &applicable_candidates)
613 {
614 return ControlFlow::Break(Ok(pick));
615 }
616
617 if applicable_candidates.len() > 1 {
618 if this.ctx.features.supertrait_item_shadowing
622 && let Some(pick) =
623 this.collapse_candidates_to_subtrait_pick(self_ty, &applicable_candidates)
624 {
625 return ControlFlow::Break(Ok(pick));
626 }
627
628 let sources =
629 applicable_candidates.iter().map(|p| this.candidate_source(p, self_ty)).collect();
630 return ControlFlow::Break(Err(MethodError::Ambiguity(sources)));
631 }
632
633 match applicable_candidates.pop() {
634 Some(probe) => ControlFlow::Break(Ok(probe.to_unadjusted_pick(self_ty))),
635 None => ControlFlow::Continue(()),
636 }
637 }
638
639 fn consider_private_candidates(
640 this: &mut ProbeContext<'_, 'db, Self>,
641 self_ty: Ty<'db>,
642 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
643 ) {
644 if this.choice.private_candidate.is_none()
645 && let ControlFlow::Break(Ok(pick)) = this.consider_candidates(
646 self_ty,
647 instantiate_self_ty_obligations,
648 &this.private_candidates,
649 None,
650 )
651 {
652 this.choice.private_candidate = Some(pick);
653 }
654 }
655
656 fn map_choice_pick(
657 choice: Self::Choice,
658 f: impl FnOnce(Pick<'db>) -> Pick<'db>,
659 ) -> Self::Choice {
660 choice.map(f)
661 }
662
663 fn check_by_value_method_shadowing(
664 this: &mut ProbeContext<'_, 'db, Self>,
665 by_value_pick: &Self::Choice,
666 step: &CandidateStep<'db>,
667 self_ty: Ty<'db>,
668 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
669 ) -> ControlFlow<Self::Choice> {
670 if let Ok(by_value_pick) = by_value_pick
671 && matches!(by_value_pick.kind, PickKind::InherentImplPick(_))
672 {
673 for mutbl in [Mutability::Not, Mutability::Mut] {
674 if let Err(e) = this.check_for_shadowed_autorefd_method(
675 by_value_pick,
676 step,
677 self_ty,
678 instantiate_self_ty_obligations,
679 mutbl,
680 ) {
681 return ControlFlow::Break(Err(e));
682 }
683 }
684 }
685 ControlFlow::Continue(())
686 }
687
688 fn check_autorefed_method_shadowing(
689 this: &mut ProbeContext<'_, 'db, Self>,
690 autoref_pick: &Self::Choice,
691 step: &CandidateStep<'db>,
692 self_ty: Ty<'db>,
693 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
694 ) -> ControlFlow<Self::Choice> {
695 if let Ok(autoref_pick) = autoref_pick.as_ref() {
696 if matches!(autoref_pick.kind, PickKind::InherentImplPick(_))
698 && let Err(e) = this.check_for_shadowed_autorefd_method(
699 autoref_pick,
700 step,
701 self_ty,
702 instantiate_self_ty_obligations,
703 Mutability::Mut,
704 )
705 {
706 return ControlFlow::Break(Err(e));
707 }
708 }
709 ControlFlow::Continue(())
710 }
711
712 fn final_choice_from_err(err: MethodError<'db>) -> Self::FinalChoice {
713 Err(err)
714 }
715
716 fn choose(this: ProbeContext<'_, 'db, Self>) -> Self::FinalChoice {
717 this.pick()
718 }
719}
720
721#[derive(Debug)]
722struct ProbeAllChoice<'db> {
723 candidates: RefCell<FxIndexMap<CandidateId, CandidateWithPrivate<'db>>>,
724 considering_visible_candidates: bool,
725}
726
727impl ProbeAllChoice<'_> {
728 fn new() -> Self {
729 Self { candidates: RefCell::default(), considering_visible_candidates: true }
730 }
731}
732
733impl<'db> ProbeChoice<'db> for ProbeAllChoice<'db> {
734 type Choice = Infallible;
735 type FinalChoice = Self;
736
737 fn with_impl_or_trait_item<'a>(
738 this: &mut ProbeContext<'a, 'db, Self>,
739 items: &[(Name, AssocItemId)],
740 mut callback: impl FnMut(&mut ProbeContext<'a, 'db, Self>, CandidateId),
741 ) {
742 let mode = this.mode;
743 items
744 .iter()
745 .filter_map(|(_, id)| is_relevant_kind_for_mode(mode, *id))
746 .for_each(|id| callback(this, id));
747 }
748
749 fn consider_candidates(
750 this: &ProbeContext<'_, 'db, Self>,
751 _self_ty: Ty<'db>,
752 candidates: Vec<&Candidate<'db>>,
753 ) -> ControlFlow<Self::Choice> {
754 let is_visible = this.choice.considering_visible_candidates;
755 let mut all_candidates = this.choice.candidates.borrow_mut();
756 for candidate in candidates {
757 all_candidates
760 .entry(candidate.item)
761 .or_insert(CandidateWithPrivate { candidate: candidate.clone(), is_visible });
762 }
763 ControlFlow::Continue(())
764 }
765
766 fn consider_private_candidates(
767 this: &mut ProbeContext<'_, 'db, Self>,
768 self_ty: Ty<'db>,
769 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
770 ) {
771 this.choice.considering_visible_candidates = false;
772 let ControlFlow::Continue(()) = this.consider_candidates(
773 self_ty,
774 instantiate_self_ty_obligations,
775 &this.private_candidates,
776 None,
777 );
778 this.choice.considering_visible_candidates = true;
779 }
780
781 fn map_choice_pick(
782 choice: Self::Choice,
783 _f: impl FnOnce(Pick<'db>) -> Pick<'db>,
784 ) -> Self::Choice {
785 choice
786 }
787
788 fn check_by_value_method_shadowing(
789 _this: &mut ProbeContext<'_, 'db, Self>,
790 _by_value_pick: &Self::Choice,
791 _step: &CandidateStep<'db>,
792 _self_ty: Ty<'db>,
793 _instantiate_self_ty_obligations: &[PredicateObligation<'db>],
794 ) -> ControlFlow<Self::Choice> {
795 ControlFlow::Continue(())
796 }
797
798 fn check_autorefed_method_shadowing(
799 _this: &mut ProbeContext<'_, 'db, Self>,
800 _autoref_pick: &Self::Choice,
801 _step: &CandidateStep<'db>,
802 _self_ty: Ty<'db>,
803 _instantiate_self_ty_obligations: &[PredicateObligation<'db>],
804 ) -> ControlFlow<Self::Choice> {
805 ControlFlow::Continue(())
806 }
807
808 fn final_choice_from_err(_err: MethodError<'db>) -> Self::FinalChoice {
809 Self::new()
810 }
811
812 fn choose(mut this: ProbeContext<'_, 'db, Self>) -> Self::FinalChoice {
813 let ControlFlow::Continue(()) = this.pick_all_method();
814 this.choice
815 }
816}
817
818impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> {
819 fn new(
820 ctx: &'a MethodResolutionContext<'a, 'db>,
821 mode: Mode,
822 orig_steps_var_values: &'a OriginalQueryValues<'db>,
823 steps: &'a [CandidateStep<'db>],
824 choice: Choice,
825 ) -> ProbeContext<'a, 'db, Choice> {
826 ProbeContext {
827 ctx,
828 mode,
829 inherent_candidates: Vec::new(),
830 extension_candidates: Vec::new(),
831 impl_dups: FxHashSet::default(),
832 orig_steps_var_values,
833 steps,
834 private_candidates: Vec::new(),
835 static_candidates: Vec::new(),
836 choice,
837 }
838 }
839
840 #[inline]
841 fn db(&self) -> &'db dyn HirDatabase {
842 self.ctx.infcx.interner.db
843 }
844
845 #[inline]
846 fn interner(&self) -> DbInterner<'db> {
847 self.ctx.infcx.interner
848 }
849
850 #[inline]
851 fn infcx(&self) -> &'a InferCtxt<'db> {
852 self.ctx.infcx
853 }
854
855 #[inline]
856 fn param_env(&self) -> ParamEnv<'db> {
857 self.ctx.param_env
858 }
859
860 fn variance(&self) -> Variance {
864 match self.mode {
865 Mode::MethodCall => Variance::Covariant,
866 Mode::Path => Variance::Invariant,
867 }
868 }
869
870 fn push_candidate(&mut self, candidate: Candidate<'db>, is_inherent: bool) {
874 let is_accessible = if is_inherent {
875 let candidate_id: AssocItemId = match candidate.item {
876 CandidateId::FunctionId(id) => id.into(),
877 CandidateId::ConstId(id) => id.into(),
878 };
879 let visibility = candidate_id.assoc_visibility(self.db());
880 self.ctx.resolver.is_visible(self.db(), visibility)
881 } else {
882 true
883 };
884 if is_accessible {
885 if is_inherent {
886 self.inherent_candidates.push(candidate);
887 } else {
888 self.extension_candidates.push(candidate);
889 }
890 } else {
891 self.private_candidates.push(candidate);
892 }
893 }
894
895 fn assemble_inherent_candidates(&mut self) {
896 for step in self.steps.iter() {
897 self.assemble_probe(&step.self_ty, step.autoderefs);
898 }
899 }
900
901 #[instrument(level = "debug", skip(self))]
902 fn assemble_probe(
903 &mut self,
904 self_ty: &Canonical<'db, QueryResponse<'db, Ty<'db>>>,
905 receiver_steps: usize,
906 ) {
907 let raw_self_ty = self_ty.value.value;
908 match raw_self_ty.kind() {
909 TyKind::Dynamic(data, ..) => {
910 if let Some(p) = data.principal() {
911 let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
929 self.infcx().instantiate_canonical(self.ctx.call_span, self_ty);
930
931 self.assemble_inherent_candidates_from_object(generalized_self_ty);
932 self.assemble_inherent_impl_candidates_for_type(
933 &SimplifiedType::Trait(p.def_id().0.into()),
934 receiver_steps,
935 );
936 self.assemble_inherent_candidates_for_incoherent_ty(
937 raw_self_ty,
938 receiver_steps,
939 );
940 }
941 }
942 TyKind::Adt(def, _) => {
943 let def_id = def.def_id();
944 self.assemble_inherent_impl_candidates_for_type(
945 &SimplifiedType::Adt(def_id.into()),
946 receiver_steps,
947 );
948 self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps);
949 }
950 TyKind::Foreign(did) => {
951 self.assemble_inherent_impl_candidates_for_type(
952 &SimplifiedType::Foreign(did.0.into()),
953 receiver_steps,
954 );
955 self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps);
956 }
957 TyKind::Param(_) => {
958 self.assemble_inherent_candidates_from_param(raw_self_ty);
959 }
960 TyKind::Bool
961 | TyKind::Char
962 | TyKind::Int(_)
963 | TyKind::Uint(_)
964 | TyKind::Float(_)
965 | TyKind::Str
966 | TyKind::Array(..)
967 | TyKind::Slice(_)
968 | TyKind::RawPtr(_, _)
969 | TyKind::Ref(..)
970 | TyKind::Never
971 | TyKind::Tuple(..) => {
972 self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps)
973 }
974 _ => {}
975 }
976 }
977
978 fn assemble_inherent_candidates_for_incoherent_ty(
979 &mut self,
980 self_ty: Ty<'db>,
981 receiver_steps: usize,
982 ) {
983 let Some(simp) = simplify_type(self.interner(), self_ty, TreatParams::InstantiateWithInfer)
984 else {
985 panic!("unexpected incoherent type: {:?}", self_ty)
986 };
987 with_incoherent_inherent_impls(self.db(), self.ctx.resolver.krate(), &simp, |impls| {
988 for &impl_def_id in impls {
989 self.assemble_inherent_impl_probe(impl_def_id, receiver_steps);
990 }
991 });
992 }
993
994 fn assemble_inherent_impl_candidates_for_type(
995 &mut self,
996 self_ty: &SimplifiedType<'db>,
997 receiver_steps: usize,
998 ) {
999 let Some(module) = simplified_type_module(self.db(), self_ty) else {
1000 return;
1001 };
1002 InherentImpls::for_each_crate_and_block(
1003 self.db(),
1004 module.krate(self.db()),
1005 module.block(self.db()),
1006 &mut |impls| {
1007 for &impl_def_id in impls.for_self_ty(self_ty) {
1008 self.assemble_inherent_impl_probe(impl_def_id, receiver_steps);
1009 }
1010 },
1011 );
1012 }
1013
1014 #[instrument(level = "debug", skip(self))]
1015 fn assemble_inherent_impl_probe(&mut self, impl_def_id: ImplId, receiver_steps: usize) {
1016 if !self.impl_dups.insert(impl_def_id) {
1017 return; }
1019
1020 self.with_impl_item(impl_def_id, |this, item| {
1021 if !this.has_applicable_self(item) {
1022 this.record_static_candidate(CandidateSource::Impl(impl_def_id.into()));
1024 return;
1025 }
1026 this.push_candidate(
1027 Candidate { item, kind: InherentImplCandidate { impl_def_id, receiver_steps } },
1028 true,
1029 );
1030 });
1031 }
1032
1033 #[instrument(level = "debug", skip(self))]
1034 fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'db>) {
1035 let principal = match self_ty.kind() {
1036 TyKind::Dynamic(data, ..) => Some(data),
1037 _ => None,
1038 }
1039 .and_then(|data| data.principal())
1040 .unwrap_or_else(|| {
1041 panic!("non-object {:?} in assemble_inherent_candidates_from_object", self_ty)
1042 });
1043
1044 let trait_ref = principal.with_self_ty(self.interner(), self_ty);
1051 self.assemble_candidates_for_bounds(
1052 elaborate::supertraits(self.interner(), trait_ref),
1053 |this, new_trait_ref, item| {
1054 this.push_candidate(Candidate { item, kind: ObjectCandidate(new_trait_ref) }, true);
1055 },
1056 );
1057 }
1058
1059 #[instrument(level = "debug", skip(self))]
1060 fn assemble_inherent_candidates_from_param(&mut self, param_ty: Ty<'db>) {
1061 debug_assert!(matches!(param_ty.kind(), TyKind::Param(_)));
1062
1063 let interner = self.interner();
1064
1065 let bounds = self.param_env().clauses.iter().filter_map(|predicate| {
1069 let bound_predicate = predicate.kind();
1070 match bound_predicate.skip_binder() {
1071 ClauseKind::Trait(trait_predicate) => DeepRejectCtxt::relate_rigid_rigid(interner)
1072 .types_may_unify(param_ty, trait_predicate.trait_ref.self_ty())
1073 .then(|| bound_predicate.rebind(trait_predicate.trait_ref)),
1074 ClauseKind::RegionOutlives(_)
1075 | ClauseKind::TypeOutlives(_)
1076 | ClauseKind::Projection(_)
1077 | ClauseKind::ConstArgHasType(_, _)
1078 | ClauseKind::WellFormed(_)
1079 | ClauseKind::ConstEvaluatable(_)
1080 | ClauseKind::UnstableFeature(_)
1081 | ClauseKind::HostEffect(..) => None,
1082 }
1083 });
1084
1085 self.assemble_candidates_for_bounds(bounds, |this, poly_trait_ref, item| {
1086 this.push_candidate(
1087 Candidate { item, kind: WhereClauseCandidate(poly_trait_ref) },
1088 true,
1089 );
1090 });
1091 }
1092
1093 fn assemble_candidates_for_bounds<F>(
1096 &mut self,
1097 bounds: impl Iterator<Item = PolyTraitRef<'db>>,
1098 mut mk_cand: F,
1099 ) where
1100 F: for<'b> FnMut(&mut ProbeContext<'b, 'db, Choice>, PolyTraitRef<'db>, CandidateId),
1101 {
1102 for bound_trait_ref in bounds {
1103 debug!("elaborate_bounds(bound_trait_ref={:?})", bound_trait_ref);
1104 self.with_trait_item(bound_trait_ref.def_id().0, |this, item| {
1105 if !this.has_applicable_self(item) {
1106 this.record_static_candidate(CandidateSource::Trait(
1107 bound_trait_ref.def_id().0,
1108 ));
1109 } else {
1110 mk_cand(this, bound_trait_ref, item);
1111 }
1112 });
1113 }
1114 }
1115
1116 #[instrument(level = "debug", skip(self))]
1117 fn assemble_extension_candidates_for_traits_in_scope(&mut self) {
1118 for &trait_did in self.ctx.traits_in_scope {
1119 self.assemble_extension_candidates_for_trait(trait_did);
1120 }
1121 }
1122
1123 #[instrument(level = "debug", skip(self))]
1124 fn assemble_extension_candidates_for_trait(&mut self, trait_def_id: TraitId) {
1125 let trait_args = self.infcx().fresh_args_for_item(self.ctx.call_span, trait_def_id.into());
1126 let trait_ref = TraitRef::new_from_args(self.interner(), trait_def_id.into(), trait_args);
1127
1128 self.with_trait_item(trait_def_id, |this, item| {
1129 if !this.has_applicable_self(item) {
1131 debug!("method has inapplicable self");
1132 this.record_static_candidate(CandidateSource::Trait(trait_def_id));
1133 return;
1134 }
1135 this.push_candidate(
1136 Candidate { item, kind: TraitCandidate(Binder::dummy(trait_ref)) },
1137 false,
1138 );
1139 });
1140 }
1141}
1142
1143impl<'a, 'db> ProbeContext<'a, 'db, ProbeForNameChoice<'db>> {
1146 #[instrument(level = "debug", skip(self))]
1147 fn pick(mut self) -> PickResult<'db> {
1148 if let Some(r) = self.pick_core() {
1149 return r;
1150 }
1151
1152 debug!("pick: actual search failed, assemble diagnostics");
1153
1154 if let Some(candidate) = self.choice.private_candidate {
1155 return Err(MethodError::PrivateMatch(candidate));
1156 }
1157
1158 Err(MethodError::NoMatch)
1159 }
1160
1161 fn pick_core(&mut self) -> Option<PickResult<'db>> {
1162 self.pick_all_method().break_value()
1163 }
1164
1165 fn check_for_shadowed_autorefd_method(
1181 &mut self,
1182 possible_shadower: &Pick<'db>,
1183 step: &CandidateStep<'db>,
1184 self_ty: Ty<'db>,
1185 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1186 mutbl: Mutability,
1187 ) -> Result<(), MethodError<'db>> {
1188 if !self.ctx.features.arbitrary_self_types
1192 && !self.ctx.features.arbitrary_self_types_pointers
1193 {
1194 return Ok(());
1195 }
1196
1197 let pick_constraints = PickConstraintsForShadowed {
1199 autoderefs: possible_shadower.autoderefs,
1201 receiver_steps: possible_shadower.receiver_steps,
1205 def_id: possible_shadower.item,
1208 };
1209 let potentially_shadowed_pick = self.pick_autorefd_method(
1239 step,
1240 self_ty,
1241 instantiate_self_ty_obligations,
1242 mutbl,
1243 Some(&pick_constraints),
1244 );
1245 if let ControlFlow::Break(Ok(possible_shadowed)) = &potentially_shadowed_pick {
1248 let sources = [possible_shadower, possible_shadowed]
1249 .into_iter()
1250 .map(|p| self.candidate_source_from_pick(p))
1251 .collect();
1252 return Err(MethodError::Ambiguity(sources));
1253 }
1254 Ok(())
1255 }
1256}
1257
1258impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> {
1259 fn pick_all_method(&mut self) -> ControlFlow<Choice::Choice> {
1260 self.steps
1261 .iter()
1262 .filter(|step| step.reachable_via_deref)
1266 .filter(|step| {
1267 debug!("pick_all_method: step={:?}", step);
1268 !step.self_ty.value.value.references_only_ty_error() && !step.from_unsafe_deref
1271 })
1272 .try_for_each(|step| {
1273 let InferOk { value: self_ty, obligations: instantiate_self_ty_obligations } = self
1274 .infcx()
1275 .instantiate_query_response_and_region_obligations(
1276 &ObligationCause::new(self.ctx.receiver_span),
1277 self.param_env(),
1278 self.orig_steps_var_values,
1279 &step.self_ty,
1280 )
1281 .unwrap_or_else(|_| panic!("{:?} was applicable but now isn't?", step.self_ty));
1282
1283 let by_value_pick =
1284 self.pick_by_value_method(step, self_ty, &instantiate_self_ty_obligations);
1285
1286 if let ControlFlow::Break(by_value_pick) = by_value_pick {
1288 Choice::check_by_value_method_shadowing(
1289 self,
1290 &by_value_pick,
1291 step,
1292 self_ty,
1293 &instantiate_self_ty_obligations,
1294 )?;
1295 return ControlFlow::Break(by_value_pick);
1296 }
1297
1298 if self.mode == Mode::Path {
1299 return ControlFlow::Continue(());
1305 }
1306
1307 let autoref_pick = self.pick_autorefd_method(
1308 step,
1309 self_ty,
1310 &instantiate_self_ty_obligations,
1311 Mutability::Not,
1312 None,
1313 );
1314 if let ControlFlow::Break(autoref_pick) = autoref_pick {
1316 Choice::check_autorefed_method_shadowing(
1317 self,
1318 &autoref_pick,
1319 step,
1320 self_ty,
1321 &instantiate_self_ty_obligations,
1322 )?;
1323 return ControlFlow::Break(autoref_pick);
1324 }
1325
1326 self.pick_autorefd_method(
1350 step,
1351 self_ty,
1352 &instantiate_self_ty_obligations,
1353 Mutability::Mut,
1354 None,
1355 )?;
1356 self.pick_const_ptr_method(step, self_ty, &instantiate_self_ty_obligations)
1357 })
1358 }
1359
1360 fn pick_by_value_method(
1367 &mut self,
1368 step: &CandidateStep<'db>,
1369 self_ty: Ty<'db>,
1370 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1371 ) -> ControlFlow<Choice::Choice> {
1372 if step.unsize {
1373 return ControlFlow::Continue(());
1374 }
1375
1376 self.pick_method(self_ty, instantiate_self_ty_obligations, None).map_break(|r| {
1377 Choice::map_choice_pick(r, |mut pick| {
1378 pick.autoderefs = step.autoderefs;
1379
1380 match step.self_ty.value.value.kind() {
1381 TyKind::Ref(_, _, mutbl) => {
1383 pick.autoderefs += 1;
1384 pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
1385 mutbl,
1386 unsize: pick.autoref_or_ptr_adjustment.is_some_and(|a| a.get_unsize()),
1387 })
1388 }
1389
1390 _ => (),
1391 }
1392
1393 pick
1394 })
1395 })
1396 }
1397
1398 fn pick_autorefd_method(
1399 &mut self,
1400 step: &CandidateStep<'db>,
1401 self_ty: Ty<'db>,
1402 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1403 mutbl: Mutability,
1404 pick_constraints: Option<&PickConstraintsForShadowed>,
1405 ) -> ControlFlow<Choice::Choice> {
1406 let interner = self.interner();
1407
1408 if let Some(pick_constraints) = pick_constraints
1409 && !pick_constraints.may_shadow_based_on_autoderefs(step.autoderefs)
1410 {
1411 return ControlFlow::Continue(());
1412 }
1413
1414 let region = Region::new_erased(interner);
1416
1417 let autoref_ty = Ty::new_ref(interner, region, self_ty, mutbl);
1418 self.pick_method(autoref_ty, instantiate_self_ty_obligations, pick_constraints).map_break(
1419 |r| {
1420 Choice::map_choice_pick(r, |mut pick| {
1421 pick.autoderefs = step.autoderefs;
1422 pick.autoref_or_ptr_adjustment =
1423 Some(AutorefOrPtrAdjustment::Autoref { mutbl, unsize: step.unsize });
1424 pick
1425 })
1426 },
1427 )
1428 }
1429
1430 fn pick_const_ptr_method(
1434 &mut self,
1435 step: &CandidateStep<'db>,
1436 self_ty: Ty<'db>,
1437 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1438 ) -> ControlFlow<Choice::Choice> {
1439 if step.unsize {
1441 return ControlFlow::Continue(());
1442 }
1443
1444 let TyKind::RawPtr(ty, Mutability::Mut) = self_ty.kind() else {
1445 return ControlFlow::Continue(());
1446 };
1447
1448 let const_ptr_ty = Ty::new_ptr(self.interner(), ty, Mutability::Not);
1449 self.pick_method(const_ptr_ty, instantiate_self_ty_obligations, None).map_break(|r| {
1450 Choice::map_choice_pick(r, |mut pick| {
1451 pick.autoderefs = step.autoderefs;
1452 pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::ToConstPtr);
1453 pick
1454 })
1455 })
1456 }
1457
1458 fn pick_method(
1459 &mut self,
1460 self_ty: Ty<'db>,
1461 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1462 pick_constraints: Option<&PickConstraintsForShadowed>,
1463 ) -> ControlFlow<Choice::Choice> {
1464 debug!("pick_method(self_ty={:?})", self_ty);
1465
1466 for (kind, candidates) in
1467 [("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
1468 {
1469 debug!("searching {} candidates", kind);
1470 self.consider_candidates(
1471 self_ty,
1472 instantiate_self_ty_obligations,
1473 candidates,
1474 pick_constraints,
1475 )?;
1476 }
1477
1478 Choice::consider_private_candidates(self, self_ty, instantiate_self_ty_obligations);
1479
1480 ControlFlow::Continue(())
1481 }
1482
1483 fn consider_candidates(
1484 &self,
1485 self_ty: Ty<'db>,
1486 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1487 candidates: &[Candidate<'db>],
1488 pick_constraints: Option<&PickConstraintsForShadowed>,
1489 ) -> ControlFlow<Choice::Choice> {
1490 let applicable_candidates: Vec<_> = candidates
1491 .iter()
1492 .filter(|candidate| {
1493 pick_constraints
1494 .map(|pick_constraints| pick_constraints.candidate_may_shadow(candidate))
1495 .unwrap_or(true)
1496 })
1497 .filter(|probe| {
1498 self.consider_probe(self_ty, instantiate_self_ty_obligations, probe)
1499 != ProbeResult::NoMatch
1500 })
1501 .collect();
1502
1503 debug!("applicable_candidates: {:?}", applicable_candidates);
1504
1505 Choice::consider_candidates(self, self_ty, applicable_candidates)
1506 }
1507
1508 fn select_trait_candidate(
1509 &self,
1510 trait_ref: TraitRef<'db>,
1511 ) -> SelectionResult<'db, Selection<'db>> {
1512 let obligation = Obligation::new(
1513 self.interner(),
1514 ObligationCause::new(self.ctx.call_span),
1515 self.param_env(),
1516 trait_ref,
1517 );
1518 self.infcx().select(&obligation)
1519 }
1520
1521 fn candidate_source(&self, candidate: &Candidate<'db>, self_ty: Ty<'db>) -> CandidateSource {
1524 match candidate.kind {
1525 InherentImplCandidate { impl_def_id, .. } => CandidateSource::Impl(impl_def_id.into()),
1526 ObjectCandidate(trait_ref) | WhereClauseCandidate(trait_ref) => {
1527 CandidateSource::Trait(trait_ref.def_id().0)
1528 }
1529 TraitCandidate(trait_ref) => self.infcx().probe(|_| {
1530 let trait_ref = self.infcx().instantiate_binder_with_fresh_vars(
1531 self.ctx.call_span,
1532 BoundRegionConversionTime::FnCall,
1533 trait_ref,
1534 );
1535 let (xform_self_ty, _) = self.xform_self_ty(
1536 candidate.item,
1537 trait_ref.self_ty(),
1538 trait_ref.args.as_slice(),
1539 );
1540 let _ = self
1543 .infcx()
1544 .at(&ObligationCause::new(self.ctx.call_span), self.param_env())
1545 .sup(xform_self_ty, self_ty);
1546 match self.select_trait_candidate(trait_ref) {
1547 Ok(Some(ImplSource::UserDefined(ref impl_data))) => {
1548 CandidateSource::Impl(impl_data.impl_def_id)
1551 }
1552 _ => CandidateSource::Trait(trait_ref.def_id.0),
1553 }
1554 }),
1555 }
1556 }
1557
1558 fn candidate_source_from_pick(&self, pick: &Pick<'db>) -> CandidateSource {
1559 match pick.kind {
1560 InherentImplPick(impl_) => CandidateSource::Impl(impl_.into()),
1561 ObjectPick(trait_) | TraitPick(trait_) => CandidateSource::Trait(trait_),
1562 WhereClausePick(trait_ref) => CandidateSource::Trait(trait_ref.skip_binder().def_id.0),
1563 }
1564 }
1565
1566 #[instrument(level = "debug", skip(self), ret)]
1567 fn consider_probe(
1568 &self,
1569 self_ty: Ty<'db>,
1570 instantiate_self_ty_obligations: &[PredicateObligation<'db>],
1571 probe: &Candidate<'db>,
1572 ) -> ProbeResult {
1573 self.infcx().probe(|_| {
1574 let mut result = ProbeResult::Match;
1575 let cause = &ObligationCause::new(self.ctx.call_span);
1576 let mut ocx = ObligationCtxt::new(self.infcx());
1577
1578 ocx.register_obligations(instantiate_self_ty_obligations.iter().cloned());
1586 let errors = ocx.try_evaluate_obligations();
1587 if !errors.is_empty() {
1588 unreachable!("unexpected autoderef error {errors:?}");
1589 }
1590
1591 let mut trait_predicate = None;
1592 let (xform_self_ty, xform_ret_ty);
1593
1594 match probe.kind {
1595 InherentImplCandidate { impl_def_id, .. } => {
1596 let impl_args =
1597 self.infcx().fresh_args_for_item(self.ctx.call_span, impl_def_id.into());
1598 let impl_ty = self
1599 .db()
1600 .impl_self_ty(impl_def_id)
1601 .instantiate(self.interner(), impl_args)
1602 .skip_norm_wip();
1603 (xform_self_ty, xform_ret_ty) =
1604 self.xform_self_ty(probe.item, impl_ty, impl_args.as_slice());
1605 match ocx.relate(
1606 cause,
1607 self.param_env(),
1608 self.variance(),
1609 self_ty,
1610 xform_self_ty,
1611 ) {
1612 Ok(()) => {}
1613 Err(err) => {
1614 debug!("--> cannot relate self-types {:?}", err);
1615 return ProbeResult::NoMatch;
1616 }
1617 }
1618 let impl_bounds = GenericPredicates::query_all(self.db(), impl_def_id.into());
1620 let impl_bounds = clauses_as_obligations(
1621 impl_bounds
1622 .iter_instantiated(self.interner(), impl_args.as_slice())
1623 .map(Unnormalized::skip_norm_wip),
1624 ObligationCause::new(self.ctx.call_span),
1625 self.param_env(),
1626 );
1627 ocx.register_obligations(impl_bounds);
1629 }
1630 TraitCandidate(poly_trait_ref) => {
1631 if self_ty.is_array() && !self.ctx.edition.at_least_2021() {
1634 let trait_signature =
1635 TraitSignature::of(self.db(), poly_trait_ref.def_id().0);
1636 if trait_signature
1637 .flags
1638 .contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH)
1639 {
1640 return ProbeResult::NoMatch;
1641 }
1642 }
1643
1644 if self_ty.boxed_ty().is_some_and(Ty::is_slice)
1647 && !self.ctx.edition.at_least_2024()
1648 {
1649 let trait_signature =
1650 TraitSignature::of(self.db(), poly_trait_ref.def_id().0);
1651 if trait_signature
1652 .flags
1653 .contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH)
1654 {
1655 return ProbeResult::NoMatch;
1656 }
1657 }
1658
1659 let trait_ref = self.infcx().instantiate_binder_with_fresh_vars(
1660 self.ctx.call_span,
1661 BoundRegionConversionTime::FnCall,
1662 poly_trait_ref,
1663 );
1664 (xform_self_ty, xform_ret_ty) = self.xform_self_ty(
1665 probe.item,
1666 trait_ref.self_ty(),
1667 trait_ref.args.as_slice(),
1668 );
1669 match ocx.relate(
1670 cause,
1671 self.param_env(),
1672 self.variance(),
1673 self_ty,
1674 xform_self_ty,
1675 ) {
1676 Ok(()) => {}
1677 Err(err) => {
1678 debug!("--> cannot relate self-types {:?}", err);
1679 return ProbeResult::NoMatch;
1680 }
1681 }
1682 let obligation = Obligation::new(
1683 self.interner(),
1684 *cause,
1685 self.param_env(),
1686 Binder::dummy(trait_ref),
1687 );
1688
1689 ocx.register_obligation(obligation);
1691
1692 trait_predicate = Some(trait_ref.upcast(self.interner()));
1693 }
1694 ObjectCandidate(poly_trait_ref) | WhereClauseCandidate(poly_trait_ref) => {
1695 let trait_ref = self.infcx().instantiate_binder_with_fresh_vars(
1696 self.ctx.call_span,
1697 BoundRegionConversionTime::FnCall,
1698 poly_trait_ref,
1699 );
1700 (xform_self_ty, xform_ret_ty) = self.xform_self_ty(
1701 probe.item,
1702 trait_ref.self_ty(),
1703 trait_ref.args.as_slice(),
1704 );
1705
1706 if matches!(probe.kind, WhereClauseCandidate(_)) {
1707 match ocx.structurally_normalize_ty(
1711 cause,
1712 self.param_env(),
1713 trait_ref.self_ty(),
1714 ) {
1715 Ok(ty) => {
1716 if !matches!(ty.kind(), TyKind::Param(_)) {
1717 debug!("--> not a param ty: {xform_self_ty:?}");
1718 return ProbeResult::NoMatch;
1719 }
1720 }
1721 Err(errors) => {
1722 debug!("--> cannot relate self-types {:?}", errors);
1723 return ProbeResult::NoMatch;
1724 }
1725 }
1726 }
1727
1728 match ocx.relate(
1729 cause,
1730 self.param_env(),
1731 self.variance(),
1732 self_ty,
1733 xform_self_ty,
1734 ) {
1735 Ok(()) => {}
1736 Err(err) => {
1737 debug!("--> cannot relate self-types {:?}", err);
1738 return ProbeResult::NoMatch;
1739 }
1740 }
1741 }
1742 }
1743
1744 if let Some(xform_ret_ty) = xform_ret_ty {
1756 ocx.register_obligation(Obligation::new(
1757 self.interner(),
1758 *cause,
1759 self.param_env(),
1760 ClauseKind::WellFormed(xform_ret_ty.into()),
1761 ));
1762 }
1763
1764 if !ocx.try_evaluate_obligations().is_empty() {
1765 result = ProbeResult::NoMatch;
1766 }
1767
1768 if self.should_reject_candidate_due_to_opaque_treated_as_rigid(trait_predicate) {
1769 result = ProbeResult::NoMatch;
1770 }
1771
1772 result
1778 })
1779 }
1780
1781 #[instrument(level = "debug", skip(self), ret)]
1796 fn should_reject_candidate_due_to_opaque_treated_as_rigid(
1797 &self,
1798 trait_predicate: Option<Predicate<'db>>,
1799 ) -> bool {
1800 if let Some(predicate) = trait_predicate {
1812 let goal = Goal { param_env: self.param_env(), predicate };
1813 if !self.infcx().goal_may_hold_opaque_types_jank(goal) {
1814 return true;
1815 }
1816 }
1817
1818 for step in self.steps {
1821 if step.self_ty_is_opaque {
1822 debug!(?step.autoderefs, ?step.self_ty, "self_type_is_opaque");
1823 let constrained_opaque = self.infcx().probe(|_| {
1824 let Ok(ok) = self.infcx().instantiate_query_response_and_region_obligations(
1829 &ObligationCause::new(self.ctx.receiver_span),
1830 self.param_env(),
1831 self.orig_steps_var_values,
1832 &step.self_ty,
1833 ) else {
1834 debug!("failed to instantiate self_ty");
1835 return false;
1836 };
1837 let mut ocx = ObligationCtxt::new(self.infcx());
1838 let self_ty = ocx.register_infer_ok_obligations(ok);
1839 if !ocx.try_evaluate_obligations().is_empty() {
1840 debug!("failed to prove instantiate self_ty obligations");
1841 return false;
1842 }
1843
1844 !self.infcx().resolve_vars_if_possible(self_ty).is_ty_var()
1845 });
1846 if constrained_opaque {
1847 debug!("opaque type has been constrained");
1848 return true;
1849 }
1850 }
1851 }
1852
1853 false
1854 }
1855
1856 fn collapse_candidates_to_trait_pick(
1874 &self,
1875 self_ty: Ty<'db>,
1876 probes: &[&Candidate<'db>],
1877 ) -> Option<Pick<'db>> {
1878 let ItemContainerId::TraitId(container) = probes[0].item.container(self.db()) else {
1880 return None;
1881 };
1882 for p in &probes[1..] {
1883 let ItemContainerId::TraitId(p_container) = p.item.container(self.db()) else {
1884 return None;
1885 };
1886 if p_container != container {
1887 return None;
1888 }
1889 }
1890
1891 Some(Pick {
1894 item: probes[0].item,
1895 kind: TraitPick(container),
1896 autoderefs: 0,
1897 autoref_or_ptr_adjustment: None,
1898 self_ty,
1899 receiver_steps: None,
1900 shadowed_candidates: vec![],
1901 })
1902 }
1903
1904 fn collapse_candidates_to_subtrait_pick(
1910 &self,
1911 self_ty: Ty<'db>,
1912 probes: &[&Candidate<'db>],
1913 ) -> Option<Pick<'db>> {
1914 let mut child_candidate = probes[0];
1915 let ItemContainerId::TraitId(mut child_trait) = child_candidate.item.container(self.db())
1916 else {
1917 return None;
1918 };
1919 let mut supertraits: FxHashSet<_> =
1920 supertrait_def_ids(self.interner(), child_trait.into()).collect();
1921
1922 let mut remaining_candidates: Vec<_> = probes[1..].to_vec();
1923 while !remaining_candidates.is_empty() {
1924 let mut made_progress = false;
1925 let mut next_round = vec![];
1926
1927 for remaining_candidate in remaining_candidates {
1928 let ItemContainerId::TraitId(remaining_trait) =
1929 remaining_candidate.item.container(self.db())
1930 else {
1931 return None;
1932 };
1933 if supertraits.contains(&remaining_trait.into()) {
1934 made_progress = true;
1935 continue;
1936 }
1937
1938 let remaining_trait_supertraits: FxHashSet<_> =
1944 supertrait_def_ids(self.interner(), remaining_trait.into()).collect();
1945 if remaining_trait_supertraits.contains(&child_trait.into()) {
1946 child_candidate = remaining_candidate;
1947 child_trait = remaining_trait;
1948 supertraits = remaining_trait_supertraits;
1949 made_progress = true;
1950 continue;
1951 }
1952
1953 next_round.push(remaining_candidate);
1959 }
1960
1961 if made_progress {
1962 remaining_candidates = next_round;
1964 } else {
1965 return None;
1968 }
1969 }
1970
1971 Some(Pick {
1972 item: child_candidate.item,
1973 kind: TraitPick(child_trait),
1974 autoderefs: 0,
1975 autoref_or_ptr_adjustment: None,
1976 self_ty,
1977 shadowed_candidates: probes
1978 .iter()
1979 .map(|c| c.item)
1980 .filter(|item| *item != child_candidate.item)
1981 .collect(),
1982 receiver_steps: None,
1983 })
1984 }
1985
1986 fn has_applicable_self(&self, item: CandidateId) -> bool {
1989 match item {
1995 CandidateId::FunctionId(id) if self.mode == Mode::MethodCall => {
1996 FunctionSignature::of(self.db(), id).has_self_param()
1997 }
1998 _ => true,
1999 }
2000 }
2007
2008 fn record_static_candidate(&mut self, source: CandidateSource) {
2009 self.static_candidates.push(source);
2010 }
2011
2012 #[instrument(level = "debug", skip(self))]
2013 fn xform_self_ty(
2014 &self,
2015 item: CandidateId,
2016 impl_ty: Ty<'db>,
2017 args: &[GenericArg<'db>],
2018 ) -> (Ty<'db>, Option<Ty<'db>>) {
2019 if let CandidateId::FunctionId(item) = item
2020 && self.mode == Mode::MethodCall
2021 {
2022 let sig = self.xform_method_sig(item, args);
2023 (sig.inputs()[0], Some(sig.output()))
2024 } else {
2025 (impl_ty, None)
2026 }
2027 }
2028
2029 #[instrument(level = "debug", skip(self))]
2030 fn xform_method_sig(&self, method: FunctionId, args: &[GenericArg<'db>]) -> FnSig<'db> {
2031 let fn_sig = self.db().callable_item_signature(method.into());
2032 debug!(?fn_sig);
2033
2034 assert!(!args.has_escaping_bound_vars());
2035
2036 let generics = GenericParams::of(self.db(), method.into());
2042
2043 let xform_fn_sig = if generics.is_empty() {
2044 fn_sig.instantiate(self.interner(), args)
2045 } else {
2046 let args = GenericArgs::for_item(
2047 self.interner(),
2048 method.into(),
2049 |param_index, param_id, _, _| {
2050 let i = param_index as usize;
2051 if i < args.len() {
2052 args[i]
2053 } else {
2054 match param_id {
2055 GenericParamId::LifetimeParamId(_) => {
2056 Region::new_erased(self.interner()).into()
2058 }
2059 GenericParamId::TypeParamId(_) => {
2060 self.infcx().next_ty_var(self.ctx.call_span).into()
2061 }
2062 GenericParamId::ConstParamId(_) => {
2063 self.infcx().next_const_var(self.ctx.call_span).into()
2064 }
2065 }
2066 }
2067 },
2068 );
2069 fn_sig.instantiate(self.interner(), args)
2070 };
2071
2072 self.interner().instantiate_bound_regions_with_erased(xform_fn_sig.skip_norm_wip())
2073 }
2074
2075 fn with_impl_item(&mut self, def_id: ImplId, callback: impl FnMut(&mut Self, CandidateId)) {
2076 Choice::with_impl_or_trait_item(self, &def_id.impl_items(self.db()).items, callback)
2077 }
2078
2079 fn with_trait_item(&mut self, def_id: TraitId, callback: impl FnMut(&mut Self, CandidateId)) {
2080 Choice::with_impl_or_trait_item(self, &def_id.trait_items(self.db()).items, callback)
2081 }
2082}
2083
2084fn is_relevant_kind_for_mode(mode: Mode, kind: AssocItemId) -> Option<CandidateId> {
2086 Some(match (mode, kind) {
2087 (Mode::MethodCall, AssocItemId::FunctionId(id)) => id.into(),
2088 (Mode::Path, AssocItemId::ConstId(id)) => id.into(),
2089 (Mode::Path, AssocItemId::FunctionId(id)) => id.into(),
2090 _ => return None,
2091 })
2092}
2093
2094impl<'db> Candidate<'db> {
2095 fn to_unadjusted_pick(&self, self_ty: Ty<'db>) -> Pick<'db> {
2096 Pick {
2097 item: self.item,
2098 kind: match self.kind {
2099 InherentImplCandidate { impl_def_id, .. } => InherentImplPick(impl_def_id),
2100 ObjectCandidate(trait_ref) => ObjectPick(trait_ref.skip_binder().def_id.0),
2101 TraitCandidate(trait_ref) => TraitPick(trait_ref.skip_binder().def_id.0),
2102 WhereClauseCandidate(trait_ref) => {
2103 assert!(
2109 !trait_ref.skip_binder().args.has_infer()
2110 && !trait_ref.skip_binder().args.has_placeholders()
2111 );
2112
2113 WhereClausePick(trait_ref)
2114 }
2115 },
2116 autoderefs: 0,
2117 autoref_or_ptr_adjustment: None,
2118 self_ty,
2119 receiver_steps: match self.kind {
2120 InherentImplCandidate { receiver_steps, .. } => Some(receiver_steps),
2121 _ => None,
2122 },
2123 shadowed_candidates: vec![],
2124 }
2125 }
2126}