pub struct InferCtxt<'db> {
pub interner: DbInterner<'db>,
typing_mode: TypingMode<'db>,
pub inner: RefCell<InferCtxtInner<'db>>,
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
universe: Cell<UniverseIndex>,
obligation_inspector: Cell<Option<ObligationInspector<'db>>>,
}Fields§
§interner: DbInterner<'db>§typing_mode: TypingMode<'db>The mode of this inference context, see the struct documentation for more details.
inner: RefCell<InferCtxtInner<'db>>§tainted_by_errors: Cell<Option<ErrorGuaranteed>>When an error occurs, we want to avoid reporting “derived” errors that are due to this original failure. We have this flag that one can set whenever one creates a type-error that is due to an error in a prior pass.
Don’t read this flag directly, call is_tainted_by_errors()
and set_tainted_by_errors().
universe: Cell<UniverseIndex>What is the innermost universe we have created? Starts out as
UniverseIndex::root() but grows from there as we enter
universal quantifiers.
N.B., at present, we exclude the universal quantifiers on the
item we are type-checking, and just consider those names as
part of the root universe. So this would only get incremented
when we enter into a higher-ranked (for<..>) type or trait
bound.
obligation_inspector: Cell<Option<ObligationInspector<'db>>>Implementations§
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
pub fn at<'a>( &'a self, cause: &'a ObligationCause, param_env: ParamEnv<'db>, ) -> At<'a, 'db>
Sourcepub fn fork(&self) -> Self
pub fn fork(&self) -> Self
Forks the inference context, creating a new inference context with the same inference variables in the same state. This can be used to “branch off” many tests from the same common state.
Sourcepub fn fork_with_typing_mode(
&self,
typing_mode: TypingMode<DbInterner<'db>>,
) -> Self
pub fn fork_with_typing_mode( &self, typing_mode: TypingMode<DbInterner<'db>>, ) -> Self
Forks the inference context, creating a new inference context with the same inference variables in the same state, except possibly changing the intercrate mode. This can be used to “branch off” many tests from the same common state. Used in negative coherence.
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Sourcepub fn canonicalize_query<V>(
&self,
value: V,
query_state: &mut OriginalQueryValues<'db>,
) -> Canonical<'db, V>where
V: TypeFoldable<DbInterner<'db>>,
pub fn canonicalize_query<V>(
&self,
value: V,
query_state: &mut OriginalQueryValues<'db>,
) -> Canonical<'db, V>where
V: TypeFoldable<DbInterner<'db>>,
Canonicalizes a query value V. When we canonicalize a query,
we not only canonicalize unbound inference variables, but we
also replace all free regions whatsoever. So for example a
query like T: Trait<'static> would be canonicalized to
T: Trait<'?0>with a mapping M that maps '?0 to 'static.
To get a good understanding of what is happening here, check out the chapter in the rustc dev guide.
Sourcepub fn canonicalize_response<V>(&self, value: V) -> Canonical<'db, V>where
V: TypeFoldable<DbInterner<'db>>,
pub fn canonicalize_response<V>(&self, value: V) -> Canonical<'db, V>where
V: TypeFoldable<DbInterner<'db>>,
Canonicalizes a query response V. When we canonicalize a
query response, we only canonicalize unbound inference
variables, and we leave other free regions alone. So,
continuing with the example from canonicalize_query, if
there was an input query T: Trait<'static>, it would have
been canonicalized to
T: Trait<'?0>with a mapping M that maps '?0 to 'static. But if we found that there
exists only one possible impl of Trait, and it looks like
impl<T> Trait<'static> for T { .. }then we would prepare a query result R that (among other
things) includes a mapping to '?0 := 'static. When
canonicalizing this query result R, we would leave this
reference to 'static alone.
To get a good understanding of what is happening here, check out the chapter in the rustc dev guide.
pub fn canonicalize_user_type_annotation<V>(
&self,
value: V,
) -> Canonical<'db, V>where
V: TypeFoldable<DbInterner<'db>>,
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Sourcepub fn make_query_response_ignoring_pending_obligations<T>(
&self,
inference_vars: CanonicalVarValues<'db>,
answer: T,
prev_entries: OpaqueTypeStorageEntries,
) -> Canonical<'db, QueryResponse<'db, T>>where
T: TypeFoldable<DbInterner<'db>>,
pub fn make_query_response_ignoring_pending_obligations<T>(
&self,
inference_vars: CanonicalVarValues<'db>,
answer: T,
prev_entries: OpaqueTypeStorageEntries,
) -> Canonical<'db, QueryResponse<'db, T>>where
T: TypeFoldable<DbInterner<'db>>,
A version of make_canonicalized_query_response that does
not pack in obligations, for contexts that want to drop
pending obligations instead of treating them as an ambiguity (e.g.
typeck “probing” contexts).
If you DO want to keep track of pending obligations (which include all region obligations, so this includes all cases that care about regions) with this function, you have to do it yourself, by e.g., having them be a part of the answer.
Sourcepub fn instantiate_query_response_and_region_obligations<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, R>where
R: TypeFoldable<DbInterner<'db>>,
pub fn instantiate_query_response_and_region_obligations<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, R>where
R: TypeFoldable<DbInterner<'db>>,
Given the (canonicalized) result to a canonical query, instantiates the result so it can be used, plugging in the values from the canonical query. (Note that the result may have been ambiguous; you should check the certainty level of the query before applying this function.)
To get a good understanding of what is happening here, check out the chapter in the rustc dev guide.
Sourcefn query_response_instantiation<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, CanonicalVarValues<'db>>where
R: Debug + TypeFoldable<DbInterner<'db>>,
fn query_response_instantiation<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, CanonicalVarValues<'db>>where
R: Debug + TypeFoldable<DbInterner<'db>>,
Given the original values and the (canonicalized) result from computing a query, returns an instantiation that can be applied to the query result to convert the result back into the original namespace.
The instantiation also comes accompanied with subobligations that arose from unification; these might occur if (for example) we are doing lazy normalization and the value assigned to a type variable is unified with an unnormalized projection.
Sourcefn query_response_instantiation_guess<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, CanonicalVarValues<'db>>where
R: Debug + TypeFoldable<DbInterner<'db>>,
fn query_response_instantiation_guess<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, CanonicalVarValues<'db>>where
R: Debug + TypeFoldable<DbInterner<'db>>,
Given the original values and the (canonicalized) result from computing a query, returns a guess at an instantiation that can be applied to the query result to convert the result back into the original namespace. This is called a guess because it uses a quick heuristic to find the values for each canonical variable; if that quick heuristic fails, then we will instantiate fresh inference variables for each canonical variable instead. Therefore, the result of this method must be properly unified
Sourcefn unify_query_response_instantiation_guess<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
result_args: &CanonicalVarValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, ()>where
R: Debug + TypeFoldable<DbInterner<'db>>,
fn unify_query_response_instantiation_guess<R>(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
original_values: &OriginalQueryValues<'db>,
result_args: &CanonicalVarValues<'db>,
query_response: &Canonical<'db, QueryResponse<'db, R>>,
) -> InferResult<'db, ()>where
R: Debug + TypeFoldable<DbInterner<'db>>,
Given a “guess” at the values for the canonical variables in the input, try to unify with the actual values found in the query result. Often, but not always, this is a no-op, because we already found the mapping in the “guessing” step.
See also: Self::query_response_instantiation_guess
Sourcefn unify_canonical_vars(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
variables1: &OriginalQueryValues<'db>,
variables2: impl Fn(BoundVar) -> GenericArg<'db>,
) -> InferResult<'db, ()>
fn unify_canonical_vars( &self, cause: &ObligationCause, param_env: ParamEnv<'db>, variables1: &OriginalQueryValues<'db>, variables2: impl Fn(BoundVar) -> GenericArg<'db>, ) -> InferResult<'db, ()>
Given two sets of values for the same set of canonical variables, unify them. The second set is produced lazily by supplying indices from the first set.
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Sourcepub fn instantiate_canonical<T>(
&self,
span: Span,
canonical: &Canonical<'db, T>,
) -> (T, CanonicalVarValues<'db>)where
T: TypeFoldable<DbInterner<'db>>,
pub fn instantiate_canonical<T>(
&self,
span: Span,
canonical: &Canonical<'db, T>,
) -> (T, CanonicalVarValues<'db>)where
T: TypeFoldable<DbInterner<'db>>,
Creates an instantiation S for the canonical value with fresh inference variables and placeholders then applies it to the canonical value. Returns both the instantiated result and the instantiation S.
This can be invoked as part of constructing an
inference context at the start of a query (see
InferCtxtBuilder::build_with_canonical). It basically
brings the canonical value “into scope” within your new infcx.
At the end of processing, the instantiation S (once canonicalized) then represents the values that you computed for each of the canonical inputs to your query.
Sourcepub fn instantiate_canonical_var(
&self,
span: Span,
cv_info: CanonicalVarKind<DbInterner<'db>>,
previous_var_values: &[GenericArg<'db>],
universe_map: impl Fn(UniverseIndex) -> UniverseIndex,
) -> GenericArg<'db>
pub fn instantiate_canonical_var( &self, span: Span, cv_info: CanonicalVarKind<DbInterner<'db>>, previous_var_values: &[GenericArg<'db>], universe_map: impl Fn(UniverseIndex) -> UniverseIndex, ) -> GenericArg<'db>
Given the “info” about a canonical variable, creates a fresh variable for it. If this is an existentially quantified variable, then you’ll get a new inference variable; if it is a universally quantified variable, you get a placeholder.
FIXME(-Znext-solver): This is public because it’s used by the new trait solver which has a different canonicalization routine. We should somehow deduplicate all of this.
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Insert a hidden type into the opaque type storage, making sure it hasn’t previously been defined. This does not emit any constraints and it’s the responsibility of the caller to make sure that the item bounds of the opaque are checked.
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
pub fn register_outlives_constraint( &self, OutlivesPredicate: ArgOutlivesPredicate<'db>, )
pub fn register_region_outlives_constraint( &self, OutlivesPredicate: RegionOutlivesPredicate<'db>, )
Sourcepub fn register_type_outlives_constraint_inner(
&self,
obligation: TypeOutlivesConstraint<'db>,
)
pub fn register_type_outlives_constraint_inner( &self, obligation: TypeOutlivesConstraint<'db>, )
Registers that the given region obligation must be resolved
from within the scope of body_id. These regions are enqueued
and later processed by regionck, when full type information is
available (see region_obligations field for more
information).
pub fn register_type_outlives_constraint( &self, sup_type: Ty<'db>, sub_region: Region<'db>, )
pub fn register_region_assumption(&self, assumption: ArgOutlivesPredicate<'db>)
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Sourcepub fn instantiate_ty_var<R: PredicateEmittingRelation<InferCtxt<'db>>>(
&self,
relation: &mut R,
target_is_expected: bool,
target_vid: TyVid,
instantiation_variance: Variance,
source_ty: Ty<'db>,
) -> RelateResult<'db, ()>
pub fn instantiate_ty_var<R: PredicateEmittingRelation<InferCtxt<'db>>>( &self, relation: &mut R, target_is_expected: bool, target_vid: TyVid, instantiation_variance: Variance, source_ty: Ty<'db>, ) -> RelateResult<'db, ()>
The idea is that we should ensure that the type variable target_vid
is equal to, a subtype of, or a supertype of source_ty.
For this, we will instantiate target_vid with a generalized version
of source_ty. Generalization introduces other inference variables wherever
subtyping could occur. This also does the occurs checks, detecting whether
instantiating target_vid would result in a cyclic type. We eagerly error
in this case.
This is not expected to be used anywhere except for an implementation of
TypeRelation. Do not use this, and instead please use At::eq, for all
other usecases (i.e. setting the value of a type var).
Sourcepub(crate) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'db>>>(
&self,
relation: &mut R,
target_is_expected: bool,
target_vid: ConstVid,
source_ct: Const<'db>,
) -> RelateResult<'db, ()>
pub(crate) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'db>>>( &self, relation: &mut R, target_is_expected: bool, target_vid: ConstVid, source_ct: Const<'db>, ) -> RelateResult<'db, ()>
Instantiates the const variable target_vid with the given constant.
This also tests if the given const ct contains an inference variable which was previously
unioned with target_vid. If this is the case, inferring target_vid to ct
would result in an infinite type as we continuously replace an inference variable
in ct with ct itself.
This is especially important as unevaluated consts use their parents generics. They therefore often contain unused args, making these errors far more likely.
A good example of this is the following:
#![feature(generic_const_exprs)]
fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
todo!()
}
fn main() {
let mut arr = Default::default();
arr = bind(arr);
}Here 3 + 4 ends up as ConstKind::Unevaluated which uses the generics
of fn bind (meaning that its args contain N).
bind(arr) now infers that the type of arr must be [u8; N].
The assignment arr = bind(arr) now tries to equate N with 3 + 4.
As 3 + 4 contains N in its args, this must not succeed.
See tests/ui/const-generics/occurs-check/ for more examples where this is relevant.
Sourcefn generalize<T: Into<Term<'db>> + Relate<DbInterner<'db>>>(
&self,
span: Span,
structurally_relate_aliases: StructurallyRelateAliases,
target_vid: impl Into<TermVid>,
ambient_variance: Variance,
source_term: T,
) -> RelateResult<'db, Generalization<T>>
fn generalize<T: Into<Term<'db>> + Relate<DbInterner<'db>>>( &self, span: Span, structurally_relate_aliases: StructurallyRelateAliases, target_vid: impl Into<TermVid>, ambient_variance: Variance, source_term: T, ) -> RelateResult<'db, Generalization<T>>
Attempts to generalize source_term for the type variable target_vid.
This checks for cycles – that is, whether source_term references target_vid.
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Sourcepub fn enter_forall_and_leak_universe<T>(&self, binder: Binder<'db, T>) -> Twhere
T: TypeFoldable<DbInterner<'db>> + Clone,
pub fn enter_forall_and_leak_universe<T>(&self, binder: Binder<'db, T>) -> Twhere
T: TypeFoldable<DbInterner<'db>> + Clone,
Replaces all bound variables (lifetimes, types, and constants) bound by
binder with placeholder variables in a new universe. This means that the
new placeholders can only be named by inference variables created after
this method has been called.
This is the first step of checking subtyping when higher-ranked things are involved. For more details visit the relevant sections of the rustc dev guide.
fn enter_forall should be preferred over this method.
Sourcepub fn enter_forall<T, U>(
&self,
forall: Binder<'db, T>,
f: impl FnOnce(T) -> U,
) -> Uwhere
T: TypeFoldable<DbInterner<'db>> + Clone,
pub fn enter_forall<T, U>(
&self,
forall: Binder<'db, T>,
f: impl FnOnce(T) -> U,
) -> Uwhere
T: TypeFoldable<DbInterner<'db>> + Clone,
Replaces all bound variables (lifetimes, types, and constants) bound by
binder with placeholder variables in a new universe and then calls the
closure f with the instantiated value. The new placeholders can only be
named by inference variables created inside of the closure f or afterwards.
This is the first step of checking subtyping when higher-ranked things are involved. For more details visit the relevant sections of the rustc dev guide.
This method should be preferred over fn enter_forall_and_leak_universe.
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
pub(crate) fn select( &self, obligation: &Obligation<'db, TraitPredicate<'db>>, ) -> Result<Option<ImplSource<'db, Obligation<'db, Predicate<'db>>>>, SelectionError<'db>>
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
Sourcepub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
pub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
This rather funky routine is used while processing expected
types. What happens here is that we want to propagate a
coercion through the return type of a fn to its
argument. Consider the type of Option::Some, which is
basically for<T> fn(T) -> Option<T>. So if we have an
expression Some(&[1, 2, 3]), and that has the expected type
Option<&[u32]>, we would like to type check &[1, 2, 3]
with the expectation of &[u32]. This will cause us to coerce
from &[u32; 3] to &[u32] and make the users life more
pleasant.
The way we do this is using fudge_inference_if_ok. What the
routine actually does is to start a snapshot and execute the
closure f. In our example above, what this closure will do
is to unify the expectation (Option<&[u32]>) with the actual
return type (Option<?T>, where ?T represents the variable
instantiated for T). This will cause ?T to be unified
with &?a [u32], where ?a is a fresh lifetime variable. The
input type (?T) is then returned by f().
At this point, fudge_inference_if_ok will normalize all type
variables, converting ?T to &?a [u32] and end the
snapshot. The problem is that we can’t just return this type
out, because it references the region variable ?a, and that
region variable was popped when we popped the snapshot.
So what we do is to keep a list (region_vars, in the code below)
of region variables created during the snapshot (here, ?a). We
fold the return value and replace any such regions with a new
region variable (e.g., ?b) and return the result (&?b [u32]).
This can then be used as the expectation for the fn argument.
The important point here is that, for soundness purposes, the
regions in question are not particularly important. We will
use the expected types to guide coercions, but we will still
type-check the resulting types from those coercions against
the actual types (?T, Option<?T>) – and remember that
after the snapshot is popped, the variable ?T is no longer
unified.
fn fudge_inference<T: TypeFoldable<DbInterner<'db>>>( &self, snapshot_vars: SnapshotVarData, value: T, ) -> T
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
fn variable_lengths(&self) -> VariableLengths
pub fn in_snapshot(&self) -> bool
pub fn num_open_snapshots(&self) -> usize
pub fn start_snapshot(&self) -> CombinedSnapshot
pub fn rollback_to(&self, snapshot: CombinedSnapshot)
pub fn commit_from(&self, snapshot: CombinedSnapshot)
Sourcepub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
Execute f and commit the bindings if closure f returns Ok(_).
Sourcepub fn probe<R, F>(&self, f: F) -> Rwhere
F: FnOnce(&CombinedSnapshot) -> R,
pub fn probe<R, F>(&self, f: F) -> Rwhere
F: FnOnce(&CombinedSnapshot) -> R,
Execute f then unroll any bindings it creates.
Sourcepub fn region_constraints_added_in_snapshot(
&self,
snapshot: &CombinedSnapshot,
) -> bool
pub fn region_constraints_added_in_snapshot( &self, snapshot: &CombinedSnapshot, ) -> bool
Scan the constraints produced since snapshot and check whether
we added any region constraints.
pub fn opaque_types_added_in_snapshot( &self, snapshot: &CombinedSnapshot, ) -> bool
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
pub fn typing_mode_raw(&self) -> TypingMode<'db>
pub fn typing_mode_unchecked(&self) -> TypingMode<'db>
Sourcepub fn predicate_may_hold(
&self,
obligation: &Obligation<'db, Predicate<'db>>,
) -> bool
pub fn predicate_may_hold( &self, obligation: &Obligation<'db, Predicate<'db>>, ) -> bool
Evaluates whether the predicate can be satisfied (by any means)
in the given ParamEnv.
Sourcepub fn predicate_may_hold_opaque_types_jank(
&self,
obligation: &Obligation<'db, Predicate<'db>>,
) -> bool
pub fn predicate_may_hold_opaque_types_jank( &self, obligation: &Obligation<'db, Predicate<'db>>, ) -> bool
See the comment on GeneralAutoderef::overloaded_deref_ty
for more details.
pub(crate) fn insert_type_vars<T>(&self, ty: T) -> Twhere
T: TypeFoldable<DbInterner<'db>>,
Sourcepub fn predicate_must_hold_considering_regions(
&self,
obligation: &Obligation<'db, Predicate<'db>>,
) -> bool
pub fn predicate_must_hold_considering_regions( &self, obligation: &Obligation<'db, Predicate<'db>>, ) -> bool
Evaluates whether the predicate can be satisfied in the given
ParamEnv, and returns false if not certain. However, this is
not entirely accurate if inference variables are involved.
This version may conservatively fail when outlives obligations
are required. Therefore, this version should only be used for
optimizations or diagnostics and be treated as if it can always
return false.
§Example
trait Trait {}
fn check<T: Trait>() {}
fn foo<T: 'static>()
where
&'static T: Trait,
{
// Evaluating `&'?0 T: Trait` adds a `'?0: 'static` outlives obligation,
// which means that `predicate_must_hold_considering_regions` will return
// `false`.
check::<&'_ T>();
}Sourcepub fn predicate_must_hold_modulo_regions(
&self,
obligation: &Obligation<'db, Predicate<'db>>,
) -> bool
pub fn predicate_must_hold_modulo_regions( &self, obligation: &Obligation<'db, Predicate<'db>>, ) -> bool
Evaluates whether the predicate can be satisfied in the given
ParamEnv, and returns false if not certain. However, this is
not entirely accurate if inference variables are involved.
This version ignores all outlives constraints.
Sourcepub fn type_implements_trait(
&self,
trait_def_id: TraitId,
params: impl IntoIterator<Item: Into<GenericArg<'db>>>,
param_env: ParamEnv<'db>,
) -> EvaluationResult
pub fn type_implements_trait( &self, trait_def_id: TraitId, params: impl IntoIterator<Item: Into<GenericArg<'db>>>, param_env: ParamEnv<'db>, ) -> EvaluationResult
Check whether a ty implements given trait(trait_def_id) without side-effects.
The inputs are:
- the def-id of the trait
- the type parameters of the trait, including the self-type
- the parameter environment
Invokes evaluate_obligation, so in the event that evaluating
Ty: Trait causes overflow, EvaluatedToAmbigStackDependent will be returned.
type_implements_trait is a convenience function for simple cases like
let copy_trait = infcx.tcx.require_lang_item(LangItem::Copy, span);
let implements_copy = infcx.type_implements_trait(copy_trait, [ty], param_env)
.must_apply_modulo_regions();In most cases you should instead create an Obligation and check whether
it holds via evaluate_obligation or one of its helper functions like
predicate_must_hold_modulo_regions, because it properly handles higher ranked traits
and it is more convenient and safer when your params are inside a Binder.
Sourcefn evaluate_obligation(
&self,
obligation: &Obligation<'db, Predicate<'db>>,
) -> EvaluationResult
fn evaluate_obligation( &self, obligation: &Obligation<'db, Predicate<'db>>, ) -> EvaluationResult
Evaluate a given predicate, capturing overflow and propagating it back.
pub fn can_eq<T: ToTrace<'db>>( &self, param_env: ParamEnv<'db>, a: T, b: T, ) -> bool
Sourcepub fn goal_may_hold_opaque_types_jank(
&self,
goal: Goal<'db, Predicate<'db>>,
) -> bool
pub fn goal_may_hold_opaque_types_jank( &self, goal: Goal<'db, Predicate<'db>>, ) -> bool
See the comment on GeneralAutoderef::overloaded_deref_ty
for more details.
pub fn type_is_copy_modulo_regions( &self, param_env: ParamEnv<'db>, ty: Ty<'db>, ) -> bool
pub fn type_is_sized_modulo_regions( &self, param_env: ParamEnv<'db>, ty: Ty<'db>, ) -> bool
pub fn type_is_use_cloned_modulo_regions( &self, param_env: ParamEnv<'db>, ty: Ty<'db>, ) -> bool
pub fn unresolved_variables(&self) -> Vec<Ty<'db>>
pub fn sub_regions(&self, a: Region<'db>, b: Region<'db>)
Sourcepub fn coerce_predicate(
&self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
predicate: PolyCoercePredicate<'db>,
) -> Result<InferResult<'db, ()>, (TyVid, TyVid)>
pub fn coerce_predicate( &self, cause: &ObligationCause, param_env: ParamEnv<'db>, predicate: PolyCoercePredicate<'db>, ) -> Result<InferResult<'db, ()>, (TyVid, TyVid)>
Processes a Coerce predicate from the fulfillment context.
This is NOT the preferred way to handle coercion, which is to
invoke FnCtxt::coerce or a similar method (see coercion.rs).
This method here is actually a fallback that winds up being
invoked when FnCtxt::coerce encounters unresolved type variables
and records a coercion predicate. Presently, this method is equivalent
to subtype_predicate – that is, “coercing” a to b winds up
actually requiring a <: b. This is of course a valid coercion,
but it’s not as flexible as FnCtxt::coerce would be.
(We may refactor this in the future, but there are a number of
practical obstacles. Among other things, FnCtxt::coerce presently
records adjustments that are required on the HIR in order to perform
the coercion, and we don’t currently have a way to manage that.)
pub fn subtype_predicate( &self, cause: &ObligationCause, param_env: ParamEnv<'db>, predicate: PolySubtypePredicate<'db>, ) -> Result<InferResult<'db, ()>, (TyVid, TyVid)>
pub fn region_outlives_predicate( &self, _cause: &ObligationCause, predicate: PolyRegionOutlivesPredicate<'db>, )
Sourcepub fn num_ty_vars(&self) -> usize
pub fn num_ty_vars(&self) -> usize
Number of type variables created so far.
pub fn next_ty_var(&self, span: Span) -> Ty<'db>
pub fn next_ty_vid(&self, span: Span) -> TyVid
pub fn next_ty_var_id_in_universe( &self, universe: UniverseIndex, span: Span, ) -> TyVid
pub fn next_ty_var_in_universe( &self, universe: UniverseIndex, span: Span, ) -> Ty<'db>
pub fn next_const_var(&self, span: Span) -> Const<'db>
pub fn next_const_vid(&self, span: Span) -> ConstVid
pub fn next_const_vid_in_universe( &self, universe: UniverseIndex, span: Span, ) -> ConstVid
pub fn next_const_var_in_universe( &self, universe: UniverseIndex, span: Span, ) -> Const<'db>
pub fn next_int_var(&self) -> Ty<'db>
pub fn next_int_vid(&self) -> IntVid
pub fn next_float_var(&self) -> Ty<'db>
pub fn next_float_vid(&self) -> FloatVid
Sourcepub fn next_region_var(&self, span: Span) -> Region<'db>
pub fn next_region_var(&self, span: Span) -> Region<'db>
Creates a fresh region variable with the next available index. The variable will be created in the maximum universe created thus far, allowing it to name any region created thus far.
pub fn next_region_vid(&self, span: Span) -> RegionVid
Sourcepub fn next_region_var_in_universe(
&self,
universe: UniverseIndex,
span: Span,
) -> Region<'db>
pub fn next_region_var_in_universe( &self, universe: UniverseIndex, span: Span, ) -> Region<'db>
Creates a fresh region variable with the next available index
in the given universe; typically, you can use
next_region_var and just use the maximal universe.
pub fn next_term_var_of_kind(&self, term: Term<'db>, span: Span) -> Term<'db>
Sourcepub fn universe_of_region(&self, r: Region<'db>) -> UniverseIndex
pub fn universe_of_region(&self, r: Region<'db>) -> UniverseIndex
Return the universe that the region r was created in. For
most regions (e.g., 'static, named regions from the user,
etc) this is the root universe U0. For inference variables or
placeholders, however, it will return the universe which they
are associated.
Sourcepub fn num_region_vars(&self) -> usize
pub fn num_region_vars(&self) -> usize
Number of region variables created so far.
pub fn var_for_def(&self, id: GenericParamId, span: Span) -> GenericArg<'db>
Sourcepub fn fresh_args_for_item(
&self,
span: Span,
def_id: SolverDefId<'db>,
) -> GenericArgs<'db>
pub fn fresh_args_for_item( &self, span: Span, def_id: SolverDefId<'db>, ) -> GenericArgs<'db>
Given a set of generics defined on a type or impl, returns the generic parameters mapping each type/region parameter to a fresh inference variable.
Sourcepub fn fill_rest_fresh_args(
&self,
span: Span,
def_id: SolverDefId<'db>,
first: impl IntoIterator<Item = GenericArg<'db>>,
) -> GenericArgs<'db>
pub fn fill_rest_fresh_args( &self, span: Span, def_id: SolverDefId<'db>, first: impl IntoIterator<Item = GenericArg<'db>>, ) -> GenericArgs<'db>
Like Self::fresh_args_for_item, but first uses the args from first.
Sourcepub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed>
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed>
Returns true if errors have been reported since this infcx was
created. This is sometimes used as a heuristic to skip
reporting errors that often occur as a result of earlier
errors, but where it’s hard to be 100% sure (e.g., unresolved
inference variables, regionck errors).
Sourcepub fn set_tainted_by_errors(&self, e: ErrorGuaranteed)
pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed)
Set the “tainted by errors” flag to true. We call this when we observe an error from a prior pass.
pub fn take_opaque_types( &self, ) -> impl IntoIterator<Item = (OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> + use<'db>
pub fn clone_opaque_types( &self, ) -> Vec<(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)>
pub fn can_define_opaque_ty(&self, id: impl Into<SolverDefId<'db>>) -> bool
Sourcepub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'db>, UniverseIndex>
pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'db>, UniverseIndex>
If TyVar(vid) resolves to a type, return that type. Else, return the
universe index of TyVar(vid).
pub fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db>
pub fn shallow_resolve_const(&self, ct: Const<'db>) -> Const<'db>
pub fn shallow_resolve_term(&self, term: Term<'db>) -> Term<'db>
pub fn root_var(&self, var: TyVid) -> TyVid
pub fn root_const_var(&self, var: ConstVid) -> ConstVid
Sourcepub fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'db>
pub fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'db>
Resolves an int var to a rigid int type, if it was constrained to one, or else the root int var in the unification table.
pub fn resolve_int_var(&self, vid: IntVid) -> Option<Ty<'db>>
Sourcepub fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'db>
pub fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'db>
Resolves a float var to a rigid int type, if it was constrained to one, or else the root float var in the unification table.
pub fn resolve_float_var(&self, vid: FloatVid) -> Option<Ty<'db>>
Sourcepub fn resolve_vars_if_possible<T>(&self, value: T) -> Twhere
T: TypeFoldable<DbInterner<'db>>,
pub fn resolve_vars_if_possible<T>(&self, value: T) -> Twhere
T: TypeFoldable<DbInterner<'db>>,
Where possible, replaces type/const variables in
value with their final value. Note that region variables
are unaffected. If a type/const variable has not been unified, it
is left as is. This is an idempotent operation that does
not affect inference state in any way and so you can do it
at will.
pub fn probe_const_var( &self, vid: ConstVid, ) -> Result<Const<'db>, UniverseIndex>
Sourcepub fn type_var_span(&self, vid: TyVid) -> Span
pub fn type_var_span(&self, vid: TyVid) -> Span
Returns the span of the type variable identified by vid.
No attempt is made to resolve vid to its root variable.
Sourcepub fn const_var_span(&self, vid: ConstVid) -> Option<Span>
pub fn const_var_span(&self, vid: ConstVid) -> Option<Span>
Returns the span of the const variable identified by vid
pub fn instantiate_binder_with_fresh_vars<T>(
&self,
span: Span,
_lbrct: BoundRegionConversionTime<'db>,
value: Binder<'db, T>,
) -> Twhere
T: TypeFoldable<DbInterner<'db>> + Clone,
Sourcepub fn closure_kind(&self, closure_ty: Ty<'db>) -> Option<ClosureKind>
pub fn closure_kind(&self, closure_ty: Ty<'db>) -> Option<ClosureKind>
Obtains the latest type of the given closure; this may be a
closure in the current function, in which case its
ClosureKind may not yet be known.
pub fn universe(&self) -> UniverseIndex
Sourcepub fn create_next_universe(&self) -> UniverseIndex
pub fn create_next_universe(&self) -> UniverseIndex
Creates and return a fresh universe that extends all previous
universes. Updates self.universe to that new universe.
Sourcepub fn is_ty_infer_var_definitely_unchanged<'a>(
&'a self,
) -> impl Fn(TyOrConstInferVar) -> bool + use<'a, 'db>
pub fn is_ty_infer_var_definitely_unchanged<'a>( &'a self, ) -> impl Fn(TyOrConstInferVar) -> bool + use<'a, 'db>
The returned function is used in a fast path. If it returns true the variable is
unchanged, false indicates that the status is unknown.
Sourcepub fn ty_or_const_infer_var_changed(
&self,
infer_var: TyOrConstInferVar,
) -> bool
pub fn ty_or_const_infer_var_changed( &self, infer_var: TyOrConstInferVar, ) -> bool
ty_or_const_infer_var_changed is equivalent to one of these two:
shallow_resolve(ty) != ty(wherety.kind = Infer(_))shallow_resolve(ct) != ct(wherect.kind = ConstKind::Infer(_))
However, ty_or_const_infer_var_changed is more efficient. It’s always
inlined, despite being large, because it has only two call sites that
are extremely hot (both in traits::fulfill’s checking of stalled_on
inference variables), and it handles both Ty and Const without
having to resort to storing full GenericArgs in stalled_on.
fn sub_unification_table_root_var(&self, var: TyVid) -> TyVid
fn sub_unify_ty_vids_raw(&self, a: TyVid, b: TyVid)
Sourcepub fn attach_obligation_inspector(&self, inspector: ObligationInspector<'db>)
pub fn attach_obligation_inspector(&self, inspector: ObligationInspector<'db>)
Attach a callback to be invoked on each root obligation evaluated in the new trait solver.
pub fn inspect_evaluated_obligation( &self, obligation: &Obligation<'db, Predicate<'db>>, result: &Result<GoalEvaluation<DbInterner<'db>>, NoSolution>, get_proof_tree: impl FnOnce() -> Option<GoalEvaluation<DbInterner<'db>>>, )
Source§impl<'db> InferCtxt<'db>
impl<'db> InferCtxt<'db>
pub(crate) fn visit_proof_tree<V: ProofTreeVisitor<'db>>( &self, goal: Goal<'db, Predicate<'db>>, visitor: &mut V, ) -> V::Result
pub(crate) fn visit_proof_tree_at_depth<V: ProofTreeVisitor<'db>>( &self, goal: Goal<'db, Predicate<'db>>, depth: usize, visitor: &mut V, ) -> V::Result
Trait Implementations§
Source§impl<'a, 'db> From<&'a InferCtxt<'db>> for &'a SolverContext<'db>
impl<'a, 'db> From<&'a InferCtxt<'db>> for &'a SolverContext<'db>
Source§impl<'db> InferCtxtLike for InferCtxt<'db>
impl<'db> InferCtxtLike for InferCtxt<'db>
type Interner = DbInterner<'db>
type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries
fn cx(&self) -> DbInterner<'db>
Source§fn next_trait_solver(&self) -> bool
fn next_trait_solver(&self) -> bool
fn disable_trait_solver_fast_paths(&self) -> bool
fn typing_mode_raw(&self) -> TypingMode<DbInterner<'db>>
fn universe(&self) -> UniverseIndex
fn create_next_universe(&self) -> UniverseIndex
fn universe_of_ty(&self, vid: TyVid) -> Option<UniverseIndex>
fn universe_of_lt(&self, lt: RegionVid) -> Option<UniverseIndex>
fn universe_of_ct(&self, ct: ConstVid) -> Option<UniverseIndex>
fn root_ty_var(&self, var: TyVid) -> TyVid
fn root_const_var(&self, var: ConstVid) -> ConstVid
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'db>
fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'db>
fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'db>
fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> Const<'db>
fn opportunistic_resolve_lt_var(&self, vid: RegionVid) -> Region<'db>
fn is_changed_arg(&self, arg: <Self::Interner as Interner>::GenericArg) -> bool
fn next_ty_infer(&self) -> Ty<'db>
fn next_region_infer(&self) -> <Self::Interner as Interner>::Region
fn next_const_infer(&self) -> Const<'db>
fn fresh_args_for_item(&self, def_id: SolverDefId<'db>) -> GenericArgs<'db>
fn instantiate_binder_with_infer<T: TypeFoldable<DbInterner<'db>> + Clone>( &self, value: Binder<'db, T>, ) -> T
fn enter_forall<T: TypeFoldable<DbInterner<'db>> + Clone, U>( &self, value: Binder<'db, T>, f: impl FnOnce(T) -> U, ) -> U
fn equate_ty_vids_raw(&self, a: TyVid, b: TyVid)
fn equate_int_vids_raw(&self, a: IntVid, b: IntVid)
fn equate_float_vids_raw(&self, a: FloatVid, b: FloatVid)
fn equate_const_vids_raw(&self, a: ConstVid, b: ConstVid)
fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>( &self, relation: &mut R, target_is_expected: bool, target_vid: TyVid, instantiation_variance: Variance, source_ty: Ty<'db>, ) -> RelateResult<'db, ()>
fn instantiate_int_var_raw(&self, vid: IntVid, value: IntVarValue)
fn instantiate_float_var_raw(&self, vid: FloatVid, value: FloatVarValue)
fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>( &self, relation: &mut R, target_is_expected: bool, target_vid: ConstVid, source_ct: Const<'db>, ) -> RelateResult<'db, ()>
fn set_tainted_by_errors(&self, e: ErrorGuaranteed)
fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db>
fn shallow_resolve_const(&self, ct: Const<'db>) -> Const<'db>
fn resolve_vars_if_possible<T>(&self, value: T) -> Twhere
T: TypeFoldable<DbInterner<'db>>,
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T
fn sub_regions( &self, sub: Region<'db>, sup: Region<'db>, _vis: VisibleForLeakCheck, _span: Span, )
fn equate_regions( &self, a: Region<'db>, b: Region<'db>, _vis: VisibleForLeakCheck, _span: Span, )
fn register_ty_outlives(&self, _ty: Ty<'db>, _r: Region<'db>, _span: Span)
fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries
fn clone_opaque_types_lookup_table(&self) -> Vec<(OpaqueTypeKey<'db>, Ty<'db>)>
fn clone_duplicate_opaque_types(&self) -> Vec<(OpaqueTypeKey<'db>, Ty<'db>)>
fn clone_opaque_types_added_since( &self, prev_entries: OpaqueTypeStorageEntries, ) -> Vec<(OpaqueTypeKey<'db>, Ty<'db>)>
fn add_duplicate_opaque_type( &self, opaque_type_key: OpaqueTypeKey<'db>, hidden_ty: Ty<'db>, _span: Span, )
fn reset_opaque_types(&self)
fn sub_unification_table_root_var(&self, var: TyVid) -> TyVid
fn sub_unify_ty_vids_raw(&self, a: TyVid, b: TyVid)
Source§impl<'db> PredicateEmittingRelation<InferCtxt<'db>> for LatticeOp<'_, 'db>
impl<'db> PredicateEmittingRelation<InferCtxt<'db>> for LatticeOp<'_, 'db>
fn span(&self) -> Span
Source§fn structurally_relate_aliases(&self) -> StructurallyRelateAliases
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases
No unless you’re equating in some specific locations of the
new solver. See the comments in these use-cases for more details.fn param_env(&self) -> ParamEnv<'db>
Source§fn register_predicates(
&mut self,
preds: impl IntoIterator<Item: Upcast<DbInterner<'db>, Predicate<'db>>>,
)
fn register_predicates( &mut self, preds: impl IntoIterator<Item: Upcast<DbInterner<'db>, Predicate<'db>>>, )
param_env of the obligation.Source§fn register_goals(
&mut self,
goals: impl IntoIterator<Item = Goal<'db, Predicate<'db>>>,
)
fn register_goals( &mut self, goals: impl IntoIterator<Item = Goal<'db, Predicate<'db>>>, )
Source§fn register_alias_relate_predicate(&mut self, a: Ty<'db>, b: Ty<'db>)
fn register_alias_relate_predicate(&mut self, a: Ty<'db>, b: Ty<'db>)
AliasRelate obligation(s) that both types must be related to each other.Auto Trait Implementations§
impl<'db> !Freeze for InferCtxt<'db>
impl<'db> !RefUnwindSafe for InferCtxt<'db>
impl<'db> Send for InferCtxt<'db>
impl<'db> !Sync for InferCtxt<'db>
impl<'db> Unpin for InferCtxt<'db>
impl<'db> UnsafeUnpin for InferCtxt<'db>
impl<'db> !UnwindSafe for InferCtxt<'db>
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§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