Struct flux_rustc_bridge::mir::Body

source ·
pub struct Body<'tcx> {
    pub basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
    pub local_decls: IndexVec<Local, LocalDecl>,
    pub infcx: InferCtxt<'tcx>,
    fake_predecessors: IndexVec<BasicBlock, usize>,
    body_with_facts: BodyWithBorrowckFacts<'tcx>,
}

Fields§

§basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>§local_decls: IndexVec<Local, LocalDecl>§infcx: InferCtxt<'tcx>

During borrow checking, rustc generates fresh region variable ids for each structurally different position in a type. For example, given a function

fn foo<'a, 'b>(x: &'a S<'a>, y: &'b u32)

rustc will generate variables ?2 and ?3 for the universal regions 'a and 'b (the variable ?0 correspond to 'static and ?1 to the implicit lifetime of the function body). Additionally, it will assign x type &‘?4 S<’?5>andytype&’?6 u32` (together with some constraints relating region variables). Unfortunately, we cannot recover the exact region variables rustc used.

The exact ids picked for 'a and 'b are not too relevant to us, the important part is the regions used in the types of x and y. To work around this, we generate fresh regions variables for the function signature, different from the ones sued by rustc. To recover the correct regions, whenever there’s an assignment of a refinement type T to a variable with (unrefined) Rust type S, we match both types to infer a region substitution. For this to work, we need to give a different variable id to every position in T. To avoid clashes, we need to use fresh ids, so we start enumerating from the last id generated by borrow checking.

To do that, we replicate the InferCtxt use for mir typeck by generating region variables for every region in the RegionInferenceContext. The InferCtxt is then used to generate new region variables.

The ids generated during refinement type checking are purely instrumental and temporary, they should never appear in a type bound in the environment.

Besides generating ids when checking a function’s body, we also need to generate fresh ids at function calls.

Additionally, the InferCtxt is used during type projection normalization.

§fake_predecessors: IndexVec<BasicBlock, usize>§body_with_facts: BodyWithBorrowckFacts<'tcx>

Implementations§

source§

impl<'tcx> Body<'tcx>

source

pub fn new( basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>, local_decls: IndexVec<Local, LocalDecl>, body_with_facts: BodyWithBorrowckFacts<'tcx>, infcx: InferCtxt<'tcx>, ) -> Self

source

pub fn def_id(&self) -> DefId

source

pub fn span(&self) -> Span

source

pub fn inner(&self) -> &Body<'tcx>

source

pub fn args_iter(&self) -> impl ExactSizeIterator<Item = Local>

source

pub fn vars_and_temps_iter(&self) -> impl ExactSizeIterator<Item = Local>

source

pub fn is_join_point(&self, bb: BasicBlock) -> bool

source

pub fn dominators(&self) -> &Dominators<BasicBlock>

source

pub fn terminator_loc(&self, bb: BasicBlock) -> Location

source

pub fn calculate_borrows_out_of_scope_at_location( &self, ) -> FxIndexMap<Location, Vec<BorrowIndex>>

source

pub fn borrow_data(&self, idx: BorrowIndex) -> &BorrowData<'tcx>

source

pub fn rustc_body(&self) -> &Body<'tcx>

source

pub fn local_kind(&self, local: Local) -> LocalKind

Trait Implementations§

source§

impl Debug for Body<'_>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'tcx> !Freeze for Body<'tcx>

§

impl<'tcx> !RefUnwindSafe for Body<'tcx>

§

impl<'tcx> !Send for Body<'tcx>

§

impl<'tcx> !Sync for Body<'tcx>

§

impl<'tcx> Unpin for Body<'tcx>

§

impl<'tcx> !UnwindSafe for Body<'tcx>

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

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

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