Skip to main content

InferenceContext

Struct InferenceContext 

Source
pub(crate) struct InferenceContext<'db> {
Show 30 fields pub(crate) db: &'db dyn HirDatabase, pub(crate) owner: InferBodyId<'db>, pub(crate) store_owner: ExpressionStoreOwnerId, pub(crate) generic_def: GenericDefId, pub(crate) store: &'db ExpressionStore, pub(crate) lowering_mode: LoweringMode, pub(crate) resolver: Resolver<'db>, target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>, pub(crate) edition: Edition, allow_using_generic_params: bool, generics: OnceCell<Generics<'db>>, identity_args: OnceCell<GenericArgs<'db>>, pub(crate) table: InferenceTable<'db>, pub(crate) lang_items: &'db LangItems, pub(crate) features: &'db UnstableFeatures, traits_in_scope: FxHashSet<TraitId>, pub(crate) result: InferenceResult<'db>, tuple_field_accesses_rev: IndexSet<Tys<'db>, BuildHasherDefault<FxHasher>>, return_ty: Ty<'db>, return_coercion: Option<CoerceMany<'db, 'db>>, resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>, diverges: Diverges, breakables: Vec<BreakableContext<'db>>, types: &'db DefaultAny<'db>, inside_assignment: bool, deferred_cast_checks: Vec<CastCheck<'db>>, deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>, diagnostics: Diagnostics, vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>, defined_anon_consts: RefCell<ThinVec<AnonConstId<'db>>>,
}
Expand description

The inference context contains all information needed during type inference.

Fields§

§db: &'db dyn HirDatabase§owner: InferBodyId<'db>§store_owner: ExpressionStoreOwnerId§generic_def: GenericDefId§store: &'db ExpressionStore§lowering_mode: LoweringMode§resolver: Resolver<'db>

Generally you should not resolve things via this resolver. Instead create a TyLoweringContext and resolve the path via its methods. This will ensure proper error reporting.

§target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>§edition: Edition§allow_using_generic_params: bool§generics: OnceCell<Generics<'db>>§identity_args: OnceCell<GenericArgs<'db>>§table: InferenceTable<'db>§lang_items: &'db LangItems§features: &'db UnstableFeatures§traits_in_scope: FxHashSet<TraitId>

The traits in scope, disregarding block modules. This is used for caching purposes.

§result: InferenceResult<'db>§tuple_field_accesses_rev: IndexSet<Tys<'db>, BuildHasherDefault<FxHasher>>§return_ty: Ty<'db>

The return type of the function being inferred, the closure or async block if we’re currently within one.

We might consider using a nested inference context for checking closures so we can swap all shared things out at once.

§return_coercion: Option<CoerceMany<'db, 'db>>

If Some, this stores coercion information for returned expressions. If None, this is in a context where return is inappropriate, such as a const expression.

§resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>

The resume type and the yield type, respectively, of the coroutine being inferred.

§diverges: Diverges§breakables: Vec<BreakableContext<'db>>§types: &'db DefaultAny<'db>§inside_assignment: bool

Whether we are inside the pattern of a destructuring assignment.

§deferred_cast_checks: Vec<CastCheck<'db>>§deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>

The key is an expression defining a closure or a coroutine closure.

§diagnostics: Diagnostics§vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>§defined_anon_consts: RefCell<ThinVec<AnonConstId<'db>>>

Implementations§

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn infer_call( &mut self, call_expr: ExprId, callee_expr: ExprId, arg_exprs: &[ExprId], expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn try_overloaded_call_step( call_expr: ExprId, callee_expr: ExprId, arg_exprs: &[ExprId], autoderef: &mut GeneralAutoderef<'db, InferenceContextAutoderefCtx<'_, 'db>, Vec<(Ty<'db>, AutoderefKind)>>, error_reported: &mut bool, ) -> Option<CallStep<'db>>

Source

fn try_overloaded_call_traits( &mut self, call_expr: ExprId, adjusted_ty: Ty<'db>, opt_arg_exprs: Option<&[ExprId]>, ) -> Option<(Option<Adjustment>, MethodCallee<'db>)>

Source

fn check_legacy_const_generics( &mut self, callee: Option<CallableDefId>, callee_ty: Ty<'db>, args: &[ExprId], ) -> Box<[u32]>

Returns the argument indices to skip.

Source

fn confirm_builtin_call( &mut self, callee_expr: ExprId, call_expr: ExprId, callee_ty: Ty<'db>, arg_exprs: &[ExprId], expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn confirm_deferred_closure_call( &mut self, call_expr: ExprId, arg_exprs: &[ExprId], expected: &Expectation<'db>, fn_sig: FnSig<'db>, ) -> Ty<'db>

Source

fn confirm_overloaded_call( &mut self, call_expr: ExprId, arg_exprs: &[ExprId], expected: &Expectation<'db>, method: MethodCallee<'db>, ) -> Ty<'db>

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn closure_analyze(&mut self)

Source

fn analyze_closures_in_expr( &mut self, expr: ExprId, upvars: &'db FxHashMap<ExprId, Upvars>, )

Source

fn analyze_closure( &mut self, closure_expr_id: ExprId, params: &[PatId], body: ExprId, capture_clause: CaptureBy, closure_kind: ClosureKind, upvars: UpvarsRef<'db>, )

Analysis starting point.

Source

fn coroutine_body_consumes_upvars( &mut self, coroutine_def_id: ExprId, body: ExprId, upvars: UpvarsRef<'db>, ) -> bool

Determines whether the body of the coroutine uses its upvars in a way that consumes (i.e. moves) the value, which would force the coroutine to FnOnce. In a more detailed comment above, we care whether this happens, since if this happens, we want to force the coroutine to move all of the upvars it would’ve borrowed from the parent coroutine-closure.

This only really makes sense to be called on the child coroutine of a coroutine-closure.

Source

fn final_upvar_tys(&self, closure_id: ExprId) -> Vec<Ty<'db>>

Source

fn process_collected_capture_information( &mut self, capture_clause: CaptureBy, capture_information: &Vec<(Place, CaptureInfo)>, ) -> (Vec<(Place, CaptureInfo)>, ClosureKind, Option<Place>)

Adjusts the closure capture information to ensure that the operations aren’t unsafe, and that the path can be captured with required capture kind (depending on use in closure, move closure etc.)

Returns the set of adjusted information along with the inferred closure kind and span associated with the closure kind inference.

Note that we always infer a minimal kind, even if we don’t always use that in the final result (i.e., sometimes we’ve taken the closure kind from the expectations instead, and for coroutines we don’t even implement the closure traits really).

If we inferred that the closure needs to be FnMut/FnOnce, last element of the returned tuple contains a Some() with the Place that caused us to do so.

Source

fn compute_min_captures( &mut self, closure_def_id: ExprId, capture_information: Vec<(Place, CaptureInfo)>, )

Analyzes the information collected by InferBorrowKind to compute the min number of Places (and corresponding capture kind) that we need to keep track of to support all the required captured paths.

Note: If this function is called multiple times for the same closure, it will update the existing min_capture map that is stored in TypeckResults.

Eg:

#[derive(Debug)]
struct Point { x: i32, y: i32 }

let s = String::from("s");  // hir_id_s
let mut p = Point { x: 2, y: -2 }; // his_id_p
let c = || {
       println!("{s:?}");  // L1
       p.x += 10;  // L2
       println!("{}" , p.y); // L3
       println!("{p:?}"); // L4
       drop(s);   // L5
};

and let hir_id_L1..5 be the expressions pointing to use of a captured variable on the lines L1..5 respectively.

InferBorrowKind results in a structure like this:

{
      Place(base: hir_id_s, projections: [], ....) -> {
                                                           capture_kind_expr: hir_id_L5,
                                                           path_expr_id: hir_id_L5,
                                                           capture_kind: ByValue
                                                      },
      Place(base: hir_id_p, projections: [Field(0, 0)], ...) -> {
                                                                    capture_kind_expr: hir_id_L2,
                                                                    path_expr_id: hir_id_L2,
                                                                    capture_kind: ByValue
                                                                },
      Place(base: hir_id_p, projections: [Field(1, 0)], ...) -> {
                                                                    capture_kind_expr: hir_id_L3,
                                                                    path_expr_id: hir_id_L3,
                                                                    capture_kind: ByValue
                                                                },
      Place(base: hir_id_p, projections: [], ...) -> {
                                                         capture_kind_expr: hir_id_L4,
                                                         path_expr_id: hir_id_L4,
                                                         capture_kind: ByValue
                                                     },
}

After the min capture analysis, we get:

{
      hir_id_s -> [
           Place(base: hir_id_s, projections: [], ....) -> {
                                                               capture_kind_expr: hir_id_L5,
                                                               path_expr_id: hir_id_L5,
                                                               capture_kind: ByValue
                                                           },
      ],
      hir_id_p -> [
           Place(base: hir_id_p, projections: [], ...) -> {
                                                              capture_kind_expr: hir_id_L2,
                                                              path_expr_id: hir_id_L4,
                                                              capture_kind: ByValue
                                                          },
      ],
}
Source

fn normalize_capture_place(&mut self, span: Span, place: Place) -> Place

Source

fn closure_min_captures_flattened( &self, closure_expr_id: ExprId, ) -> impl Iterator<Item = &CapturedPlace>

Source

fn init_capture_kind_for_place( &self, place: &Place, capture_clause: CaptureBy, ) -> UpvarCapture

Source

fn place_for_root_variable( &mut self, closure_def_id: ExprId, var_hir_id: BindingId, ) -> Place

Source

fn determine_capture_mutability( &mut self, closure_expr: ExprId, place: &Place, ) -> Mutability

A captured place is mutable if

  1. Projections don’t include a Deref of an immut-borrow, and
  2. PlaceBase is mut or projections include a Deref of a mut-borrow.
Source§

impl<'db> InferenceContext<'db>

Source

fn poll_option_ty(&mut self, item_ty: Ty<'db>) -> Ty<'db>

Source

pub(super) fn infer_closure( &mut self, body: ExprId, args: &[PatId], ret_type: Option<TypeRefId>, arg_types: &[Option<TypeRefId>], closure_kind: ClosureKind, closure_expr: ExprId, expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn fn_trait_kind_from_def_id(&self, trait_id: TraitId) -> Option<ClosureKind>

Source

fn async_fn_trait_kind_from_def_id( &self, trait_id: TraitId, ) -> Option<ClosureKind>

Source

fn deduce_closure_signature( &mut self, closure_expr: ExprId, expected_ty: Ty<'db>, closure_kind: ClosureKind, ) -> (Option<PolyFnSig<'db>>, Option<ClosureKind>)

Given the expected type, figures out what it can about this closure we are about to type check:

Source

fn deduce_closure_signature_from_predicates( &mut self, closure_expr: ExprId, expected_ty: Ty<'db>, closure_kind: ClosureKind, predicates: impl DoubleEndedIterator<Item = Predicate<'db>>, ) -> (Option<PolyFnSig<'db>>, Option<ClosureKind>)

Source

fn deduce_sig_from_projection( &mut self, closure_expr: ExprId, closure_kind: ClosureKind, projection: PolyProjectionPredicate<'db>, ) -> Option<PolyFnSig<'db>>

Given a projection like “<F as Fn(X)>::Result == Y”, we can deduce everything we need to know about a closure or coroutine.

The cause_span should be the span that caused us to have this expected signature, or None if we can’t readily know that.

Source

fn extract_sig_from_projection( &self, projection: PolyProjectionPredicate<'db>, ) -> Option<PolyFnSig<'db>>

Given an FnOnce::Output or AsyncFn::Output projection, extract the args and return type to infer a PolyFnSig for the closure.

Source

fn extract_sig_from_projection_and_future_bound( &mut self, closure_expr: ExprId, projection: PolyProjectionPredicate<'db>, ) -> Option<PolyFnSig<'db>>

When an async closure is passed to a function that has a “two-part” Fn and Future trait bound, like:

use std::future::Future;

fn not_exactly_an_async_closure<F, Fut>(_f: F)
where
    F: FnOnce(String, u32) -> Fut,
    Fut: Future<Output = i32>,
{}

The we want to be able to extract the signature to guide inference in the async closure. We will have two projection predicates registered in this case. First, we identify the FnOnce<Args, Output = ?Fut> bound, and if the output type is an inference variable ?Fut, we check if that is bounded by a Future<Output = Ty> projection.

This function is actually best-effort with the return type; if we don’t find a Future projection, we still will return arguments that we extracted from the FnOnce projection, and the output will be an unconstrained type variable instead.

Source

fn sig_of_closure( &mut self, closure_expr: ExprId, decl_inputs: &[PatId], decl_input_tys: &[Option<TypeRefId>], decl_output_ty: Option<TypeRefId>, expected_sig: Option<PolyFnSig<'db>>, closure_kind: ClosureKind, ) -> ClosureSignatures<'db>

Source

fn sig_of_closure_no_expectation( &mut self, closure_expr: ExprId, decl_inputs: &[Option<TypeRefId>], decl_output: Option<TypeRefId>, closure_kind: ClosureKind, ) -> ClosureSignatures<'db>

If there is no expected signature, then we will convert the types that the user gave into a signature.

Source

fn sig_of_closure_with_expectation( &mut self, closure_expr: ExprId, decl_inputs: &[PatId], decl_input_tys: &[Option<TypeRefId>], decl_output_ty: Option<TypeRefId>, expected_sig: PolyFnSig<'db>, closure_kind: ClosureKind, ) -> ClosureSignatures<'db>

Invoked to compute the signature of a closure expression. This combines any user-provided type annotations (e.g., |x: u32| -> u32 { .. }) with the expected signature.

The approach is as follows:

  • Let S be the (higher-ranked) signature that we derive from the user’s annotations.
  • Let E be the (higher-ranked) signature that we derive from the expectations, if any.
    • If we have no expectation E, then the signature of the closure is S.
    • Otherwise, the signature of the closure is E. Moreover:
      • Skolemize the late-bound regions in E, yielding E'.
      • Instantiate all the late-bound regions bound in the closure within S with fresh (existential) variables, yielding S'
      • Require that E' = S'
        • We could use some kind of subtyping relationship here, I imagine, but equality is easier and works fine for our purposes.

The key intuition here is that the user’s types must be valid from “the inside” of the closure, but the expectation ultimately drives the overall signature.

§Examples
fn with_closure<F>(_: F)
  where F: Fn(&u32) -> &u32 { .. }

with_closure(|x: &u32| { ... })

Here:

  • E would be fn(&u32) -> &u32.
  • S would be fn(&u32) -> ?T
  • E’ is &'!0 u32 -> &'!0 u32
  • S’ is &'?0 u32 -> ?T

S’ can be unified with E’ with ['?0 = '!0, ?T = &'!10 u32].

§Arguments
  • expr_def_id: the LocalDefId of the closure expression
  • decl: the HIR declaration of the closure
  • body: the body of the closure
  • expected_sig: the expected signature (if any). Note that this is missing a binder: that is, there may be late-bound regions with depth 1, which are bound then by the closure.
Source

fn sig_of_closure_with_mismatched_number_of_arguments( &mut self, decl_inputs: &[Option<TypeRefId>], decl_output: Option<TypeRefId>, ) -> ClosureSignatures<'db>

Source

fn merge_supplied_sig_with_expectation( &mut self, closure_expr: ExprId, decl_inputs: &[PatId], decl_input_tys: &[Option<TypeRefId>], decl_output_ty: Option<TypeRefId>, expected_sigs: ClosureSignatures<'db>, closure_kind: ClosureKind, ) -> InferResult<'db, ClosureSignatures<'db>>

Enforce the user’s types against the expectation. See sig_of_closure_with_expectation for details on the overall strategy.

Source

fn supplied_sig_of_closure( &mut self, closure_expr: ExprId, decl_inputs: &[Option<TypeRefId>], decl_output: Option<TypeRefId>, closure_kind: ClosureKind, ) -> PolyFnSig<'db>

If there is no expected signature, then we will convert the types that the user gave into a signature.

Also, record this closure signature for later.

Source

fn deduce_future_output_from_obligations( &mut self, body_def_id: ExprId, ) -> Option<Ty<'db>>

Invoked when we are translating the coroutine that results from desugaring an async fn. Returns the “sugared” return type of the async fn – that is, the return type that the user specified. The “desugared” return type is an impl Future<Output = T>, so we do this by searching through the obligations to extract the T.

Source

fn deduce_future_output_from_projection( &self, predicate: PolyProjectionPredicate<'db>, ) -> Option<Ty<'db>>

Given a projection like

<X as Future>::Output = T

where X is some type that has no late-bound regions, returns Some(T). If the projection is for some other trait, returns None.

Source

fn error_sig_of_closure( &mut self, decl_inputs: &[Option<TypeRefId>], decl_output: Option<TypeRefId>, ) -> PolyFnSig<'db>

Converts the types that the user supplied, in case that doing so should yield an error, but returns back a signature where all parameters are of type ty::Error.

Source

fn closure_sigs(&self, bound_sig: PolyFnSig<'db>) -> ClosureSignatures<'db>

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn coerce( &mut self, expr: ExprId, expr_ty: Ty<'db>, target: Ty<'db>, allow_two_phase: AllowTwoPhase, expr_is_read: ExprIsRead, ) -> RelateResult<'db, Ty<'db>>

Attempt to coerce an expression to a type, and return the adjusted type of the expression, if successful. Adjustments are only recorded if the coercion succeeded. The expressions must not have any preexisting adjustments.

Source

fn try_find_coercion_lub( &mut self, exprs: &[ExprId], prev_ty: Ty<'db>, new: ExprId, new_ty: Ty<'db>, ) -> RelateResult<'db, Ty<'db>>

Given some expressions, their known unified type and another expression, tries to unify the types, potentially inserting coercions on any of the provided expressions and returns their LUB (aka “common supertype”).

This is really an internal helper. From outside the coercion module, you should instantiate a CoerceMany instance.

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn infer_expr( &mut self, tgt_expr: ExprId, expected: &Expectation<'db>, is_read: ExprIsRead, ) -> Ty<'db>

Source

pub(crate) fn infer_expr_suptype_coerce_never( &mut self, expr: ExprId, expected: &Expectation<'db>, is_read: ExprIsRead, ) -> Ty<'db>

Source

pub(crate) fn infer_expr_no_expect( &mut self, tgt_expr: ExprId, is_read: ExprIsRead, ) -> Ty<'db>

Source

pub(super) fn infer_expr_coerce( &mut self, expr: ExprId, expected: &Expectation<'db>, is_read: ExprIsRead, ) -> Ty<'db>

Infer type of expression with possibly implicit coerce to the expected type. Return the type after possible coercion.

Source

pub(super) fn expr_guaranteed_to_constitute_read_for_never( &mut self, expr: ExprId, is_read: ExprIsRead, ) -> bool

Whether this expression constitutes a read of value of the type that it evaluates to.

This is used to determine if we should consider the block to diverge if the expression evaluates to !, and if we should insert a NeverToAny coercion for values of type !.

This function generally returns false if the expression is a place expression and the parent expression is the scrutinee of a match or the pointee of an & addr-of expression, since both of those parent expressions take a place and not a value.

Source

fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool

Whether this pattern constitutes a read of value of the scrutinee that it is matching against. This is used to determine whether we should perform NeverToAny coercions.

Source

fn contains_explicit_ref_binding(&self, pat: PatId) -> bool

Checks if the pattern contains any ref or ref mut bindings, and if yes whether it contains mutable or just immutables ones.

Source

fn is_syntactic_place_expr(&self, expr: ExprId) -> bool

Source

pub(crate) fn check_lhs_assignable(&self, lhs: ExprId)

Source

fn infer_expr_coerce_never( &mut self, expr: ExprId, expected: &Expectation<'db>, is_read: ExprIsRead, ) -> Ty<'db>

Source

pub(super) fn infer_expr_inner( &mut self, tgt_expr: ExprId, expected: &Expectation<'db>, is_read: ExprIsRead, ) -> Ty<'db>

Source

fn infer_ref_expr( &mut self, rawness: Rawness, mutbl: Mutability, oprnd: ExprId, expected: &Expectation<'db>, expr: ExprId, ) -> Ty<'db>

Source

fn infer_await_expr(&mut self, expr: ExprId, awaitee: ExprId) -> Ty<'db>

Source

fn infer_record_expr( &mut self, expr: ExprId, expected: &Expectation<'db>, path: &Path, fields: &[RecordLitField], base_expr: RecordSpread, ) -> Ty<'db>

Source

fn check_record_expr_fields( &mut self, adt_ty: Ty<'db>, expected: &Expectation<'db>, expr: ExprId, variant: VariantId, hir_fields: &[RecordLitField], base_expr: RecordSpread, )

Source

fn demand_scrutinee_type( &mut self, scrut: ExprId, contains_ref_bindings: bool, no_arms: bool, scrutinee_is_read: ExprIsRead, ) -> Ty<'db>

Source

fn infer_expr_path( &mut self, path: &Path, id: ExprOrPatIdPacked, scope_id: ExprId, ) -> Ty<'db>

Source

fn infer_unop_expr( &mut self, unop: UnaryOp, oprnd: ExprId, expected: &Expectation<'db>, expr: ExprId, ) -> Ty<'db>

Source

fn infer_array_repeat_expr( &mut self, element: ExprId, count: ExprId, expected: &Expectation<'db>, expr: ExprId, ) -> Ty<'db>

Source

fn infer_array_elements_expr( &mut self, args: &[ExprId], expected: &Expectation<'db>, expr: ExprId, ) -> Ty<'db>

Source

pub(super) fn infer_return(&mut self, expr: ExprId)

Source

fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty<'db>

Source

fn infer_expr_become(&mut self, tgt_expr: ExprId, expr: ExprId) -> Ty<'db>

Source

fn infer_expr_box( &mut self, inner_expr: ExprId, expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn infer_block( &mut self, expr: ExprId, statements: &[Statement], tail: Option<ExprId>, label: Option<LabelId>, expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn lookup_field( &mut self, field_expr: ExprId, receiver_ty: Ty<'db>, name: &Name, ) -> Option<(Ty<'db>, Either<FieldId, TupleFieldId>, Vec<Adjustment>, bool)>

Source

fn infer_field_access( &mut self, tgt_expr: ExprId, receiver: ExprId, name: &Name, expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn instantiate_erroneous_method( &mut self, def_id: FunctionId, ) -> MethodCallee<'db>

Source

fn infer_method_call_as_call( &mut self, tgt_expr: ExprId, args: &[ExprId], callee_ty: Ty<'db>, param_tys: &[Ty<'db>], ret_ty: Ty<'db>, indices_to_skip: &[u32], is_varargs: bool, expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn infer_method_call( &mut self, tgt_expr: ExprId, receiver: ExprId, args: &[ExprId], method_name: &Name, generic_args: Option<&HirGenericArgs>, expected: &Expectation<'db>, ) -> Ty<'db>

Source

fn check_method_call( &mut self, tgt_expr: ExprId, args: &[ExprId], sig: FnSig<'db>, expected: &Expectation<'db>, ) -> Ty<'db>

Source

pub(super) fn check_call_arguments( &mut self, call_expr: ExprId, formal_input_tys: &[Ty<'db>], formal_output: Ty<'db>, expectation: &Expectation<'db>, provided_args: &[ExprId], skip_indices: &[u32], c_variadic: bool, tuple_arguments: TupleArgumentsFlag, )

Generic function that factors out common logic from function calls, method calls and overloaded operators.

Source

pub(super) fn with_breakable_ctx<T>( &mut self, kind: BreakableKind, ty: Option<Ty<'db>>, label: Option<LabelId>, cb: impl FnOnce(&mut Self) -> T, ) -> (BreakableContext<'db>, T)

Source§

impl<'db> InferenceContext<'db>

Source

pub(super) fn type_inference_fallback(&mut self)

Source

fn diverging_fallback_behavior(&self) -> DivergingFallbackBehavior

Source

fn fallback_types(&mut self) -> bool

Source

fn fallback_if_possible( &mut self, ty: Ty<'db>, diverging_fallback: &FxHashMap<Ty<'db>, Ty<'db>>, ) -> bool

Source

fn calculate_diverging_fallback( &self, unresolved_variables: &[Ty<'db>], behavior: DivergingFallbackBehavior, ) -> FxHashMap<Ty<'db>, Ty<'db>>

The “diverging fallback” system is rather complicated. This is a result of our need to balance ‘do the right thing’ with backwards compatibility.

“Diverging” type variables are variables created when we coerce a ! type into an unbound type variable ?X. If they never wind up being constrained, the “right and natural” thing is that ?X should “fallback” to !. This means that e.g. an expression like Some(return) will ultimately wind up with a type like Option<!> (presuming it is not assigned or constrained to have some other type).

However, the fallback used to be () (before the ! type was added). Moreover, there are cases where the ! type ‘leaks out’ from dead code into type variables that affect live code. The most common case is something like this:

match foo() {
    22 => Default::default(), // call this type `?D`
    _ => return, // return has type `!`
} // call the type of this match `?M`

Here, coercing the type ! into ?M will create a diverging type variable ?X where ?X <: ?M. We also have that ?D <: ?M. If ?M winds up unconstrained, then ?X will fallback. If it falls back to !, then all the type variables will wind up equal to ! – this includes the type ?D (since ! doesn’t implement Default, we wind up a “trait not implemented” error in code like this). But since the original fallback was (), this code used to compile with ?D = (). This is somewhat surprising, since Default::default() on its own would give an error because the types are insufficiently constrained.

Our solution to this dilemma is to modify diverging variables so that they can either fallback to ! (the default) or to () (the backwards compatibility case). We decide which fallback to use based on whether there is a coercion pattern like this:

?Diverging -> ?V
?NonDiverging -> ?V
?V != ?NonDiverging

Here ?Diverging represents some diverging type variable and ?NonDiverging represents some non-diverging type variable. ?V can be any type variable (diverging or not), so long as it is not equal to ?NonDiverging.

Intuitively, what we are looking for is a case where a “non-diverging” type variable (like ?M in our example above) is coerced into some variable ?V that would otherwise fallback to !. In that case, we make ?V fallback to !, along with anything that would flow into ?V.

The algorithm we use:

  • Identify all variables that are coerced into by a diverging variable. Do this by iterating over each diverging, unsolved variable and finding all variables reachable from there. Call that set D.
  • Walk over all unsolved, non-diverging variables, and find any variable that has an edge into D.
Source

fn create_coercion_graph(&self) -> Graph<(), ()>

Returns a graph whose nodes are (unresolved) inference variables and where an edge ?A -> ?B indicates that the variable ?A is coerced to ?B.

Source

fn root_vid(&self, ty: Ty<'db>) -> Option<TyVid>

If ty is an unresolved type variable, returns its root vid.

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn infer_mut_body(&mut self, body_expr: ExprId)

Source

fn infer_mut_expr(&mut self, tgt_expr: ExprId, mutability: Mutability)

Source

fn infer_mut_expr_without_adjust( &mut self, tgt_expr: ExprId, mutability: Mutability, )

Source

fn infer_mut_not_expr_iter(&mut self, exprs: impl Iterator<Item = ExprId>)

Source

fn pat_iter_bound_mutability( &self, pat: impl Iterator<Item = PatId>, ) -> Mutability

Source

fn pat_bound_mutability(&self, pat: PatId) -> Mutability

Checks if the pat contains a ref mut binding. Such paths makes the context of bounded expressions mutable. For example in let (ref mut x0, ref x1) = *it; we need to use DerefMut for *it but in let (ref x0, ref x1) = *it; we should use Deref.

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn infer_assign_op_expr( &mut self, expr: ExprId, op: ArithOp, lhs: ExprId, rhs: ExprId, ) -> Ty<'db>

Checks a a <op>= b

Source

pub(crate) fn infer_binop_expr( &mut self, expr: ExprId, op: BinaryOp, lhs_expr: ExprId, rhs_expr: ExprId, ) -> Ty<'db>

Checks a potentially overloaded binary operator.

Source

fn enforce_builtin_binop_types( &mut self, expr: ExprId, lhs_ty: Ty<'db>, rhs_ty: Ty<'db>, category: BinOpCategory, ) -> Ty<'db>

Source

fn infer_overloaded_binop( &mut self, expr: ExprId, lhs_expr: ExprId, rhs_expr: ExprId, op: BinaryOp, ) -> (Ty<'db>, Ty<'db>, Ty<'db>)

Source

pub(crate) fn infer_user_unop( &mut self, ex: ExprId, operand_ty: Ty<'db>, op: UnaryOp, ) -> Ty<'db>

Source

fn lookup_op_method( &mut self, expr: ExprId, lhs_ty: Ty<'db>, opt_rhs: Option<(ExprId, Ty<'db>)>, (op_method, trait_did): (Option<FunctionId>, Option<TraitId>), ) -> Result<MethodCallee<'db>, Vec<NextSolverError<'db>>>

Source

fn lang_item_for_bin_op( &self, op: BinaryOp, ) -> (Option<FunctionId>, Option<TraitId>)

Source

fn lang_item_for_unop( &self, op: UnaryOp, ) -> (Option<FunctionId>, Option<TraitId>)

Source§

impl<'db> InferenceContext<'db>

Source

pub(super) fn handle_opaque_type_uses(&mut self)

This takes all the opaque type uses during HIR typeck. It first computes the concrete hidden type by iterating over all defining uses.

A use during HIR typeck is defining if all non-lifetime arguments are unique generic parameters and the hidden type does not reference any inference variables.

It then uses these defining uses to guide inference for all other uses.

Source§

impl<'db> InferenceContext<'db>

Source

fn compute_definition_site_hidden_types( &mut self, opaque_types: Vec<(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)>, )

Source

fn consider_opaque_type_use( &self, opaque_type_key: OpaqueTypeKey<'db>, hidden_type: OpaqueHiddenType<'db>, ) -> UsageKind<'db>

Source§

impl<'db> InferenceContext<'db>

Source

fn downgrade_mut_inside_shared(&self) -> bool

Experimental pattern feature: after matching against a shared reference, do we limit the default binding mode in subpatterns to be ref when it would otherwise be ref mut? This corresponds to Rule 3 of RFC 3627.

Source

fn ref_pat_matches_inherited_ref( &self, edition: Edition, ) -> InheritedRefMatchRule

Experimental pattern feature: when do reference patterns match against inherited references? This corresponds to variations on Rule 4 of RFC 3627.

Source

fn ref_pat_matches_mut_ref(&self) -> bool

Experimental pattern feature: do & patterns match against &mut references, treating them as if they were shared references? This corresponds to Rule 5 of RFC 3627.

Source

pub(super) fn infer_top_pat( &mut self, pat: PatId, expected: Ty<'db>, pat_origin: PatOrigin, )

Type check the given top level pattern against the expected type.

If a Some(span) is provided and origin_expr holds, then the span represents the scrutinee’s span. The scrutinee is found in e.g. match scrutinee { ... } and let pat = scrutinee;.

Otherwise, Some(span) represents the span of a type expression which originated the expected type.

Source

fn infer_pat(&mut self, pat_id: PatId, expected: Ty<'db>, pat_info: PatInfo)

Type check the given pat against the expected type with the provided binding_mode (default binding mode).

Outside of this module, check_pat_top should always be used. Conversely, inside this module, check_pat_top should never be used.

Source

fn infer_pat_inner( &mut self, pat: PatId, opt_path_res: Option<Result<ResolvedPat<'db>, ()>>, adjust_mode: AdjustMode, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn adjust_pat_info( &self, inner_mutability: Mutability, pat_info: PatInfo, ) -> PatInfo

Source

fn check_deref_pattern( &mut self, pat: PatId, opt_path_res: Option<Result<ResolvedPat<'db>, ()>>, adjust_mode: AdjustMode, expected: Ty<'db>, inner_ty: Ty<'db>, pat_adjust_kind: PatAdjust, pat_info: PatInfo, ) -> Ty<'db>

Source

fn calc_adjust_mode( &mut self, pat_id: PatId, pat: &Pat, opt_path_res: Option<Result<ResolvedPat<'db>, ()>>, ) -> AdjustMode

How should the binding mode and expected type be adjusted?

When the pattern contains a path, opt_path_res must be Some(path_res).

Source

fn should_peel_ref(&self, peel_kind: PeelKind, expected: Ty<'db>) -> bool

Assuming expected is a reference type, determine whether to peel it before matching.

Source

fn should_peel_smart_pointer( &self, peel_kind: PeelKind, expected: Ty<'db>, ) -> bool

Determine whether expected is a smart pointer type that should be peeled before matching.

Source

fn infer_expr_pat_unadjusted(&mut self, expr: ExprId) -> Ty<'db>

Source

fn infer_lit_pat(&mut self, expr: ExprId, expected: Ty<'db>) -> Ty<'db>

Source

fn infer_range_pat( &mut self, pat: PatId, lhs_expr: Option<ExprId>, rhs_expr: Option<ExprId>, expected: Ty<'db>, ) -> Ty<'db>

Source

fn infer_bind_pat( &mut self, pat: PatId, var_id: BindingId, sub: Option<PatId>, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn check_dereferenceable( &mut self, expected: Ty<'db>, pat: PatId, inner: PatId, ) -> Result<(), ()>

Source

fn resolve_record_pat( &mut self, pat: PatId, path: &Path, ) -> Result<ResolvedPat<'db>, ()>

Source

fn infer_record_pat( &mut self, pat: PatId, fields: &[RecordFieldPat], has_rest_pat: bool, pat_ty: Ty<'db>, variant: VariantId, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn resolve_pat_path( &mut self, pat: PatId, path: &Path, ) -> Result<ResolvedPat<'db>, ()>

Source

fn infer_pat_path( &mut self, pat: PatId, resolved: &ResolvedPat<'db>, expected: Ty<'db>, ) -> Ty<'db>

Source

fn resolve_tuple_struct_pat( &mut self, pat: PatId, path: &Path, ) -> Result<ResolvedPat<'db>, ()>

Source

fn infer_tuple_struct_pat( &mut self, pat: PatId, subpats: &[PatId], ddpos: Option<u32>, pat_ty: Ty<'db>, variant: VariantId, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn infer_tuple_pat( &mut self, pat: PatId, elements: &[PatId], ddpos: Option<u32>, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn check_record_pat_fields( &mut self, adt_ty: Ty<'db>, pat: PatId, variant: VariantId, fields: &[RecordFieldPat], has_rest_pat: bool, pat_info: PatInfo, )

Source

fn infer_box_pat( &mut self, pat: PatId, inner: PatId, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn infer_deref_pat( &mut self, pat: PatId, inner: PatId, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn deref_pat_target(&mut self, pat: PatId, source_ty: Ty<'db>) -> Ty<'db>

Source

fn register_deref_mut_bounds_if_needed( &self, pat: PatId, inner: PatId, derefed_tys: impl IntoIterator<Item = Ty<'db>>, ) -> InferOk<'db, ()>

Check if the interior of a deref pattern (either explicit or implicit) has any ref mut bindings, which would require DerefMut to be emitted in MIR building instead of just Deref. We do this after checking the inner pattern, since we want to make sure to account for ref mut binding modes inherited from implicitly dereferencing &mut refs.

Source

pub(super) fn pat_has_ref_mut_binding(&self, pat: PatId) -> bool

Does the pattern recursively contain a ref mut binding in it?

This is used to determined whether a deref pattern should emit a Deref or DerefMut call for its pattern scrutinee.

This is computed from the typeck results since we want to make sure to apply any match-ergonomics adjustments, which we cannot determine from the HIR alone.

Source

fn infer_ref_pat( &mut self, pat: PatId, inner: PatId, pat_mutbl: Mutability, expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Source

fn new_ref_ty(&self, span: Span, mutbl: Mutability, ty: Ty<'db>) -> Ty<'db>

Create a reference or pinned reference type with a fresh region variable.

Source

fn try_resolve_slice_ty_to_array_ty( &self, before: &[PatId], slice: Option<PatId>, pat: PatId, ) -> Option<Ty<'db>>

Source

fn pat_is_irrefutable(&self, pat_origin: PatOrigin) -> bool

Used to determines whether we can infer the expected type in the slice pattern to be of type array. This is only possible if we’re in an irrefutable pattern. If we were to allow this in refutable patterns we wouldn’t e.g. report ambiguity in the following situation:

struct Zeroes;
   const ARR: [usize; 2] = [0; 2];
   const ARR2: [usize; 2] = [2; 2];

   impl Into<&'static [usize; 2]> for Zeroes {
       fn into(self) -> &'static [usize; 2] {
           &ARR
       }
   }

   impl Into<&'static [usize]> for Zeroes {
       fn into(self) -> &'static [usize] {
           &ARR2
       }
   }

   fn main() {
       let &[a, b]: &[usize] = Zeroes.into() else {
          ..
       };
   }

If we’re in an irrefutable pattern we prefer the array impl candidate given that the slice impl candidate would be rejected anyway (if no ambiguity existed).

Source

fn infer_slice_pat( &mut self, pat: PatId, before: &[PatId], slice: Option<PatId>, after: &[PatId], expected: Ty<'db>, pat_info: PatInfo, ) -> Ty<'db>

Type check a slice pattern.

Syntactically, these look like [pat_0, ..., pat_n]. Semantically, we are type checking a pattern with structure:

[before_0, ..., before_n, (slice, after_0, ... after_n)?]

The type of slice, if it is present, depends on the expected type. If slice is missing, then so is after_i. If slice is present, it can still represent 0 elements.

Source

fn check_array_pat_len( &mut self, pat: PatId, element_ty: Ty<'db>, arr_ty: Ty<'db>, slice: Option<PatId>, len: Const<'db>, min_len: u128, ) -> (Option<Ty<'db>>, Ty<'db>)

Type check the length of an array pattern.

Returns both the type of the variable length pattern (or None), and the potentially inferred array type. We only return None for the slice type if slice.is_none().

Source

fn infer_destructuring_assignment_expr( &mut self, expr: ExprId, expected: Ty<'db>, ) -> Ty<'db>

Source§

impl<'db> InferenceContext<'db>

Source

pub(super) fn infer_path( &mut self, path: &Path, id: ExprOrPatIdPacked, ) -> Option<(ValueNs, Ty<'db>)>

Source

fn resolve_value_path( &mut self, path: &Path, id: ExprOrPatIdPacked, value: ValueNs, self_subst: Option<GenericArgs<'db>>, ) -> Option<ValuePathResolution<'db>>

Source

pub(super) fn resolve_value_path_inner( &mut self, path: &Path, id: ExprOrPatIdPacked, no_diagnostics: bool, ) -> Option<(ValueNs, Option<GenericArgs<'db>>)>

Source

pub(super) fn add_required_obligations_for_value_path( &mut self, node: ExprOrPatIdPacked, def: GenericDefId, subst: GenericArgs<'db>, )

Source

fn resolve_trait_assoc_item( &mut self, trait_ref: TraitRef<'db>, segment: PathSegment<'_>, id: ExprOrPatIdPacked, ) -> Option<(ValueNs, GenericArgs<'db>)>

Source

fn resolve_ty_assoc_item( &mut self, ty: Ty<'db>, name: &Name, id: ExprOrPatIdPacked, ) -> Option<(ValueNs, GenericArgs<'db>)>

Source

fn resolve_enum_variant_on_ty( &mut self, ty: Ty<'db>, name: &Name, id: ExprOrPatIdPacked, ) -> Option<(ValueNs, GenericArgs<'db>)>

Source§

impl<'db> InferenceContext<'db>

Source

pub(super) fn try_overloaded_deref( &self, expr: ExprId, base_ty: Ty<'db>, ) -> Option<InferOk<'db, MethodCallee<'db>>>

Source

fn make_overloaded_place_return_type( &self, method: MethodCallee<'db>, ) -> Ty<'db>

For the overloaded place expressions (*x, x[3]), the trait returns a type of &T, but the actual type we assign to the expression is T. So this function just peels off the return type by one layer to yield T.

Source

pub(super) fn lookup_derefing( &mut self, expr: ExprId, oprnd_expr: ExprId, oprnd_ty: Ty<'db>, ) -> Option<Ty<'db>>

Type-check *oprnd_expr with oprnd_expr type-checked already.

Source

pub(super) fn lookup_indexing( &mut self, expr: ExprId, base_expr: ExprId, index_expr: ExprId, base_ty: Ty<'db>, idx_ty: Ty<'db>, ) -> Option<(Ty<'db>, Ty<'db>)>

Type-check *base_expr[index_expr] with base_expr and index_expr type-checked already.

Source

fn try_index_step( expr: ExprId, base_expr: ExprId, index_expr: ExprId, autoderef: &mut GeneralAutoderef<'db, InferenceContextAutoderefCtx<'_, 'db>, Vec<(Ty<'db>, AutoderefKind)>>, index_ty: Ty<'db>, ) -> Option<(Ty<'db>, Ty<'db>)>

To type-check base_expr[index_expr], we progressively autoderef (and otherwise adjust) base_expr, looking for a type which either supports builtin indexing or overloaded indexing. This loop implements one step in that search; the autoderef loop is implemented by lookup_indexing.

Source

pub(super) fn try_overloaded_place_op( &self, expr: ExprId, base_ty: Ty<'db>, opt_rhs_ty: Option<Ty<'db>>, op: PlaceOp, ) -> Option<InferOk<'db, MethodCallee<'db>>>

Try to resolve an overloaded place op. We only deal with the immutable variant here (Deref/Index). In some contexts we would need the mutable variant (DerefMut/IndexMut); those would be later converted by convert_place_derefs_to_mutable.

Source

pub(super) fn try_mutable_overloaded_place_op( table: &InferenceTable<'db>, expr: ExprId, base_ty: Ty<'db>, opt_rhs_ty: Option<Ty<'db>>, op: PlaceOp, ) -> Option<InferOk<'db, MethodCallee<'db>>>

Source

pub(super) fn convert_place_op_to_mutable( &mut self, op: PlaceOp, expr: ExprId, base_expr: ExprId, index_expr: Option<ExprId>, )

Source§

impl<'db> InferenceContext<'db>

Source

fn new( db: &'db dyn HirDatabase, owner: InferBodyId<'db>, store_owner: ExpressionStoreOwnerId, generic_def: GenericDefId, store: &'db ExpressionStore, resolver: Resolver<'db>, allow_using_generic_params: bool, lowering_mode: LoweringMode, ) -> Self

Source

fn merge(&mut self, other: &InferenceResult<'db>)

Source

fn krate(&self) -> Crate

Source

fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget)

Source

fn deref_pat_borrow_mode( &self, pointer_ty: Ty<'_>, inner: PatId, ) -> DerefPatBorrowMode

How should a deref pattern find the place for its inner pattern to match on?

In most cases, if the pattern recursively contains a ref mut binding, we find the inner pattern’s scrutinee by calling DerefMut::deref_mut, and otherwise we call Deref::deref. However, for boxes we can use a built-in deref instead, which doesn’t borrow the scrutinee; in this case, we return DerefPatBorrowMode::Box.

Source

fn set_tainted_by_errors(&mut self)

Source

fn merge_anon_consts(&mut self)

Copy the inference of defined anon consts to ourselves, so that we don’t need to lookup the defining anon const when looking the type of something.

Source

fn resolve_all(self) -> InferenceResult<'db>

Source

fn collect_const(&mut self, id: ConstId, data: &'db ConstSignature)

Source

fn collect_static(&mut self, id: StaticId, data: &'db StaticSignature)

Source

fn collect_fn( &mut self, func: FunctionId, self_param: Option<BindingId>, params: &[Param<PatId>], )

Source

pub(crate) fn interner(&self) -> DbInterner<'db>

Source

pub(crate) fn infcx(&self) -> &InferCtxt<'db>

Source

fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db>

If ty is an error, returns an infer var instead. Otherwise, returns it.

“Refreshing” types like this is useful for getting better types, but it is also very dangerous: we might create duplicate diagnostics, for example if we try to resolve it and fail. rustc doesn’t do that for this reason (and is in general more strict with how it uses error types; an error type in inputs will almost always cause it to infer an error type in output, while we infer some type as much as we can).

Unfortunately, we cannot allow ourselves to do that. Not only we more often work with incomplete code, we also have assists, for example “Generate constant”, that will assume the inferred type is the expected type even if the expression itself cannot be inferred. Therefore, we choose a middle ground: refresh the type, but if we return a new var, mark it so that no diagnostics will be issued on it.

Source

fn infer_body(&mut self, body_expr: ExprId)

Source

fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>)

Source

pub(crate) fn write_expr_adj( &mut self, expr: ExprId, adjustments: Box<[Adjustment]>, )

Source

pub(crate) fn write_method_resolution( &mut self, expr: ExprId, func: FunctionId, subst: GenericArgs<'db>, )

Source

fn write_variant_resolution( &mut self, id: ExprOrPatIdPacked, variant: VariantId, )

Source

fn write_assoc_resolution( &mut self, id: ExprOrPatIdPacked, item: CandidateId, subs: GenericArgs<'db>, )

Source

fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>)

Source

fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>)

Source

pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic)

Source

fn record_deferred_call_resolution( &mut self, closure_def_id: ExprId, r: DeferredCallResolution<'db>, )

Source

fn remove_deferred_call_resolutions( &mut self, closure_def_id: ExprId, ) -> Vec<DeferredCallResolution<'db>>

Source

fn with_ty_lowering<R>( &mut self, store: &'db ExpressionStore, types_source: InferenceTyDiagnosticSource, store_owner: ExpressionStoreOwnerId, lifetime_elision: LifetimeElisionKind<'db>, f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R, ) -> R

Source

fn with_body_ty_lowering<R>( &mut self, f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R, ) -> R

Source

fn make_ty( &mut self, type_ref: TypeRefId, store: &'db ExpressionStore, type_source: InferenceTyDiagnosticSource, store_owner: ExpressionStoreOwnerId, lifetime_elision: LifetimeElisionKind<'db>, ) -> Ty<'db>

Source

pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db>

Source

fn generics(&self) -> &Generics<'db>

Source

fn identity_args(&self) -> GenericArgs<'db>

Source

pub(crate) fn create_body_anon_const( &mut self, expr: ExprId, expected_ty: Ty<'db>, allow_using_generic_params: bool, ) -> Const<'db>

Source

pub(crate) fn make_path_as_body_const(&mut self, path: &Path) -> Const<'db>

Source

fn err_ty(&self) -> Ty<'db>

Source

pub(crate) fn make_body_lifetime( &mut self, lifetime_ref: LifetimeRefId, ) -> Region<'db>

Source

fn insert_type_vars<T>(&mut self, ty: T) -> T
where T: TypeFoldable<DbInterner<'db>>,

Source

fn struct_tail_without_normalization(&mut self, ty: Ty<'db>) -> Ty<'db>

Attempts to returns the deeply last field of nested structures, but does not apply any normalization in its search. Returns the same type if input ty is not a structure at all.

Source

fn struct_tail_with_normalize( &mut self, ty: Ty<'db>, normalize: impl FnMut(Ty<'db>) -> Ty<'db>, ) -> Ty<'db>

Returns the deeply last field of nested structures, or the same type if not a structure at all. Corresponds to the only possible unsized field, and its type can be used to determine unsizing strategy.

This is parameterized over the normalization strategy (i.e. how to handle <T as Trait>::Assoc and impl Trait); pass the identity function to indicate no normalization should take place.

Source

fn process_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db>

Whenever you lower a user-written type, you should call this.

Source

fn process_remote_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db>

The difference of this method from process_user_written_ty() is that this method doesn’t register a well-formed obligation, while process_user_written_ty() should (but doesn’t currently).

Source

fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db>

Source

pub(crate) fn resolve_vars_if_possible<T: TypeFoldable<DbInterner<'db>>>( &self, t: T, ) -> T

Source

pub(crate) fn structurally_resolve_type( &mut self, node: ExprOrPatIdPacked, ty: Ty<'db>, ) -> Ty<'db>

Source

pub(crate) fn emit_type_mismatch( &mut self, node: ExprOrPatIdPacked, expected: Ty<'db>, found: Ty<'db>, )

Source

fn demand_eqtype( &mut self, id: ExprOrPatIdPacked, expected: Ty<'db>, actual: Ty<'db>, ) -> Result<(), ()>

Source

fn demand_eqtype_fixme_no_diag( &mut self, expected: Ty<'db>, actual: Ty<'db>, ) -> Result<(), ()>

Source

fn demand_suptype( &mut self, id: ExprOrPatIdPacked, expected: Ty<'db>, actual: Ty<'db>, ) -> Result<(), ()>

Source

fn demand_coerce( &mut self, expr: ExprId, checked_ty: Ty<'db>, expected: Ty<'db>, allow_two_phase: AllowTwoPhase, expr_is_read: ExprIsRead, ) -> Ty<'db>

Source

pub(crate) fn type_must_be_known_at_this_point( &mut self, node: ExprOrPatIdPacked, ty: Ty<'db>, ) -> Ty<'db>

Source

pub(crate) fn require_type_is_sized(&mut self, ty: Ty<'db>, span: Span)

Source

fn expr_ty(&self, expr: ExprId) -> Ty<'db>

Source

fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db>

Source

fn resolve_variant( &mut self, node: ExprOrPatIdPacked, path: &Path, value_ns: bool, ) -> (Ty<'db>, Option<VariantId>)

Source

fn resolve_variant_on_alias( &mut self, node: ExprOrPatIdPacked, ty: Ty<'db>, unresolved: Option<usize>, path: &ModPath, ) -> (Ty<'db>, Option<VariantId>)

Source

fn resolve_boxed_box(&self) -> Option<AdtId>

Source

fn resolve_range_full(&self) -> Option<AdtId>

Source

fn has_new_range_feature(&self) -> bool

Source

fn resolve_range(&self) -> Option<AdtId>

Source

fn resolve_range_inclusive(&self) -> Option<AdtId>

Source

fn resolve_range_from(&self) -> Option<AdtId>

Source

fn resolve_range_to(&self) -> Option<AdtId>

Source

fn resolve_range_to_inclusive(&self) -> Option<AdtId>

Source

fn resolve_va_list(&self) -> Option<AdtId>

Source

pub(crate) fn get_traits_in_scope( &self, ) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>>

Source

fn has_applicable_non_exhaustive(&self, def: AttrDefId) -> bool

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn confirm_method( &mut self, pick: &Pick<'db>, unadjusted_self_ty: Ty<'db>, expr: ExprId, generic_args: Option<&HirGenericArgs>, ) -> ConfirmResult<'db>

Source§

impl<'db> InferenceContext<'db>

Source

pub(crate) fn lookup_method_including_private( &mut self, self_ty: Ty<'db>, name: Name, generic_args: Option<&HirGenericArgs>, receiver: ExprId, call_expr: ExprId, ) -> Result<(MethodCallee<'db>, bool), MethodError<'db>>

Performs method lookup. If lookup is successful, it will return the callee and store an appropriate adjustment for the self-expr. In some cases it may report an error (e.g., invoking the drop method).

Source

pub(crate) fn lookup_probe( &self, call_expr: ExprId, receiver: ExprId, method_name: Name, self_ty: Ty<'db>, ) -> Result<Pick<'db>, MethodError<'db>>

Source

pub(crate) fn with_method_resolution<R>( &self, call_span: Span, receiver_span: Span, f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R, ) -> R

Trait Implementations§

Source§

impl<'db> Debug for InferenceContext<'db>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'db> !Freeze for InferenceContext<'db>

§

impl<'db> !RefUnwindSafe for InferenceContext<'db>

§

impl<'db> !Send for InferenceContext<'db>

§

impl<'db> !Sync for InferenceContext<'db>

§

impl<'db> Unpin for InferenceContext<'db>

§

impl<'db> UnsafeUnpin for InferenceContext<'db>

§

impl<'db> !UnwindSafe for InferenceContext<'db>

Blanket Implementations§

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
§

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

§

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

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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.

§

impl<T> IntoBox<dyn Any> for T
where T: Any,

§

fn into_box(self) -> Box<dyn Any>

Convert self into the appropriate boxed form.
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Lookup<T> for T

§

fn into_owned(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

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>,

Source§

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<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

§

fn upcast(self, interner: I) -> U

§

impl<I, T> UpcastFrom<I, T> for T

§

fn upcast_from(from: T, _tcx: I) -> T

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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