rustc_borrowck::type_check

Struct TypeChecker

source
struct TypeChecker<'a, 'tcx> {
    infcx: &'a BorrowckInferCtxt<'tcx>,
    param_env: ParamEnv<'tcx>,
    last_span: Span,
    body: &'a Body<'tcx>,
    user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
    known_type_outlives_obligations: &'tcx [PolyTypeOutlivesPredicate<'tcx>],
    implicit_region_bound: Region<'tcx>,
    reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
    borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
}
Expand description

The MIR type checker. Visits the MIR and enforces all the constraints needed for it to be valid and well-typed. Along the way, it accrues region constraints – these can later be used by NLL region checking.

Fields§

§infcx: &'a BorrowckInferCtxt<'tcx>§param_env: ParamEnv<'tcx>§last_span: Span§body: &'a Body<'tcx>§user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>

User type annotations are shared between the main MIR and the MIR of all of the promoted items.

§region_bound_pairs: &'a RegionBoundPairs<'tcx>§known_type_outlives_obligations: &'tcx [PolyTypeOutlivesPredicate<'tcx>]§implicit_region_bound: Region<'tcx>§reported_errors: FxIndexSet<(Ty<'tcx>, Span)>§borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>

Implementations§

source§

impl<'a, 'tcx> TypeChecker<'a, 'tcx>

source

pub(super) fn fully_perform_op<R: Debug, Op>( &mut self, locations: Locations, category: ConstraintCategory<'tcx>, op: Op, ) -> Result<R, ErrorGuaranteed>
where Op: TypeOp<'tcx, Output = R>, Op::ErrorInfo: ToUniverseInfo<'tcx>,

Given some operation op that manipulates types, proves predicates, or otherwise uses the inference context, executes op and then executes all the further obligations that op returns. This will yield a set of outlives constraints amongst regions which are extracted and stored as having occurred at locations.

Any rustc_infer::infer operations that might generate region constraints should occur within this method so that those constraints can be properly localized!

source

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

source

pub(super) fn prove_trait_ref( &mut self, trait_ref: TraitRef<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, )

source

pub(super) fn normalize_and_prove_instantiated_predicates( &mut self, _def_id: DefId, instantiated_predicates: InstantiatedPredicates<'tcx>, locations: Locations, )

source

pub(super) fn prove_predicates( &mut self, predicates: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, Predicate<'tcx>> + Debug>, locations: Locations, category: ConstraintCategory<'tcx>, )

source

pub(super) fn prove_predicate( &mut self, predicate: impl Upcast<TyCtxt<'tcx>, Predicate<'tcx>> + Debug, locations: Locations, category: ConstraintCategory<'tcx>, )

source

pub(super) fn normalize<T>( &mut self, value: T, location: impl NormalizeLocation, ) -> T
where T: Normalizable<'tcx> + Display + Copy + 'tcx,

source

pub(super) fn normalize_with_category<T>( &mut self, value: T, location: impl NormalizeLocation, category: ConstraintCategory<'tcx>, ) -> T
where T: Normalizable<'tcx> + Display + Copy + 'tcx,

source

pub(super) fn struct_tail( &mut self, ty: Ty<'tcx>, location: impl NormalizeLocation, ) -> Ty<'tcx>

source

pub(super) fn ascribe_user_type( &mut self, mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>, span: Span, )

source

pub(super) fn ascribe_user_type_skip_wf( &mut self, mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>, span: Span, )

Incorrectly skips the WF checks we normally do in ascribe_user_type.

FIXME(#104478, #104477): This is a hack for backward-compatibility.

source§

impl<'a, 'tcx> TypeChecker<'a, 'tcx>

source

pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>)

Check explicit closure signature annotation, e.g., |x: FxIndexMap<_, &'static u32>| ....

source

pub(super) fn equate_inputs_and_outputs( &mut self, body: &Body<'tcx>, universal_regions: &UniversalRegions<'tcx>, normalized_inputs_and_output: &[Ty<'tcx>], )

source

fn equate_normalized_input_or_output( &mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span, )

source§

impl<'a, 'tcx> TypeChecker<'a, 'tcx>

source

pub(super) fn relate_types( &mut self, a: Ty<'tcx>, v: Variance, b: Ty<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution>

Adds sufficient constraints to ensure that a R b where R depends on v:

  • “Covariant” a <: b
  • “Invariant” a == b
  • “Contravariant” a :> b

N.B., the type a is permitted to have unresolved inference variables, but not the type b.

source

pub(super) fn eq_args( &mut self, a: GenericArgsRef<'tcx>, b: GenericArgsRef<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution>

Add sufficient constraints to ensure a == b. See also Self::relate_types.

source§

impl<'a, 'tcx> TypeChecker<'a, 'tcx>

source

fn new( infcx: &'a BorrowckInferCtxt<'tcx>, body: &'a Body<'tcx>, param_env: ParamEnv<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, known_type_outlives_obligations: &'tcx [PolyTypeOutlivesPredicate<'tcx>], implicit_region_bound: Region<'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, ) -> Self

source

fn body(&self) -> &Body<'tcx>

source

fn unsized_feature_enabled(&self) -> bool

source

fn check_user_type_annotations(&mut self)

Equate the inferred type and the annotated type for user type annotations

source

fn push_region_constraints( &mut self, locations: Locations, category: ConstraintCategory<'tcx>, data: &QueryRegionConstraints<'tcx>, )

source

fn sub_types( &mut self, sub: Ty<'tcx>, sup: Ty<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution>

Try to relate sub <: sup

source

fn eq_types( &mut self, expected: Ty<'tcx>, found: Ty<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution>

source

fn relate_type_and_user_type( &mut self, a: Ty<'tcx>, v: Variance, user_ty: &UserTypeProjection, locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution>

source

fn check_inline_const( &mut self, inferred_ty: Ty<'tcx>, def_id: LocalDefId, args: UserArgs<'tcx>, span: Span, )

source

fn tcx(&self) -> TyCtxt<'tcx>

source

fn check_stmt( &mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location, )

source

fn check_terminator( &mut self, body: &Body<'tcx>, term: &Terminator<'tcx>, term_location: Location, )

source

fn check_call_dest( &mut self, body: &Body<'tcx>, term: &Terminator<'tcx>, sig: &FnSig<'tcx>, destination: Place<'tcx>, target: Option<BasicBlock>, term_location: Location, )

source

fn check_call_inputs( &mut self, body: &Body<'tcx>, term: &Terminator<'tcx>, func: &Operand<'tcx>, sig: &FnSig<'tcx>, args: &[Spanned<Operand<'tcx>>], term_location: Location, call_source: CallSource, )

source

fn check_iscleanup( &mut self, body: &Body<'tcx>, block_data: &BasicBlockData<'tcx>, )

source

fn assert_iscleanup( &mut self, body: &Body<'tcx>, ctxt: &dyn Debug, bb: BasicBlock, iscleanuppad: bool, )

source

fn assert_iscleanup_unwind( &mut self, body: &Body<'tcx>, ctxt: &dyn Debug, unwind: UnwindAction, is_cleanup: bool, )

source

fn check_local( &mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>, )

source

fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span)

source

fn aggregate_field_ty( &mut self, ak: &AggregateKind<'tcx>, field_index: FieldIdx, location: Location, ) -> Result<Ty<'tcx>, FieldAccessError>

source

fn check_operand(&mut self, op: &Operand<'tcx>, location: Location)

source

fn check_rvalue( &mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location, )

source

fn rvalue_user_ty( &self, rvalue: &Rvalue<'tcx>, ) -> Option<UserTypeAnnotationIndex>

If this rvalue supports a user-given type annotation, then extract and return it. This represents the final type of the rvalue and will be unified with the inferred type.

source

fn check_aggregate_rvalue( &mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, aggregate_kind: &AggregateKind<'tcx>, operands: &IndexSlice<FieldIdx, Operand<'tcx>>, location: Location, )

source

fn add_reborrow_constraint( &mut self, body: &Body<'tcx>, location: Location, borrow_region: Region<'tcx>, borrowed_place: &Place<'tcx>, )

Adds the constraints that arise from a borrow expression &'a P at the location L.

§Parameters
  • location: the location L where the borrow expression occurs
  • borrow_region: the region 'a associated with the borrow
  • borrowed_place: the place P being borrowed
source

fn prove_aggregate_predicates( &mut self, aggregate_kind: &AggregateKind<'tcx>, location: Location, )

source

fn prove_closure_bounds( &mut self, tcx: TyCtxt<'tcx>, def_id: LocalDefId, args: GenericArgsRef<'tcx>, locations: Locations, ) -> InstantiatedPredicates<'tcx>

source

fn typeck_mir(&mut self, body: &Body<'tcx>)

Auto Trait Implementations§

§

impl<'a, 'tcx> Freeze for TypeChecker<'a, 'tcx>

§

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

§

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

§

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

§

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

§

impl<'a, 'tcx> !UnwindSafe for TypeChecker<'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<_>>()).

source§

type Output = R

source§

impl<T> Filterable for T

source§

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

impl<P> IntoQueryParam<P> for P

source§

impl<T> MaybeResult<T> for T

source§

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

source§

type Output = T

Should always be Self
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.
source§

impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

source§

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

source§

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

source§

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

source§

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

source§

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,

source§

impl<T> ErasedDestructor for T
where T: 'static,

source§

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: 136 bytes