pub struct TypeErrCtxt<'a, 'tcx> {
    pub infcx: &'a InferCtxt<'tcx>,
    pub sub_relations: RefCell<SubRelations>,
    pub typeck_results: Option<Ref<'a, TypeckResults<'tcx>>>,
    pub fallback_has_occurred: bool,
    pub normalize_fn_sig: Box<dyn Fn(PolyFnSig<'tcx>) -> PolyFnSig<'tcx> + 'a>,
    pub autoderef_steps: Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>,
}
Expand description

A helper for building type related errors. The typeck_results field is only populated during an in-progress typeck. Get an instance by calling InferCtxt::err_ctxt or FnCtxt::err_ctxt.

You must only create this if you intend to actually emit an error (or perhaps a warning, though preferably not.) It provides a lot of utility methods which should not be used during the happy path.

Fields§

§infcx: &'a InferCtxt<'tcx>§sub_relations: RefCell<SubRelations>§typeck_results: Option<Ref<'a, TypeckResults<'tcx>>>§fallback_has_occurred: bool§normalize_fn_sig: Box<dyn Fn(PolyFnSig<'tcx>) -> PolyFnSig<'tcx> + 'a>§autoderef_steps: Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>

Implementations§

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub(super) fn note_region_origin( &self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx> )

source

pub(super) fn report_concrete_failure( &self, origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx> ) -> Diag<'tcx>

source

pub fn suggest_copy_trait_method_bounds( &self, trait_item_def_id: DefId, impl_item_def_id: LocalDefId, err: &mut Diag<'_> )

source

pub(super) fn report_placeholder_failure( &self, placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx> ) -> Diag<'tcx>

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub fn note_and_explain_type_err( &self, diag: &mut Diag<'_>, err: TypeError<'tcx>, cause: &ObligationCause<'tcx>, sp: Span, body_owner_def_id: DefId )

source

fn suggest_constraint( &self, diag: &mut Diag<'_>, msg: impl Fn() -> String, body_owner_def_id: DefId, proj_ty: &AliasTy<'tcx>, ty: Ty<'tcx> ) -> bool

source

fn expected_projection( &self, diag: &mut Diag<'_>, proj_ty: &AliasTy<'tcx>, values: ExpectedFound<Ty<'tcx>>, body_owner_def_id: DefId, cause_code: &ObligationCauseCode<'_> )

An associated type was expected and a different type was found.

We perform a few different checks to see what we can suggest:

  • In the current item, look for associated functions that return the expected type and suggest calling them. (Not a structured suggestion.)
  • If any of the item’s generic bounds can be constrained, we suggest constraining the associated type to the found type.
  • If the associated type has a default type and was expected inside of a trait, we mention that this is disallowed.
  • If all other things fail, and the error is not because of a mismatch between the trait and the impl, we provide a generic help to constrain the assoc type or call an assoc fn that returns the type.
source

fn suggest_constraining_opaque_associated_type( &self, diag: &mut Diag<'_>, msg: impl Fn() -> String, proj_ty: &AliasTy<'tcx>, ty: Ty<'tcx> ) -> bool

When the expected impl Trait is not defined in the current item, it will come from a return type. This can occur when dealing with TryStream (#71035).

source

fn point_at_methods_that_satisfy_associated_type( &self, diag: &mut Diag<'_>, assoc_container_id: DefId, current_method_ident: Option<Symbol>, proj_ty_item_def_id: DefId, expected: Ty<'tcx> ) -> bool

source

fn point_at_associated_type( &self, diag: &mut Diag<'_>, body_owner_def_id: DefId, found: Ty<'tcx> ) -> bool

source

fn constrain_generic_bound_associated_type_structured_suggestion( &self, diag: &mut Diag<'_>, trait_ref: &TraitRef<'tcx>, bounds: GenericBounds<'_>, assoc: AssocItem, assoc_args: &[GenericArg<'tcx>], ty: Ty<'tcx>, msg: impl Fn() -> String, is_bound_surely_present: bool ) -> bool

Given a slice of hir::GenericBounds, if any of them corresponds to the trait_ref requirement, provide a structured suggestion to constrain it to a given type ty.

is_bound_surely_present indicates whether we know the bound we’re looking for is inside bounds. If that’s the case then we can consider bounds containing only one trait bound as the one we’re looking for. This can help in cases where the associated type is defined on a supertrait of the one present in the bounds.

source

fn constrain_associated_type_structured_suggestion( &self, diag: &mut Diag<'_>, span: Span, assoc: AssocItem, assoc_args: &[GenericArg<'tcx>], ty: Ty<'tcx>, msg: impl Fn() -> String ) -> bool

Given a span corresponding to a bound, provide a structured suggestion to set an associated type to a given type ty.

source

pub fn format_generic_args(&self, args: &[GenericArg<'tcx>]) -> String

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub(super) fn suggest_remove_semi_or_return_binding( &self, first_id: Option<HirId>, first_ty: Ty<'tcx>, first_span: Span, second_id: Option<HirId>, second_ty: Ty<'tcx>, second_span: Span ) -> Option<SuggestRemoveSemiOrReturnBinding>

source

pub(super) fn suggest_boxing_for_return_impl_trait( &self, err: &mut Diag<'_>, return_sp: Span, arm_spans: impl Iterator<Item = Span> )

source

pub(super) fn suggest_tuple_pattern( &self, cause: &ObligationCause<'tcx>, exp_found: &ExpectedFound<Ty<'tcx>>, diag: &mut Diag<'_> )

source

pub(super) fn suggest_await_on_expect_found( &self, cause: &ObligationCause<'tcx>, exp_span: Span, exp_found: &ExpectedFound<Ty<'tcx>>, diag: &mut Diag<'_> )

A possible error is to forget to add .await when using futures:

async fn make_u32() -> u32 {
    22
}

fn take_u32(x: u32) {}

async fn foo() {
    let x = make_u32();
    take_u32(x);
}

This routine checks if the found type T implements Future<Output=U> where U is the expected type. If this is the case, and we are inside of an async body, it suggests adding .await to the tail of the expression.

source

pub(super) fn suggest_accessing_field_where_appropriate( &self, cause: &ObligationCause<'tcx>, exp_found: &ExpectedFound<Ty<'tcx>>, diag: &mut Diag<'_> )

source

pub(super) fn suggest_turning_stmt_into_expr( &self, cause: &ObligationCause<'tcx>, exp_found: &ExpectedFound<Ty<'tcx>>, diag: &mut Diag<'_> )

source

pub fn consider_removing_semicolon( &self, blk: &'tcx Block<'tcx>, expected_ty: Ty<'tcx>, diag: &mut Diag<'_> ) -> bool

A common error is to add an extra semicolon:

fn foo() -> usize {
    22;
}

This routine checks if the final statement in a block is an expression with an explicit semicolon whose type is compatible with expected_ty. If so, it suggests removing the semicolon.

source

pub(super) fn suggest_function_pointers( &self, cause: &ObligationCause<'tcx>, span: Span, exp_found: &ExpectedFound<Ty<'tcx>>, diag: &mut Diag<'_> )

source

pub fn should_suggest_as_ref_kind( &self, expected: Ty<'tcx>, found: Ty<'tcx> ) -> Option<SuggestAsRefKind>

source

pub fn should_suggest_as_ref( &self, expected: Ty<'tcx>, found: Ty<'tcx> ) -> Option<&str>

source

pub(super) fn suggest_let_for_letchains( &self, cause: &ObligationCause<'_>, span: Span ) -> Option<TypeErrorAdditionalDiags>

Try to find code with pattern if Some(..) = expr use a visitor to mark the if which its span contains given error span, and then try to find a assignment in the cond part, which span is equal with error span

source

pub(super) fn suggest_for_all_lifetime_closure( &self, span: Span, hir: Node<'_>, exp_found: &ExpectedFound<PolyTraitRef<'tcx>>, diag: &mut Diag<'_> )

For “one type is more general than the other” errors on closures, suggest changing the lifetime of the parameters to accept all lifetimes.

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub fn could_remove_semicolon( &self, blk: &'tcx Block<'tcx>, expected_ty: Ty<'tcx> ) -> Option<(Span, StatementAsExpression)>

Be helpful when the user wrote {... expr; } and taking the ; off is enough to fix the error.

source

pub fn consider_returning_binding_diag( &self, blk: &'tcx Block<'tcx>, expected_ty: Ty<'tcx> ) -> Option<SuggestRemoveSemiOrReturnBinding>

Suggest returning a local binding with a compatible type if the block has no return expression.

source

pub fn consider_returning_binding( &self, blk: &'tcx Block<'tcx>, expected_ty: Ty<'tcx>, err: &mut Diag<'_> ) -> bool

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub fn emit_inference_failure_err( &self, body_def_id: LocalDefId, failure_span: Span, arg: GenericArg<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool ) -> Diag<'tcx>

source§

impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx>

source§

impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx>

source

pub fn dcx(&self) -> &'tcx DiagCtxt

source

pub fn err_ctxt(&self) -> !

👎Deprecated: you already have a TypeErrCtxt

This is just to avoid a potential footgun of accidentally dropping typeck_results by calling InferCtxt::err_ctxt

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub fn report_region_errors( &self, generic_param_scope: LocalDefId, errors: &[RegionResolutionError<'tcx>] ) -> ErrorGuaranteed

source

fn process_errors( &self, errors: &[RegionResolutionError<'tcx>] ) -> Vec<RegionResolutionError<'tcx>>

source

fn check_and_note_conflicting_crates( &self, err: &mut Diag<'_>, terr: TypeError<'tcx> )

Adds a note if the types come from similarly named crates

source

fn note_error_origin( &self, err: &mut Diag<'_>, cause: &ObligationCause<'tcx>, exp_found: Option<ExpectedFound<Ty<'tcx>>>, terr: TypeError<'tcx> )

source

fn highlight_outer( &self, value: &mut DiagStyledString, other_value: &mut DiagStyledString, name: String, sub: GenericArgsRef<'tcx>, pos: usize, other_ty: Ty<'tcx> )

Given that other_ty is the same as a type argument for name in sub, populate value highlighting name and every type argument that isn’t at pos (which is other_ty), and populate other_value with other_ty.

Foo<Bar<Qux>>
^^^^--------^ this is highlighted
|   |
|   this type argument is exactly the same as the other type, not highlighted
this is highlighted
Bar<Qux>
-------- this type is the same as a type argument in the other type, not highlighted
source

fn cmp_type_arg( &self, t1_out: &mut DiagStyledString, t2_out: &mut DiagStyledString, path: String, sub: &'tcx [GenericArg<'tcx>], other_path: String, other_ty: Ty<'tcx> ) -> Option<()>

If other_ty is the same as a type argument present in sub, highlight path in t1_out, as that is the difference to the other type.

For the following code:

let x: Foo<Bar<Qux>> = foo::<Bar<Qux>>();

The type error output will behave in the following way:

Foo<Bar<Qux>>
^^^^--------^ this is highlighted
|   |
|   this type argument is exactly the same as the other type, not highlighted
this is highlighted
Bar<Qux>
-------- this type is the same as a type argument in the other type, not highlighted
source

fn push_comma( &self, value: &mut DiagStyledString, other_value: &mut DiagStyledString, len: usize, pos: usize )

Adds a , to the type representation only if it is appropriate.

source

fn cmp_fn_sig( &self, sig1: &PolyFnSig<'tcx>, sig2: &PolyFnSig<'tcx> ) -> (DiagStyledString, DiagStyledString)

Given two fn signatures highlight only sub-parts that are different.

source

pub fn cmp( &self, t1: Ty<'tcx>, t2: Ty<'tcx> ) -> (DiagStyledString, DiagStyledString)

Compares two given types, eliding parts that are the same between them and highlighting relevant differences, and return two representation of those types for highlighted printing.

source

pub fn note_type_err( &self, diag: &mut Diag<'_>, cause: &ObligationCause<'tcx>, secondary_span: Option<(Span, Cow<'static, str>)>, values: Option<ValuePairs<'tcx>>, terr: TypeError<'tcx>, swap_secondary_and_primary: bool, prefer_label: bool )

Extend a type error with extra labels pointing at “non-trivial” types, like closures and the return type of async fns.

secondary_span gives the caller the opportunity to expand diag with a span_label.

swap_secondary_and_primary is used to make projection errors in particular nicer by using the message in secondary_span as the primary label, and apply the message that would otherwise be used for the primary label on the secondary_span Span. This applies on E0271, like tests/ui/issues/issue-39970.stderr.

source

pub fn type_error_additional_suggestions( &self, trace: &TypeTrace<'tcx>, terr: TypeError<'tcx> ) -> Vec<TypeErrorAdditionalDiags>

source

fn suggest_specify_actual_length( &self, terr: TypeError<'_>, trace: &TypeTrace<'_>, span: Span ) -> Option<TypeErrorAdditionalDiags>

source

pub fn report_and_explain_type_error( &self, trace: TypeTrace<'tcx>, terr: TypeError<'tcx> ) -> Diag<'tcx>

source

fn suggest_wrap_to_build_a_tuple( &self, span: Span, found: Ty<'tcx>, expected_fields: &List<Ty<'tcx>> ) -> Option<TypeErrorAdditionalDiags>

source

fn values_str( &self, values: ValuePairs<'tcx> ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)>

source

fn expected_found_str_term( &self, exp_found: ExpectedFound<Term<'tcx>> ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)>

source

fn expected_found_str<T: Display + TypeFoldable<TyCtxt<'tcx>>>( &self, exp_found: ExpectedFound<T> ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)>

Returns a string of the form “expected {}, found {}”.

source

pub fn report_generic_bound_failure( &self, generic_param_scope: LocalDefId, span: Span, origin: Option<SubregionOrigin<'tcx>>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx> ) -> ErrorGuaranteed

source

pub fn construct_generic_bound_failure( &self, generic_param_scope: LocalDefId, span: Span, origin: Option<SubregionOrigin<'tcx>>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx> ) -> Diag<'tcx>

source

pub fn suggest_name_region( &self, lifetime: Region<'tcx>, add_lt_suggs: &mut Vec<(Span, String)> ) -> String

source

fn report_sub_sup_conflict( &self, var_origin: RegionVariableOrigin, sub_origin: SubregionOrigin<'tcx>, sub_region: Region<'tcx>, sup_origin: SubregionOrigin<'tcx>, sup_region: Region<'tcx> ) -> ErrorGuaranteed

source

pub fn is_try_conversion(&self, span: Span, trait_def_id: DefId) -> bool

Determine whether an error associated with the given span and definition should be treated as being caused by the implicit From conversion within ? desugaring.

source

pub fn same_type_modulo_infer<T: Relate<'tcx>>(&self, a: T, b: T) -> bool

Structurally compares two types, modulo any inference variables.

Returns true if two types are equal, or if one type is an inference variable compatible with the other type. A TyVar inference type is compatible with any type, and an IntVar or FloatVar inference type are compatible with themselves or their concrete types (Int and Float types, respectively). When comparing two ADTs, these rules apply recursively.

source§

impl<'tcx> TypeErrCtxt<'_, 'tcx>

source

pub fn type_error_struct_with_diag<M>( &self, sp: Span, mk_diag: M, actual_ty: Ty<'tcx> ) -> Diag<'tcx>
where M: FnOnce(String) -> Diag<'tcx>,

source

pub fn report_mismatched_types( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx> ) -> Diag<'tcx>

source

pub fn report_mismatched_consts( &self, cause: &ObligationCause<'tcx>, expected: Const<'tcx>, actual: Const<'tcx>, err: TypeError<'tcx> ) -> Diag<'tcx>

Methods from Deref<Target = InferCtxt<'tcx>>§

source

pub fn at<'a>( &'a self, cause: &'a ObligationCause<'tcx>, param_env: ParamEnv<'tcx> ) -> At<'a, 'tcx>

source

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.

source

pub fn fork_with_intercrate(&self, intercrate: bool) -> 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

pub fn canonicalize_query<V>( &self, value: ParamEnvAnd<'tcx, V>, query_state: &mut OriginalQueryValues<'tcx> ) -> Canonical<'tcx, ParamEnvAnd<'tcx, V>>
where V: TypeFoldable<TyCtxt<'tcx>>,

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.

source

pub fn canonicalize_response<V>(&self, value: V) -> Canonical<'tcx, V>
where V: TypeFoldable<TyCtxt<'tcx>>,

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.

source

pub fn canonicalize_user_type_annotation<V>( &self, value: V ) -> Canonical<'tcx, V>
where V: TypeFoldable<TyCtxt<'tcx>>,

source

pub fn make_canonicalized_query_response<T>( &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, fulfill_cx: &mut dyn TraitEngine<'tcx> ) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
where T: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,

This method is meant to be invoked as the final step of a canonical query implementation. It is given:

  • the instantiated variables inference_vars created from the query key
  • the result answer of the query
  • a fulfillment context fulfill_cx that may contain various obligations which have yet to be proven.

Given this, the function will process the obligations pending in fulfill_cx:

  • If all the obligations can be proven successfully, it will package up any resulting region obligations (extracted from infcx) along with the fully resolved value answer into a query result (which is then itself canonicalized).
  • If some obligations can be neither proven nor disproven, then the same thing happens, but the resulting query is marked as ambiguous.
  • Finally, if any of the obligations result in a hard error, then Err(NoSolution) is returned.
source

pub fn make_query_response_ignoring_pending_obligations<T>( &self, inference_vars: CanonicalVarValues<'tcx>, answer: T ) -> Canonical<'tcx, QueryResponse<'tcx, T>>
where T: Debug + TypeFoldable<TyCtxt<'tcx>>,

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.

source

fn make_query_response<T>( &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, fulfill_cx: &mut dyn TraitEngine<'tcx> ) -> Result<QueryResponse<'tcx, T>, NoSolution>
where T: Debug + TypeFoldable<TyCtxt<'tcx>>,

Helper for make_canonicalized_query_response that does everything up until the final canonicalization.

source

pub fn clone_opaque_types_for_query_response( &self ) -> Vec<(OpaqueTypeKey<'tcx>, Ty<'tcx>)>

Used by the new solver as that one takes the opaque types at the end of a probe to deal with multiple candidates without having to recompute them.

source

fn take_opaque_types_for_query_response( &self ) -> Vec<(OpaqueTypeKey<'tcx>, Ty<'tcx>)>

source

pub fn instantiate_query_response_and_region_obligations<R>( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>> ) -> InferResult<'tcx, R>
where R: Debug + TypeFoldable<TyCtxt<'tcx>>,

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.

source

pub fn instantiate_nll_query_response_and_region_obligations<R>( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, output_query_region_constraints: &mut QueryRegionConstraints<'tcx> ) -> InferResult<'tcx, R>
where R: Debug + TypeFoldable<TyCtxt<'tcx>>,

An alternative to instantiate_query_response_and_region_obligations that is more efficient for NLL. NLL is a bit more advanced in the “transition to chalk” than the rest of the compiler. During the NLL type check, all of the “processing” of types and things happens in queries – the NLL checker itself is only interested in the region obligations ('a: 'b or T: 'b) that come out of these queries, which it wants to convert into MIR-based constraints and solve. Therefore, it is most convenient for the NLL Type Checker to directly consume the QueryOutlivesConstraint values that arise from doing a query. This is contrast to other parts of the compiler, which would prefer for those QueryOutlivesConstraint to be converted into the older infcx-style constraints (e.g., calls to sub_regions or register_region_obligation).

Therefore, instantiate_nll_query_response_and_region_obligations performs the same basic operations as instantiate_query_response_and_region_obligations but it returns its result differently:

  • It creates an instantiation S that maps from the original query variables to the values computed in the query result. If any errors arise, they are propagated back as an Err result.
  • In the case of a successful instantiation, we will append QueryOutlivesConstraint values onto the output_query_region_constraints vector for the solver to use (if an error arises, some values may also be pushed, but they should be ignored).
  • It can happen (though it rarely does currently) that equating types and things will give rise to subobligations that must be processed. In this case, those subobligations are propagated back in the return value.
  • Finally, the query result (of type R) is propagated back, after applying the instantiation S.
source

fn query_response_instantiation<R>( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>> ) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
where R: Debug + TypeFoldable<TyCtxt<'tcx>>,

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.

source

fn query_response_instantiation_guess<R>( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>> ) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
where R: Debug + TypeFoldable<TyCtxt<'tcx>>,

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

source

fn unify_query_response_instantiation_guess<R>( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, result_args: &CanonicalVarValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>> ) -> InferResult<'tcx, ()>
where R: Debug + TypeFoldable<TyCtxt<'tcx>>,

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

source

fn query_outlives_constraints_into_obligations<'a>( &'a self, cause: &'a ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, uninstantiated_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], result_args: &'a CanonicalVarValues<'tcx> ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx>

Converts the region constraints resulting from a query into an iterator of obligations.

source

pub fn query_outlives_constraint_to_obligation( &self, (predicate, _): QueryOutlivesConstraint<'tcx>, cause: ObligationCause<'tcx>, param_env: ParamEnv<'tcx> ) -> Obligation<'tcx, Predicate<'tcx>>

source

fn unify_canonical_vars( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, variables1: &OriginalQueryValues<'tcx>, variables2: impl Fn(BoundVar) -> GenericArg<'tcx> ) -> InferResult<'tcx, ()>

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

pub fn instantiate_canonical_with_fresh_inference_vars<T>( &self, span: Span, canonical: &Canonical<'tcx, T> ) -> (T, CanonicalVarValues<'tcx>)
where T: TypeFoldable<TyCtxt<'tcx>>,

Creates an instantiation S for the canonical value with fresh inference variables and 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.

source

fn instantiate_canonical_vars( &self, span: Span, variables: &List<CanonicalVarInfo<'tcx>>, universe_map: impl Fn(UniverseIndex) -> UniverseIndex ) -> CanonicalVarValues<'tcx>

Given the “infos” about the canonical variables from some canonical, creates fresh variables with the same characteristics (see instantiate_canonical_var for details). You can then use instantiate to instantiate the canonical variable with these inference variables.

source

pub fn instantiate_canonical_var( &self, span: Span, cv_info: CanonicalVarInfo<'tcx>, universe_map: impl Fn(UniverseIndex) -> UniverseIndex ) -> GenericArg<'tcx>

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

pub fn extract_inference_diagnostics_data( &self, arg: GenericArg<'tcx>, highlight: Option<RegionHighlightMode<'tcx>> ) -> InferenceDiagnosticsData

Extracts data used by diagnostic for either types or constants which were stuck during inference.

source

fn bad_inference_failure_err( &self, span: Span, arg_data: InferenceDiagnosticsData, error_code: TypeAnnotationNeeded ) -> Diag<'tcx>

Used as a fallback in TypeErrCtxt::emit_inference_failure_err in case we weren’t able to get a better error.

source

pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>>

source

fn report_inference_failure( &self, var_origin: RegionVariableOrigin ) -> Diag<'tcx>

source

pub fn find_block_span(&self, block: &'tcx Block<'tcx>) -> Span

Given a hir::Block, get the span of its last expression or statement, peeling off any inner blocks.

source

pub fn find_block_span_from_hir_id(&self, hir_id: HirId) -> Span

Given a hir::HirId for a block, get the span of its last expression or statement, peeling off any inner blocks.

source

pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<TyCtxt<'tcx>>>( &self, value: T, body_id: LocalDefId, span: Span, param_env: ParamEnv<'tcx> ) -> InferOk<'tcx, T>

This is a backwards compatibility hack to prevent breaking changes from lazy TAIT around RPIT handling.

source

pub fn handle_opaque_type( &self, a: Ty<'tcx>, b: Ty<'tcx>, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx> ) -> InferResult<'tcx, ()>

source

pub fn register_member_constraints( &self, opaque_type_key: OpaqueTypeKey<'tcx>, concrete_ty: Ty<'tcx>, span: Span )

Given the map opaque_types containing the opaque impl Trait types whose underlying, hidden types are being inferred, this method adds constraints to the regions appearing in those underlying hidden types to ensure that they at least do not refer to random scopes within the current function. These constraints are not (quite) sufficient to guarantee that the regions are actually legal values; that final condition is imposed after region inference is done.

§The Problem

Let’s work through an example to explain how it works. Assume the current function is as follows:

fn foo<'a, 'b>(..) -> (impl Bar<'a>, impl Bar<'b>)

Here, we have two impl Trait types whose values are being inferred (the impl Bar<'a> and the impl Bar<'b>). Conceptually, this is sugar for a setup where we define underlying opaque types (Foo1, Foo2) and then, in the return type of foo, we reference those definitions:

type Foo1<'x> = impl Bar<'x>;
type Foo2<'x> = impl Bar<'x>;
fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
                   //  ^^^^ ^^
                   //  |    |
                   //  |    args
                   //  def_id

As indicating in the comments above, each of those references is (in the compiler) basically generic paramters (args) applied to the type of a suitable def_id (which identifies Foo1 or Foo2).

Now, at this point in compilation, what we have done is to replace each of the references (Foo1<'a>, Foo2<'b>) with fresh inference variables C1 and C2. We wish to use the values of these variables to infer the underlying types of Foo1 and Foo2. That is, this gives rise to higher-order (pattern) unification constraints like:

for<'a> (Foo1<'a> = C1)
for<'b> (Foo1<'b> = C2)

For these equation to be satisfiable, the types C1 and C2 can only refer to a limited set of regions. For example, C1 can only refer to 'static and 'a, and C2 can only refer to 'static and 'b. The job of this function is to impose that constraint.

Up to this point, C1 and C2 are basically just random type inference variables, and hence they may contain arbitrary regions. In fact, it is fairly likely that they do! Consider this possible definition of foo:

fn foo<'a, 'b>(x: &'a i32, y: &'b i32) -> (impl Bar<'a>, impl Bar<'b>) {
        (&*x, &*y)
    }

Here, the values for the concrete types of the two impl traits will include inference variables:

&'0 i32
&'1 i32

Ordinarily, the subtyping rules would ensure that these are sufficiently large. But since impl Bar<'a> isn’t a specific type per se, we don’t get such constraints by default. This is where this function comes into play. It adds extra constraints to ensure that all the regions which appear in the inferred type are regions that could validly appear.

This is actually a bit of a tricky constraint in general. We want to say that each variable (e.g., '0) can only take on values that were supplied as arguments to the opaque type (e.g., 'a for Foo1<'a>) or 'static, which is always in scope. We don’t have a constraint quite of this kind in the current region checker.

§The Solution

We generally prefer to make <= constraints, since they integrate best into the region solver. To do that, we find the “minimum” of all the arguments that appear in the args: that is, some region which is less than all the others. In the case of Foo1<'a>, that would be 'a (it’s the only choice, after all). Then we apply that as a least bound to the variables (e.g., 'a <= '0).

In some cases, there is no minimum. Consider this example:

fn baz<'a, 'b>() -> impl Trait<'a, 'b> { ... }

Here we would report a more complex “in constraint”, like 'r in ['a, 'b, 'static] (where 'r is some region appearing in the hidden type).

§Constrain regions, not the hidden concrete type

Note that generating constraints on each region Rc is not the same as generating an outlives constraint on Tc itself. For example, if we had a function like this:

fn foo<'a, T>(x: &'a u32, y: T) -> impl Foo<'a> {
  (x, y)
}

// Equivalent to:
type FooReturn<'a, T> = impl Foo<'a>;
fn foo<'a, T>(x: &'a u32, y: T) -> FooReturn<'a, T> {
  (x, y)
}

then the hidden type Tc would be (&'0 u32, T) (where '0 is an inference variable). If we generated a constraint that Tc: 'a, then this would incorrectly require that T: 'a – but this is not necessary, because the opaque type we create will be allowed to reference T. So we only generate a constraint that '0: 'a.

source

pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin>

Returns the origin of the opaque type def_id if we’re currently in its defining scope.

source

fn register_hidden_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, cause: ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, hidden_ty: Ty<'tcx> ) -> InferResult<'tcx, ()>

source

pub fn insert_hidden_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, obligations: &mut Vec<PredicateObligation<'tcx>> ) -> Result<(), TypeError<'tcx>>

Insert a hidden type into the opaque type storage, equating it with any previous entries if necessary.

This does not add the item bounds of the opaque as nested obligations. That is only necessary when normalizing the opaque itself, not when getting the opaque type constraints from somewhere else.

source

pub fn add_item_bounds_for_hidden_type( &self, def_id: DefId, args: GenericArgsRef<'tcx>, cause: ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, obligations: &mut Vec<PredicateObligation<'tcx>> )

source

pub fn register_region_obligation(&self, obligation: RegionObligation<'tcx>)

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).

source

pub fn register_region_obligation_with_cause( &self, sup_type: Ty<'tcx>, sub_region: Region<'tcx>, cause: &ObligationCause<'tcx> )

source

pub fn take_registered_region_obligations(&self) -> Vec<RegionObligation<'tcx>>

Trait queries just want to pass back type obligations “as is”

source

pub fn process_registered_region_obligations( &self, outlives_env: &OutlivesEnvironment<'tcx>, deeply_normalize_ty: impl FnMut(PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>) -> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution> ) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)>

Process the region obligations that must be proven (during regionck) for the given body_id, given information about the region bounds in scope and so forth.

See the region_obligations field of InferCtxt for some comments about how this function fits into the overall expected flow of the inferencer. The key point is that it is invoked after all type-inference variables have been bound – right before lexical region resolution.

source

pub fn resolve_regions_with_normalize( &self, outlives_env: &OutlivesEnvironment<'tcx>, deeply_normalize_ty: impl Fn(PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>) -> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution> ) -> Vec<RegionResolutionError<'tcx>>

Process the region constraints and return any errors that result. After this, no more unification operations should be done – or the compiler will panic – but it is legal to use resolve_vars_if_possible as well as fully_resolve.

If you are in a crate that has access to rustc_trait_selection, then it’s probably better to use resolve_regions, which knows how to normalize registered region obligations.

source

pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx>

Obtains (and clears) the current set of region constraints. The inference context is still usable: further unifications will simply add new constraints.

This method is not meant to be used with normal lexical region resolution. Rather, it is used in the NLL mode as a kind of interim hack: basically we run normal type-check and generate region constraints as normal, but then we take them and translate them into the form that the NLL solver understands. See the NLL module for mode details.

source

pub fn with_region_constraints<R>( &self, op: impl FnOnce(&RegionConstraintData<'tcx>) -> R ) -> R

Gives temporary access to the region constraint data.

source

pub fn infer_projection( &self, param_env: ParamEnv<'tcx>, projection_ty: AliasTy<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, obligations: &mut Vec<PredicateObligation<'tcx>> ) -> Ty<'tcx>

Instead of normalizing an associated type projection, this function generates an inference variable and registers an obligation that this inference variable must be the result of the given projection. This allows us to proceed with projections while they cannot be resolved yet due to missing information or simply due to the lack of access to the trait resolution machinery.

source

pub fn super_combine_tys<R>( &self, relation: &mut R, a: Ty<'tcx>, b: Ty<'tcx> ) -> RelateResult<'tcx, Ty<'tcx>>

source

pub fn super_combine_consts<R>( &self, relation: &mut R, a: Const<'tcx>, b: Const<'tcx> ) -> RelateResult<'tcx, Const<'tcx>>

source

fn unify_integral_variable( &self, vid_is_expected: bool, vid: IntVid, val: IntVarValue ) -> RelateResult<'tcx, Ty<'tcx>>

source

fn unify_float_variable( &self, vid_is_expected: bool, vid: FloatVid, val: FloatTy ) -> RelateResult<'tcx, Ty<'tcx>>

source

fn unify_effect_variable(&self, vid: EffectVid, val: Const<'tcx>) -> Const<'tcx>

source

pub fn instantiate_ty_var<R: ObligationEmittingRelation<'tcx>>( &self, relation: &mut R, target_is_expected: bool, target_vid: TyVid, instantiation_variance: Variance, source_ty: Ty<'tcx> ) -> RelateResult<'tcx, ()>

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).

source

pub(super) fn instantiate_const_var<R: ObligationEmittingRelation<'tcx>>( &self, relation: &mut R, target_is_expected: bool, target_vid: ConstVid, source_ct: Const<'tcx> ) -> RelateResult<'tcx, ()>

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.

source

fn generalize<T: Into<Term<'tcx>> + Relate<'tcx>>( &self, span: Span, structurally_relate_aliases: StructurallyRelateAliases, target_vid: impl Into<TermVid>, ambient_variance: Variance, source_term: T ) -> RelateResult<'tcx, 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

pub fn enter_forall_and_leak_universe<T>(&self, binder: Binder<'tcx, T>) -> T
where T: TypeFoldable<TyCtxt<'tcx>> + Copy,

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.

source

pub fn enter_forall<T, U>( &self, forall: Binder<'tcx, T>, f: impl FnOnce(T) -> U ) -> U
where T: TypeFoldable<TyCtxt<'tcx>> + Copy,

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

pub fn leak_check( &self, outer_universe: UniverseIndex, only_consider_snapshot: Option<&CombinedSnapshot<'tcx>> ) -> RelateResult<'tcx, ()>

See RegionConstraintCollector::leak_check. We only check placeholder leaking into outer_universe, i.e. placeholders which cannot be named by that universe.

source

fn variable_lengths(&self) -> VariableLengths

source

pub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
where F: FnOnce() -> Result<T, E>, T: TypeFoldable<TyCtxt<'tcx>>,

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.

source

pub fn in_snapshot(&self) -> bool

source

pub fn num_open_snapshots(&self) -> usize

source

fn start_snapshot(&self) -> CombinedSnapshot<'tcx>

source

fn rollback_to(&self, snapshot: CombinedSnapshot<'tcx>)

source

fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>)

source

pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
where F: FnOnce(&CombinedSnapshot<'tcx>) -> Result<T, E>,

Execute f and commit the bindings if closure f returns Ok(_).

source

pub fn probe<R, F>(&self, f: F) -> R
where F: FnOnce(&CombinedSnapshot<'tcx>) -> R,

Execute f then unroll any bindings it creates.

source

pub fn region_constraints_added_in_snapshot( &self, snapshot: &CombinedSnapshot<'tcx> ) -> bool

Scan the constraints produced since snapshot and check whether we added any region constraints.

source

pub fn opaque_types_added_in_snapshot( &self, snapshot: &CombinedSnapshot<'tcx> ) -> bool

source

pub fn dcx(&self) -> &'tcx DiagCtxt

source

pub fn next_trait_solver(&self) -> bool

source

pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx>

Creates a TypeErrCtxt for emitting various inference errors. During typeck, use FnCtxt::err_ctxt instead.

source

pub fn freshen<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T

source

pub fn type_var_origin(&self, ty: Ty<'tcx>) -> Option<TypeVariableOrigin>

Returns the origin of the type variable identified by vid, or None if this is not a type variable.

No attempt is made to resolve ty.

source

pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx>

source

pub fn unresolved_variables(&self) -> Vec<Ty<'tcx>>

source

pub fn unsolved_effects(&self) -> Vec<Const<'tcx>>

source

fn combine_fields<'a>( &'a self, trace: TypeTrace<'tcx>, param_env: ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes ) -> CombineFields<'a, 'tcx>

source

pub fn can_sub<T>( &self, param_env: ParamEnv<'tcx>, expected: T, actual: T ) -> bool
where T: ToTrace<'tcx>,

source

pub fn can_eq<T>(&self, param_env: ParamEnv<'tcx>, a: T, b: T) -> bool
where T: ToTrace<'tcx>,

source

pub fn sub_regions( &self, origin: SubregionOrigin<'tcx>, a: Region<'tcx>, b: Region<'tcx> )

source

pub fn member_constraint( &self, key: OpaqueTypeKey<'tcx>, definition_span: Span, hidden_ty: Ty<'tcx>, region: Region<'tcx>, in_regions: &Lrc<Vec<Region<'tcx>>> )

Require that the region r be equal to one of the regions in the set regions.

source

pub fn coerce_predicate( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, predicate: PolyCoercePredicate<'tcx> ) -> Result<InferResult<'tcx, ()>, (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.)

source

pub fn subtype_predicate( &self, cause: &ObligationCause<'tcx>, param_env: ParamEnv<'tcx>, predicate: PolySubtypePredicate<'tcx> ) -> Result<InferResult<'tcx, ()>, (TyVid, TyVid)>

source

pub fn region_outlives_predicate( &self, cause: &ObligationCause<'tcx>, predicate: PolyRegionOutlivesPredicate<'tcx> )

source

pub fn num_ty_vars(&self) -> usize

Number of type variables created so far.

source

pub fn next_ty_var_id(&self, origin: TypeVariableOrigin) -> TyVid

source

pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx>

source

pub fn next_ty_var_id_in_universe( &self, origin: TypeVariableOrigin, universe: UniverseIndex ) -> TyVid

source

pub fn next_ty_var_in_universe( &self, origin: TypeVariableOrigin, universe: UniverseIndex ) -> Ty<'tcx>

source

pub fn next_const_var( &self, ty: Ty<'tcx>, origin: ConstVariableOrigin ) -> Const<'tcx>

source

pub fn next_const_var_in_universe( &self, ty: Ty<'tcx>, origin: ConstVariableOrigin, universe: UniverseIndex ) -> Const<'tcx>

source

pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid

source

fn next_int_var_id(&self) -> IntVid

source

pub fn next_int_var(&self) -> Ty<'tcx>

source

fn next_float_var_id(&self) -> FloatVid

source

pub fn next_float_var(&self) -> Ty<'tcx>

source

pub fn next_region_var(&self, origin: RegionVariableOrigin) -> Region<'tcx>

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.

source

pub fn next_region_var_in_universe( &self, origin: RegionVariableOrigin, universe: UniverseIndex ) -> Region<'tcx>

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.

source

pub fn universe_of_region(&self, r: Region<'tcx>) -> 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.

source

pub fn num_region_vars(&self) -> usize

Number of region variables created so far.

source

pub fn next_nll_region_var( &self, origin: NllRegionVariableOrigin ) -> Region<'tcx>

Just a convenient wrapper of next_region_var for using during NLL.

source

pub fn next_nll_region_var_in_universe( &self, origin: NllRegionVariableOrigin, universe: UniverseIndex ) -> Region<'tcx>

Just a convenient wrapper of next_region_var for using during NLL.

source

pub fn var_for_def( &self, span: Span, param: &GenericParamDef ) -> GenericArg<'tcx>

source

pub fn var_for_effect(&self, param: &GenericParamDef) -> GenericArg<'tcx>

source

pub fn fresh_args_for_item( &self, span: Span, def_id: DefId ) -> GenericArgsRef<'tcx>

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.

source

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).

source

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.

source

pub fn region_var_origin(&self, vid: RegionVid) -> RegionVariableOrigin

source

pub fn get_region_var_origins(&self) -> VarInfos

Clone the list of variable regions. This is used only during NLL processing to put the set of region variables into the NLL region context.

source

pub fn take_opaque_types(&self) -> OpaqueTypeMap<'tcx>

source

pub fn clone_opaque_types(&self) -> OpaqueTypeMap<'tcx>

source

pub fn ty_to_string(&self, t: Ty<'tcx>) -> String

source

pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, UniverseIndex>

If TyVar(vid) resolves to a type, return that type. Else, return the universe index of TyVar(vid).

source

pub fn shallow_resolve<T>(&self, value: T) -> T
where T: TypeFoldable<TyCtxt<'tcx>>,

Resolve any type variables found in value – but only one level. So, if the variable ?X is bound to some type Foo<?Y>, then this would return Foo<?Y> (but ?Y may itself be bound to a type).

Useful when you only need to inspect the outermost level of the type and don’t care about nested types (or perhaps you will be resolving them as well, e.g. in a loop).

source

pub fn root_var(&self, var: TyVid) -> TyVid

source

pub fn root_const_var(&self, var: ConstVid) -> ConstVid

source

pub fn root_effect_var(&self, var: EffectVid) -> EffectVid

source

pub fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'tcx>

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.

source

pub fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'tcx>

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.

source

pub fn resolve_vars_if_possible<T>(&self, value: T) -> T
where T: TypeFoldable<TyCtxt<'tcx>>,

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.

source

pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T
where T: TypeFoldable<TyCtxt<'tcx>>,

source

pub fn probe_const_var( &self, vid: ConstVid ) -> Result<Const<'tcx>, UniverseIndex>

source

pub fn probe_effect_var(&self, vid: EffectVid) -> Option<Const<'tcx>>

source

pub fn fully_resolve<T: TypeFoldable<TyCtxt<'tcx>>>( &self, value: T ) -> FixupResult<T>

Attempts to resolve all type/region/const variables in value. Region inference must have been run already (e.g., by calling resolve_regions_and_report_errors). If some variable was never unified, an Err results.

This method is idempotent, but it not typically not invoked except during the writeback phase.

source

pub fn instantiate_binder_with_fresh_vars<T>( &self, span: Span, lbrct: BoundRegionConversionTime, value: Binder<'tcx, T> ) -> T
where T: TypeFoldable<TyCtxt<'tcx>> + Copy,

source

pub fn verify_generic_bound( &self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, a: Region<'tcx>, bound: VerifyBound<'tcx> )

source

pub fn closure_kind(&self, closure_ty: Ty<'tcx>) -> 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.

source

pub fn clear_caches(&self)

Clears the selection, evaluation, and projection caches. This is useful when repeatedly attempting to select an Obligation while changing only its ParamEnv, since FulfillmentContext doesn’t use probing.

source

pub fn universe(&self) -> UniverseIndex

source

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.

source

pub fn try_const_eval_resolve( &self, param_env: ParamEnv<'tcx>, unevaluated: UnevaluatedConst<'tcx>, ty: Ty<'tcx>, span: Option<Span> ) -> Result<Const<'tcx>, ErrorHandled>

source

pub fn const_eval_resolve( &self, param_env: ParamEnv<'tcx>, unevaluated: UnevaluatedConst<'tcx>, span: Option<Span> ) -> EvalToValTreeResult<'tcx>

Resolves and evaluates a constant.

The constant can be located on a trait like <A as B>::C, in which case the given generic parameters and environment are used to resolve the constant. Alternatively if the constant has generic parameters in scope the instantiations are used to evaluate the value of the constant. For example in fn foo<T>() { let _ = [0; bar::<T>()]; } the repeat count constant bar::<T>() requires a instantiation for T, if the instantiation for T is still too generic for the constant to be evaluated then Err(ErrorHandled::TooGeneric) is returned.

This handles inferences variables within both param_env and args by performing the operation on their respective canonical forms.

source

pub fn is_ty_infer_var_definitely_unchanged<'a>( &'a self ) -> impl Fn(TyOrConstInferVar) -> bool + Captures<'tcx> + 'a

The returned function is used in a fast path. If it returns true the variable is unchanged, false indicates that the status is unknown.

source

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 (where ty.kind = ty::Infer(_))
  • shallow_resolve(ct) != ct (where ct.kind = ty::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 ty::Const without having to resort to storing full GenericArgs in stalled_on.

source

pub fn attach_obligation_inspector(&self, inspector: ObligationInspector<'tcx>)

Attach a callback to be invoked on each root obligation evaluated in the new trait solver.

source

pub fn report_extra_impl_obligation( &self, error_span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId, requirement: &dyn Display ) -> Diag<'tcx>

Trait Implementations§

source§

impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx>

§

type Target = InferCtxt<'tcx>

The resulting type after dereferencing.
source§

fn deref(&self) -> &InferCtxt<'tcx>

Dereferences the value.

Auto Trait Implementations§

§

impl<'a, 'tcx> !Freeze for TypeErrCtxt<'a, 'tcx>

§

impl<'a, 'tcx> !RefUnwindSafe for TypeErrCtxt<'a, 'tcx>

§

impl<'a, 'tcx> !Send for TypeErrCtxt<'a, 'tcx>

§

impl<'a, 'tcx> !Sync for TypeErrCtxt<'a, 'tcx>

§

impl<'a, 'tcx> Unpin for TypeErrCtxt<'a, 'tcx>

§

impl<'a, 'tcx> !UnwindSafe for TypeErrCtxt<'a, 'tcx>

Blanket Implementations§

source§

impl<T> Aligned for T

source§

const ALIGN: Alignment = _

Alignment of Self.
source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T, R> CollectAndApply<T, R> for T

source§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

§

type Output = R

§

impl<T> Filterable for T

§

fn filterable( self, filter_name: &'static str ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<P> IntoQueryParam<P> for P

source§

impl<T> MaybeResult<T> for T

§

type Error = !

source§

fn from(_: Result<T, <T as MaybeResult<T>>::Error>) -> T

source§

fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<'tcx, T> ToPredicate<'tcx, T> for T

source§

fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> T

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed ) -> T

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

§

impl<T> ErasedDestructor for T
where 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: 128 bytes