pub struct BodyRoot<'tcx> {
pub body: Body<'tcx>,
pub promoted: IndexVec<Promoted, Body<'tcx>>,
pub infcx: InferCtxt<'tcx>,
pub borrow_set: BorrowSet<'tcx>,
pub region_inference_context: RegionInferenceContext<'tcx>,
}Fields§
§body: Body<'tcx>§promoted: IndexVec<Promoted, Body<'tcx>>§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.
borrow_set: BorrowSet<'tcx>The set of borrows occurring in body with data about them.
region_inference_context: RegionInferenceContext<'tcx>Context generated during borrowck, intended to be passed to
[calculate_borrows_out_of_scope_at_location].
Implementations§
Source§impl<'tcx> BodyRoot<'tcx>
impl<'tcx> BodyRoot<'tcx>
pub fn body(&self) -> &Body<'tcx>
pub fn calculate_borrows_out_of_scope_at_location( &self, ) -> FxIndexMap<Location, Vec<BorrowIndex>>
pub fn borrow_data(&self, idx: BorrowIndex) -> &BorrowData<'tcx>
Auto Trait Implementations§
impl<'tcx> !Freeze for BodyRoot<'tcx>
impl<'tcx> !RefUnwindSafe for BodyRoot<'tcx>
impl<'tcx> !Send for BodyRoot<'tcx>
impl<'tcx> !Sync for BodyRoot<'tcx>
impl<'tcx> Unpin for BodyRoot<'tcx>
impl<'tcx> !UnwindSafe for BodyRoot<'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
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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