pub struct SelectionContext<'cx, 'tcx> {
pub infcx: &'cx InferCtxt<'tcx>,
freshener: TypeFreshener<'cx, 'tcx>,
intercrate_ambiguity_causes: Option<FxIndexSet<IntercrateAmbiguityCause<'tcx>>>,
query_mode: TraitQueryMode,
}
Fields§
§infcx: &'cx InferCtxt<'tcx>
§freshener: TypeFreshener<'cx, 'tcx>
Freshener used specifically for entries on the obligation stack. This ensures that all entries on the stack at one time will have the same set of placeholder entries, which is important for checking for trait bounds that recursively require themselves.
intercrate_ambiguity_causes: Option<FxIndexSet<IntercrateAmbiguityCause<'tcx>>>
If intercrate
is set, we remember predicates which were
considered ambiguous because of impls potentially added in other crates.
This is used in coherence to give improved diagnostics.
We don’t do his until we detect a coherence error because it can
lead to false overflow results (#47139) and because always
computing it may negatively impact performance.
query_mode: TraitQueryMode
The mode that trait queries run in, which informs our error handling policy. In essence, canonicalized queries need their errors propagated rather than immediately reported because we do not have accurate spans.
Implementations§
source§impl<'cx, 'tcx> SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx>
pub(super) fn assemble_candidates<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>>
fn assemble_candidates_from_projected_tys( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
sourcefn assemble_candidates_from_caller_bounds<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>>
fn assemble_candidates_from_caller_bounds<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>>
Given an obligation like <SomeTrait for T>
, searches the obligations that the caller
supplied to find out whether it is listed among them.
Never affects the inference environment.
fn assemble_coroutine_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_future_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_iterator_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_fused_iterator_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_async_iterator_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
sourcefn assemble_closure_candidates(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
)
fn assemble_closure_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
Checks for the artificial impl that the compiler will create for an obligation like X : FnMut<..>
where X
is a closure type.
Note: the type parameters on a closure candidate are modeled as output type parameters and hence do not affect whether this trait is a match or not. They will be unified during the confirmation step.
fn assemble_async_closure_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_async_fn_kind_helper_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
sourcefn assemble_fn_pointer_candidates(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
)
fn assemble_fn_pointer_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
Implements one of the Fn()
family for a fn pointer.
sourcefn assemble_candidates_from_impls(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
)
fn assemble_candidates_from_impls( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
Searches for impls that might apply to obligation
.
sourcefn reject_fn_ptr_impls(
&mut self,
impl_def_id: DefId,
obligation: &PolyTraitObligation<'tcx>,
impl_self_ty: Ty<'tcx>,
) -> bool
fn reject_fn_ptr_impls( &mut self, impl_def_id: DefId, obligation: &PolyTraitObligation<'tcx>, impl_self_ty: Ty<'tcx>, ) -> bool
The various impl<T: FnPtr> Trait for T
in libcore are more like builtin impls for all function items
and function pointers and less like blanket impls. Rejecting them when they can’t possibly apply (because
the obligation’s self-type does not implement FnPtr
) avoids reporting that the self type does not implement
FnPtr
, when we wanted to report that it doesn’t implement Trait
.
fn assemble_candidates_from_auto_impls( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
sourcefn assemble_candidates_from_object_ty(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
)
fn assemble_candidates_from_object_ty( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
Searches for impls that might apply to obligation
.
sourcefn need_migrate_deref_output_trait_object(
&mut self,
ty: Ty<'tcx>,
param_env: ParamEnv<'tcx>,
cause: &ObligationCause<'tcx>,
) -> Option<PolyExistentialTraitRef<'tcx>>
fn need_migrate_deref_output_trait_object( &mut self, ty: Ty<'tcx>, param_env: ParamEnv<'tcx>, cause: &ObligationCause<'tcx>, ) -> Option<PolyExistentialTraitRef<'tcx>>
Temporary migration for #89190
sourcefn assemble_candidates_for_unsizing(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
)
fn assemble_candidates_for_unsizing( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
Searches for unsizing that might apply to obligation
.
fn assemble_candidates_for_transmutability( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_candidates_for_trait_alias( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
sourcefn assemble_builtin_bound_candidates(
&mut self,
conditions: BuiltinImplConditions<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
)
fn assemble_builtin_bound_candidates( &mut self, conditions: BuiltinImplConditions<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
Assembles the trait which are built-in to the language itself:
Copy
, Clone
and Sized
.
fn assemble_const_destruct_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_candidate_for_tuple( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_candidate_for_pointer_like( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
fn assemble_candidates_for_fn_ptr_trait( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, )
source§impl<'cx, 'tcx> SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx>
pub(super) fn confirm_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, candidate: SelectionCandidate<'tcx>, ) -> Result<Selection<'tcx>, SelectionError<'tcx>>
fn confirm_projection_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_param_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, param: PolyTraitRef<'tcx>, ) -> Vec<PredicateObligation<'tcx>>
fn confirm_builtin_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, has_nested: bool, ) -> Vec<PredicateObligation<'tcx>>
fn confirm_transmutability_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
sourcefn confirm_auto_impl_candidate(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_auto_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
This handles the case where an auto trait Foo
impl is being used.
The idea is that the impl applies to X : Foo
if the following conditions are met:
- For each constituent type
Y
inX
,Y : Foo
holds - For each where-clause
C
declared onFoo
,[Self => X] C
holds.
sourcefn vtable_auto_impl(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
trait_def_id: DefId,
nested: Binder<'tcx, Vec<Ty<'tcx>>>,
) -> Vec<PredicateObligation<'tcx>>
fn vtable_auto_impl( &mut self, obligation: &PolyTraitObligation<'tcx>, trait_def_id: DefId, nested: Binder<'tcx, Vec<Ty<'tcx>>>, ) -> Vec<PredicateObligation<'tcx>>
See confirm_auto_impl_candidate
.
fn confirm_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: DefId, ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>
fn vtable_impl( &mut self, impl_def_id: DefId, args: Normalized<'tcx, GenericArgsRef<'tcx>>, cause: &ObligationCause<'tcx>, recursion_depth: usize, param_env: ParamEnv<'tcx>, parent_trait_pred: Binder<'tcx, TraitPredicate<'tcx>>, ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>
fn confirm_object_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, index: usize, ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_fn_pointer_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, fn_host_effect: Const<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_trait_alias_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Vec<PredicateObligation<'tcx>>
fn confirm_coroutine_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_future_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_iterator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_async_iterator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_async_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
sourcefn equate_trait_refs(
&mut self,
obligation: TraitObligation<'tcx>,
found_trait_ref: PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn equate_trait_refs( &mut self, obligation: TraitObligation<'tcx>, found_trait_ref: PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
In the case of closure types and fn pointers, we currently treat the input type parameters on the trait as outputs. This means that when we have a match we have only considered the self type, so we have to go back and make sure to relate the argument types too. This is kind of wrong, but since we control the full set of impls, also not that wrong, and it DOES yield better error messages (since we don’t report errors as if there is no applicable impl, but rather report errors are about mismatched argument types.
Here is an example. Imagine we have a closure expression
and we desugared it so that the type of the expression is
Closure
, and Closure
expects i32
as argument. Then it
is “as if” the compiler generated this impl:
impl Fn(i32) for Closure { ... }
Now imagine our obligation is Closure: Fn(usize)
. So far
we have matched the self type Closure
. At this point we’ll
compare the i32
to usize
and generate an error.
Note that this checking occurs after the impl has selected, because these output type parameters should not affect the selection of the impl. Therefore, if there is a mismatch, we report an error to the user.
fn confirm_trait_upcasting_unsize_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_builtin_unsize_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
fn confirm_const_destruct_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: Option<DefId>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
source§impl<'cx, 'tcx> SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx>
pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx>
pub fn with_query_mode( infcx: &'cx InferCtxt<'tcx>, query_mode: TraitQueryMode, ) -> SelectionContext<'cx, 'tcx>
sourcepub fn enable_tracking_intercrate_ambiguity_causes(&mut self)
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self)
Enables tracking of intercrate ambiguity causes. See
the documentation of Self::intercrate_ambiguity_causes
for more.
sourcepub fn take_intercrate_ambiguity_causes(
&mut self,
) -> FxIndexSet<IntercrateAmbiguityCause<'tcx>>
pub fn take_intercrate_ambiguity_causes( &mut self, ) -> FxIndexSet<IntercrateAmbiguityCause<'tcx>>
Gets the intercrate ambiguity causes collected since tracking was enabled and disables tracking at the same time. If tracking is not enabled, just returns an empty vector.
pub fn tcx(&self) -> TyCtxt<'tcx>
pub fn is_intercrate(&self) -> bool
sourcepub fn poly_select(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>>
pub fn poly_select( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>>
Attempts to satisfy the obligation. If successful, this will affect the surrounding type environment by performing unification.
pub fn select( &mut self, obligation: &TraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>>
fn select_from_obligation( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>
fn candidate_from_obligation<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>
fn candidate_from_obligation_no_cache<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>
sourcepub fn evaluate_root_obligation(
&mut self,
obligation: &PredicateObligation<'tcx>,
) -> Result<EvaluationResult, OverflowError>
pub fn evaluate_root_obligation( &mut self, obligation: &PredicateObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError>
Evaluates whether the obligation obligation
can be satisfied
and returns an EvaluationResult
. This is meant for the
initial call.
Do not use this directly, use infcx.evaluate_obligation
instead.
sourcefn evaluation_probe(
&mut self,
op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
) -> Result<EvaluationResult, OverflowError>
fn evaluation_probe( &mut self, op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>, ) -> Result<EvaluationResult, OverflowError>
Computes the evaluation result of op
, discarding any constraints.
This also runs for leak check to allow higher ranked region errors to impact
selection. By default it checks for leaks from all universes created inside of
op
, but this can be overwritten if necessary.
sourcefn evaluate_predicates_recursively<'o, I>(
&mut self,
stack: TraitObligationStackList<'o, 'tcx>,
predicates: I,
) -> Result<EvaluationResult, OverflowError>
fn evaluate_predicates_recursively<'o, I>( &mut self, stack: TraitObligationStackList<'o, 'tcx>, predicates: I, ) -> Result<EvaluationResult, OverflowError>
Evaluates the predicates in predicates
recursively. This may
guide inference. If this is not desired, run it inside of a
is run within an inference probe.
probe
.
fn evaluate_predicate_recursively<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: PredicateObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError>
fn evaluate_trait_predicate_recursively<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: PolyTraitObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError>
sourcefn check_evaluation_cycle(
&mut self,
stack: &TraitObligationStack<'_, 'tcx>,
) -> Option<EvaluationResult>
fn check_evaluation_cycle( &mut self, stack: &TraitObligationStack<'_, 'tcx>, ) -> Option<EvaluationResult>
If there is any previous entry on the stack that precisely
matches this obligation, then we can assume that the
obligation is satisfied for now (still all other conditions
must be met of course). One obvious case this comes up is
marker traits like Send
. Think of a linked list:
struct List<T> { data: T, next: Option<Box<List<T>>> }
Box<List<T>>
will be Send
if T
is Send
and
Option<Box<List<T>>>
is Send
, and in turn
Option<Box<List<T>>>
is Send
if Box<List<T>>
is
Send
.
Note that we do this comparison using the fresh_trait_ref
fields. Because these have all been freshened using
self.freshener
, we can be sure that (a) this will not
affect the inferencer state and (b) that if we see two
fresh regions with the same index, they refer to the same
unbound type variable.
fn evaluate_stack<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> Result<EvaluationResult, OverflowError>
sourcepub(crate) fn coinductive_match<I>(&mut self, cycle: I) -> bool
pub(crate) fn coinductive_match<I>(&mut self, cycle: I) -> bool
For defaulted traits, we use a co-inductive strategy to solve, so
that recursion is ok. This routine returns true
if the top of the
stack (cycle[0]
):
- is a defaulted trait,
- it also appears in the backtrace at some position
X
, - all the predicates at positions
X..
betweenX
and the top are also defaulted traits.
sourcefn evaluate_candidate<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
candidate: &SelectionCandidate<'tcx>,
) -> Result<EvaluationResult, OverflowError>
fn evaluate_candidate<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidate: &SelectionCandidate<'tcx>, ) -> Result<EvaluationResult, OverflowError>
Further evaluates candidate
to decide whether all type parameters match and whether nested
obligations are met. Returns whether candidate
remains viable after this further
scrutiny.
fn check_evaluation_cache( &self, param_env: ParamEnv<'tcx>, trait_pred: PolyTraitPredicate<'tcx>, ) -> Option<EvaluationResult>
fn insert_evaluation_cache( &mut self, param_env: ParamEnv<'tcx>, trait_pred: PolyTraitPredicate<'tcx>, dep_node: DepNodeIndex, result: EvaluationResult, )
fn check_recursion_depth<T>( &self, depth: usize, error_obligation: &Obligation<'tcx, T>, ) -> Result<(), OverflowError>
sourcefn check_recursion_limit<T: Display + TypeFoldable<TyCtxt<'tcx>>, V>(
&self,
obligation: &Obligation<'tcx, T>,
error_obligation: &Obligation<'tcx, V>,
) -> Result<(), OverflowError>
fn check_recursion_limit<T: Display + TypeFoldable<TyCtxt<'tcx>>, V>( &self, obligation: &Obligation<'tcx, T>, error_obligation: &Obligation<'tcx, V>, ) -> Result<(), OverflowError>
Checks that the recursion limit has not been exceeded.
The weird return type of this function allows it to be used with the try
(?
)
operator within certain functions.
fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)where
OP: FnOnce(&mut Self) -> R,
sourcefn filter_impls(
&mut self,
candidates: Vec<SelectionCandidate<'tcx>>,
obligation: &PolyTraitObligation<'tcx>,
) -> Vec<SelectionCandidate<'tcx>>
fn filter_impls( &mut self, candidates: Vec<SelectionCandidate<'tcx>>, obligation: &PolyTraitObligation<'tcx>, ) -> Vec<SelectionCandidate<'tcx>>
filter_impls filters candidates that have a positive impl for a negative goal and a negative impl for a positive goal
sourcefn filter_reservation_impls(
&mut self,
candidate: SelectionCandidate<'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>
fn filter_reservation_impls( &mut self, candidate: SelectionCandidate<'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>
filter_reservation_impls filter reservation impl for any goal as ambiguous
fn is_knowable<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> Result<(), Conflict>
sourcefn can_use_global_caches(
&self,
param_env: ParamEnv<'tcx>,
pred: PolyTraitPredicate<'tcx>,
) -> bool
fn can_use_global_caches( &self, param_env: ParamEnv<'tcx>, pred: PolyTraitPredicate<'tcx>, ) -> bool
Returns true
if the global caches can be used.
fn check_candidate_cache( &mut self, param_env: ParamEnv<'tcx>, cache_fresh_trait_pred: PolyTraitPredicate<'tcx>, ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>>
sourcefn can_cache_candidate(
&self,
result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>,
) -> bool
fn can_cache_candidate( &self, result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>, ) -> bool
Determines whether can we safely cache the result
of selecting an obligation. This is almost always true
,
except when dealing with certain ParamCandidate
s.
Ordinarily, a ParamCandidate
will contain no inference variables,
since it was usually produced directly from a DefId
. However,
certain cases (currently only librustdoc’s blanket impl finder),
a ParamEnv
may be explicitly constructed with inference types.
When this is the case, we do not want to cache the resulting selection
candidate. This is due to the fact that it might not always be possible
to equate the obligation’s trait ref and the candidate’s trait ref,
if more constraints end up getting added to an inference variable.
Because of this, we always want to re-run the full selection
process for our obligation the next time we see it, since
we might end up picking a different SelectionCandidate
(or none at all).
fn insert_candidate_cache( &mut self, param_env: ParamEnv<'tcx>, cache_fresh_trait_pred: PolyTraitPredicate<'tcx>, dep_node: DepNodeIndex, candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>, )
sourcepub(super) fn for_each_item_bound<T>(
&mut self,
self_ty: Ty<'tcx>,
for_each: impl FnMut(&mut Self, Clause<'tcx>, usize) -> ControlFlow<T, ()>,
on_ambiguity: impl FnOnce(),
) -> ControlFlow<T, ()>
pub(super) fn for_each_item_bound<T>( &mut self, self_ty: Ty<'tcx>, for_each: impl FnMut(&mut Self, Clause<'tcx>, usize) -> ControlFlow<T, ()>, on_ambiguity: impl FnOnce(), ) -> ControlFlow<T, ()>
Looks at the item bounds of the projection or opaque type.
If this is a nested rigid projection, such as
<<T as Tr1>::Assoc as Tr2>::Assoc
, consider the item bounds
on both Tr1::Assoc
and Tr2::Assoc
, since we may encounter
relative bounds on both via the associated_type_bounds
feature.
sourcefn match_normalize_trait_ref(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
placeholder_trait_ref: TraitRef<'tcx>,
trait_bound: PolyTraitRef<'tcx>,
) -> Result<Option<TraitRef<'tcx>>, ()>
fn match_normalize_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, placeholder_trait_ref: TraitRef<'tcx>, trait_bound: PolyTraitRef<'tcx>, ) -> Result<Option<TraitRef<'tcx>>, ()>
Equates the trait in obligation
with trait bound. If the two traits
can be equated and the normalized trait bound doesn’t contain inference
variables or placeholders, the normalized bound is returned.
fn where_clause_may_apply<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: PolyTraitRef<'tcx>, ) -> Result<EvaluationResult, OverflowError>
sourcepub(super) fn match_projection_projections(
&mut self,
obligation: &ProjectionTermObligation<'tcx>,
env_predicate: PolyProjectionPredicate<'tcx>,
potentially_unnormalized_candidates: bool,
) -> ProjectionMatchesProjection
pub(super) fn match_projection_projections( &mut self, obligation: &ProjectionTermObligation<'tcx>, env_predicate: PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidates: bool, ) -> ProjectionMatchesProjection
Return Yes
if the obligation’s predicate type applies to the env_predicate, and
No
if it does not. Return Ambiguous
in the case that the projection type is a GAT,
and applying this env_predicate constrains any of the obligation’s GAT parameters.
This behavior is a somewhat of a hack to prevent over-constraining inference variables in cases like #91762.
source§impl<'tcx> SelectionContext<'_, 'tcx>
impl<'tcx> SelectionContext<'_, 'tcx>
§Winnowing
Winnowing is the process of attempting to resolve ambiguity by probing further. During the winnowing process, we unify all type variables and then we also attempt to evaluate recursive bounds to see if they are satisfied.
sourcefn candidate_should_be_dropped_in_favor_of(
&mut self,
victim: &EvaluatedCandidate<'tcx>,
other: &EvaluatedCandidate<'tcx>,
has_non_region_infer: bool,
) -> DropVictim
fn candidate_should_be_dropped_in_favor_of( &mut self, victim: &EvaluatedCandidate<'tcx>, other: &EvaluatedCandidate<'tcx>, has_non_region_infer: bool, ) -> DropVictim
Returns DropVictim::Yes
if victim
should be dropped in favor of
other
. Generally speaking we will drop duplicate
candidates and prefer where-clause candidates.
See the comment for “SelectionCandidate” for more details.
source§impl<'tcx> SelectionContext<'_, 'tcx>
impl<'tcx> SelectionContext<'_, 'tcx>
fn sized_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx>
fn copy_clone_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx>
fn fused_iterator_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx>
sourcefn constituent_types_for_ty(
&self,
t: Binder<'tcx, Ty<'tcx>>,
) -> Result<Binder<'tcx, Vec<Ty<'tcx>>>, SelectionError<'tcx>>
fn constituent_types_for_ty( &self, t: Binder<'tcx, Ty<'tcx>>, ) -> Result<Binder<'tcx, Vec<Ty<'tcx>>>, SelectionError<'tcx>>
For default impls, we need to break apart a type into its “constituent types” – meaning, the types that it contains.
Here are some (simple) examples:
(i32, u32) -> [i32, u32]
Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
fn collect_predicates_for_types( &mut self, param_env: ParamEnv<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, trait_def_id: DefId, types: Binder<'tcx, Vec<Ty<'tcx>>>, ) -> Vec<PredicateObligation<'tcx>>
fn rematch_impl( &mut self, impl_def_id: DefId, obligation: &PolyTraitObligation<'tcx>, ) -> Normalized<'tcx, GenericArgsRef<'tcx>>
fn match_impl( &mut self, impl_def_id: DefId, impl_trait_header: ImplTraitHeader<'tcx>, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()>
fn match_upcast_principal( &mut self, obligation: &PolyTraitObligation<'tcx>, unnormalized_upcast_principal: PolyTraitRef<'tcx>, a_data: &'tcx List<PolyExistentialPredicate<'tcx>>, b_data: &'tcx List<PolyExistentialPredicate<'tcx>>, a_region: Region<'tcx>, b_region: Region<'tcx>, ) -> SelectionResult<'tcx, Vec<PredicateObligation<'tcx>>>
sourcefn match_where_clause_trait_ref(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
where_clause_trait_ref: PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, ()>
fn match_where_clause_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, where_clause_trait_ref: PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, ()>
Normalize where_clause_trait_ref
and try to match it against
obligation
. If successful, return any predicates that
result from the normalization.
sourcefn match_poly_trait_ref(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
poly_trait_ref: PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, ()>
fn match_poly_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, poly_trait_ref: PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, ()>
Returns Ok
if poly_trait_ref
being true implies that the
obligation is satisfied.
fn match_fresh_trait_refs( &self, previous: PolyTraitPredicate<'tcx>, current: PolyTraitPredicate<'tcx>, ) -> bool
fn push_stack<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &'o PolyTraitObligation<'tcx>, ) -> TraitObligationStack<'o, 'tcx>
fn closure_trait_ref_unnormalized( &mut self, self_ty: Ty<'tcx>, fn_trait_def_id: DefId, fn_host_effect: Const<'tcx>, ) -> PolyTraitRef<'tcx>
sourcefn impl_or_trait_obligations(
&mut self,
cause: &ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ParamEnv<'tcx>,
def_id: DefId,
args: GenericArgsRef<'tcx>,
parent_trait_pred: Binder<'tcx, TraitPredicate<'tcx>>,
) -> Vec<PredicateObligation<'tcx>>
fn impl_or_trait_obligations( &mut self, cause: &ObligationCause<'tcx>, recursion_depth: usize, param_env: ParamEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, parent_trait_pred: Binder<'tcx, TraitPredicate<'tcx>>, ) -> Vec<PredicateObligation<'tcx>>
Returns the obligations that are implied by instantiating an impl or trait. The obligations are instantiated and fully normalized. This is used when confirming an impl or default impl.
Auto Trait Implementations§
impl<'cx, 'tcx> Freeze for SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> !RefUnwindSafe for SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> !Send for SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> !Sync for SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> Unpin for SelectionContext<'cx, 'tcx>
impl<'cx, 'tcx> !UnwindSafe for SelectionContext<'cx, 'tcx>
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
source§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
source§impl<T> Filterable for T
impl<T> Filterable for T
source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§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 moresource§impl<P> IntoQueryParam<P> for P
impl<P> IntoQueryParam<P> for P
fn into_query_param(self) -> P
source§impl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
source§impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T
source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<T> MaybeSendSync for T
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 152 bytes