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>and
ytype
&’?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>
impl<'tcx> Body<'tcx>
pub fn new( basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>, local_decls: IndexVec<Local, LocalDecl>, body_with_facts: BodyWithBorrowckFacts<'tcx>, infcx: InferCtxt<'tcx>, ) -> Self
pub fn def_id(&self) -> DefId
pub fn span(&self) -> Span
pub fn inner(&self) -> &Body<'tcx>
pub fn args_iter(&self) -> impl ExactSizeIterator<Item = Local>
pub fn vars_and_temps_iter(&self) -> impl ExactSizeIterator<Item = Local>
pub fn is_join_point(&self, bb: BasicBlock) -> bool
pub fn dominators(&self) -> &Dominators<BasicBlock>
pub fn terminator_loc(&self, bb: BasicBlock) -> Location
pub fn calculate_borrows_out_of_scope_at_location( &self, ) -> FxIndexMap<Location, Vec<BorrowIndex>>
pub fn borrow_data(&self, idx: BorrowIndex) -> &BorrowData<'tcx>
pub fn rustc_body(&self) -> &Body<'tcx>
pub fn local_kind(&self, local: Local) -> LocalKind
Trait Implementations§
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more