struct ProbeContext<'a, 'db, Choice> {
ctx: &'a MethodResolutionContext<'a, 'db>,
mode: Mode,
orig_steps_var_values: &'a OriginalQueryValues<'db>,
steps: &'a [CandidateStep<'db>],
inherent_candidates: Vec<Candidate<'db>>,
extension_candidates: Vec<Candidate<'db>>,
impl_dups: FxHashSet<ImplId>,
private_candidates: Vec<Candidate<'db>>,
static_candidates: Vec<CandidateSource>,
choice: Choice,
}Fields§
§ctx: &'a MethodResolutionContext<'a, 'db>§mode: Mode§orig_steps_var_values: &'a OriginalQueryValues<'db>This is the OriginalQueryValues for the steps queries that are answered in steps.
steps: &'a [CandidateStep<'db>]§inherent_candidates: Vec<Candidate<'db>>§extension_candidates: Vec<Candidate<'db>>§impl_dups: FxHashSet<ImplId>§private_candidates: Vec<Candidate<'db>>List of potential private candidates. Will be trimmed to ones that
actually apply and then the result inserted into private_candidate
static_candidates: Vec<CandidateSource>Collects near misses when the candidate functions are missing a self keyword and is only
used for error reporting
choice: ChoiceImplementations§
Source§impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice>
impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice>
fn new( ctx: &'a MethodResolutionContext<'a, 'db>, mode: Mode, orig_steps_var_values: &'a OriginalQueryValues<'db>, steps: &'a [CandidateStep<'db>], choice: Choice, ) -> ProbeContext<'a, 'db, Choice>
fn db(&self) -> &'db dyn HirDatabase
fn interner(&self) -> DbInterner<'db>
fn infcx(&self) -> &'a InferCtxt<'db>
fn param_env(&self) -> ParamEnv<'db>
Sourcefn variance(&self) -> Variance
fn variance(&self) -> Variance
When we’re looking up a method by path (UFCS), we relate the receiver
types invariantly. When we are looking up a method by the . operator,
we relate them covariantly.
fn push_candidate(&mut self, candidate: Candidate<'db>, is_inherent: bool)
fn assemble_inherent_candidates(&mut self)
fn assemble_probe( &mut self, self_ty: &Canonical<'db, QueryResponse<'db, Ty<'db>>>, receiver_steps: usize, )
fn assemble_inherent_candidates_for_incoherent_ty( &mut self, self_ty: Ty<'db>, receiver_steps: usize, )
fn assemble_inherent_impl_candidates_for_type( &mut self, self_ty: &SimplifiedType<'db>, receiver_steps: usize, )
fn assemble_inherent_impl_probe( &mut self, impl_def_id: ImplId, receiver_steps: usize, )
fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'db>)
fn assemble_inherent_candidates_from_param(&mut self, param_ty: Ty<'db>)
fn assemble_candidates_for_bounds<F>( &mut self, bounds: impl Iterator<Item = PolyTraitRef<'db>>, mk_cand: F, )
fn assemble_extension_candidates_for_traits_in_scope(&mut self)
fn assemble_extension_candidates_for_trait(&mut self, trait_def_id: TraitId)
Source§impl<'a, 'db> ProbeContext<'a, 'db, ProbeForNameChoice<'db>>
impl<'a, 'db> ProbeContext<'a, 'db, ProbeForNameChoice<'db>>
fn pick(self) -> Result<Pick<'db>, MethodError<'db>>
fn pick_core(&mut self) -> Option<Result<Pick<'db>, MethodError<'db>>>
Sourcefn check_for_shadowed_autorefd_method(
&mut self,
possible_shadower: &Pick<'db>,
step: &CandidateStep<'db>,
self_ty: Ty<'db>,
instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>],
mutbl: Mutability,
) -> Result<(), MethodError<'db>>
fn check_for_shadowed_autorefd_method( &mut self, possible_shadower: &Pick<'db>, step: &CandidateStep<'db>, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], mutbl: Mutability, ) -> Result<(), MethodError<'db>>
Check for cases where arbitrary self types allows shadowing of methods that might be a compatibility break. Specifically, we have something like:
struct A;
impl A {
fn foo(self: &NonNull<A>) {}
// note this is by reference
}then we’ve come along and added this method to NonNull:
fn foo(self) // note this is by valueReport an error in this case.
Source§impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice>
impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice>
fn pick_all_method(&mut self) -> ControlFlow<Choice::Choice>
Sourcefn pick_by_value_method(
&mut self,
step: &CandidateStep<'db>,
self_ty: Ty<'db>,
instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>],
) -> ControlFlow<Choice::Choice>
fn pick_by_value_method( &mut self, step: &CandidateStep<'db>, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], ) -> ControlFlow<Choice::Choice>
For each type T in the step list, this attempts to find a method where
the (transformed) self type is exactly T. We do however do one
transformation on the adjustment: if we are passing a region pointer in,
we will potentially reborrow it to a shorter lifetime. This allows us
to transparently pass &mut pointers, in particular, without consuming
them for their entire lifetime.
fn pick_autorefd_method( &mut self, step: &CandidateStep<'db>, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], mutbl: Mutability, pick_constraints: Option<&PickConstraintsForShadowed>, ) -> ControlFlow<Choice::Choice>
Sourcefn pick_const_ptr_method(
&mut self,
step: &CandidateStep<'db>,
self_ty: Ty<'db>,
instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>],
) -> ControlFlow<Choice::Choice>
fn pick_const_ptr_method( &mut self, step: &CandidateStep<'db>, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], ) -> ControlFlow<Choice::Choice>
If self_ty is *mut T then this picks *const T methods. The reason why we have a
special case for this is because going from *mut T to *const T with autoderefs and
autorefs would require dereferencing the pointer, which is not safe.
fn pick_method( &mut self, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], pick_constraints: Option<&PickConstraintsForShadowed>, ) -> ControlFlow<Choice::Choice>
fn consider_candidates( &self, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], candidates: &[Candidate<'db>], pick_constraints: Option<&PickConstraintsForShadowed>, ) -> ControlFlow<Choice::Choice>
fn select_trait_candidate( &self, trait_ref: TraitRef<'db>, ) -> Result<Option<ImplSource<'db, Obligation<'db, Predicate<'db>>>>, SelectionError<'db>>
Sourcefn candidate_source(
&self,
candidate: &Candidate<'db>,
self_ty: Ty<'db>,
) -> CandidateSource
fn candidate_source( &self, candidate: &Candidate<'db>, self_ty: Ty<'db>, ) -> CandidateSource
Used for ambiguous method call error reporting. Uses probing that throws away the result internally, so do not use to make a decision that may lead to a successful compilation.
fn candidate_source_from_pick(&self, pick: &Pick<'db>) -> CandidateSource
fn consider_probe( &self, self_ty: Ty<'db>, instantiate_self_ty_obligations: &[Obligation<'db, Predicate<'db>>], probe: &Candidate<'db>, ) -> ProbeResult
Sourcefn should_reject_candidate_due_to_opaque_treated_as_rigid(
&self,
trait_predicate: Option<Predicate<'db>>,
) -> bool
fn should_reject_candidate_due_to_opaque_treated_as_rigid( &self, trait_predicate: Option<Predicate<'db>>, ) -> bool
Trait candidates for not-yet-defined opaque types are a somewhat hacky.
We want to only accept trait methods if they were hold even if the
opaque types were rigid. To handle this, we both check that for trait
candidates the goal were to hold even when treating opaques as rigid,
see rustc_trait_selection::solve::OpaqueTypesJank.
We also check that all opaque types encountered as self types in the
autoderef chain don’t get constrained when applying the candidate.
Importantly, this also handles calling methods taking &self on
impl Trait to reject the “by-self” candidate.
This needs to happen at the end of consider_probe as we need to take
all the constraints from that into account.
Sourcefn collapse_candidates_to_trait_pick(
&self,
self_ty: Ty<'db>,
probes: &[&Candidate<'db>],
) -> Option<Pick<'db>>
fn collapse_candidates_to_trait_pick( &self, self_ty: Ty<'db>, probes: &[&Candidate<'db>], ) -> Option<Pick<'db>>
Sometimes we get in a situation where we have multiple probes that are all impls of the same trait, but we don’t know which impl to use. In this case, since in all cases the external interface of the method can be determined from the trait, it’s ok not to decide. We can basically just collapse all of the probes for various impls into one where-clause probe. This will result in a pending obligation so when more type-info is available we can make the final decision.
Example (tests/ui/methods/method-two-trait-defer-resolution-1.rs):
trait Foo { ... }
impl Foo for Vec<i32> { ... }
impl Foo for Vec<usize> { ... }Now imagine the receiver is Vec<_>. It doesn’t really matter at this time which impl we
use, so it’s ok to just commit to “using the method from the trait Foo”.
Sourcefn collapse_candidates_to_subtrait_pick(
&self,
self_ty: Ty<'db>,
probes: &[&Candidate<'db>],
) -> Option<Pick<'db>>
fn collapse_candidates_to_subtrait_pick( &self, self_ty: Ty<'db>, probes: &[&Candidate<'db>], ) -> Option<Pick<'db>>
Much like collapse_candidates_to_trait_pick, this method allows us to collapse
multiple conflicting picks if there is one pick whose trait container is a subtrait
of the trait containers of all of the other picks.
This implements RFC #3624.
fn has_applicable_self(&self, item: CandidateId) -> bool
fn record_static_candidate(&mut self, source: CandidateSource)
fn xform_self_ty( &self, item: CandidateId, impl_ty: Ty<'db>, args: &[GenericArg<'db>], ) -> (Ty<'db>, Option<Ty<'db>>)
fn xform_method_sig( &self, method: FunctionId, args: &[GenericArg<'db>], ) -> FnSig<'db>
fn with_impl_item( &mut self, def_id: ImplId, callback: impl FnMut(&mut Self, CandidateId), )
fn with_trait_item( &mut self, def_id: TraitId, callback: impl FnMut(&mut Self, CandidateId), )
Auto Trait Implementations§
impl<'a, 'db, Choice> Freeze for ProbeContext<'a, 'db, Choice>where
Choice: Freeze,
impl<'a, 'db, Choice> !RefUnwindSafe for ProbeContext<'a, 'db, Choice>
impl<'a, 'db, Choice> !Send for ProbeContext<'a, 'db, Choice>
impl<'a, 'db, Choice> !Sync for ProbeContext<'a, 'db, Choice>
impl<'a, 'db, Choice> Unpin for ProbeContext<'a, 'db, Choice>where
Choice: Unpin,
impl<'a, 'db, Choice> UnsafeUnpin for ProbeContext<'a, 'db, Choice>where
Choice: UnsafeUnpin,
impl<'a, 'db, Choice> !UnwindSafe for ProbeContext<'a, 'db, Choice>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more