Struct rustc_mir_dataflow::elaborate_drops::DropCtxt
source · struct DropCtxt<'l, 'b, 'tcx, D>where
D: DropElaborator<'b, 'tcx>,{
elaborator: &'l mut D,
source_info: SourceInfo,
place: Place<'tcx>,
path: D::Path,
succ: BasicBlock,
unwind: Unwind,
}
Fields
elaborator: &'l mut D
source_info: SourceInfo
place: Place<'tcx>
path: D::Path
succ: BasicBlock
unwind: Unwind
Implementations
sourceimpl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>where
D: DropElaborator<'b, 'tcx>,
'tcx: 'b,
impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>where
D: DropElaborator<'b, 'tcx>,
'tcx: 'b,
fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx>
fn tcx(&self) -> TyCtxt<'tcx>
sourcepub fn elaborate_drop(&mut self, bb: BasicBlock)
pub fn elaborate_drop(&mut self, bb: BasicBlock)
This elaborates a single drop instruction, located at bb
, and
patches over it.
The elaborated drop checks the drop flags to only drop what is initialized.
In addition, the relevant drop flags also need to be cleared to avoid double-drops. However, in the middle of a complex drop, one must avoid clearing some of the flags before they are read, as that would cause a memory leak.
In particular, when dropping an ADT, multiple fields may be
joined together under the rest
subpath. They are all controlled
by the primary drop flag, but only the last rest-field dropped
should clear it (and it must also not clear anything else).
sourcefn move_paths_for_fields(
&self,
base_place: Place<'tcx>,
variant_path: D::Path,
variant: &'tcx VariantDef,
substs: SubstsRef<'tcx>
) -> Vec<(Place<'tcx>, Option<D::Path>)>
fn move_paths_for_fields(
&self,
base_place: Place<'tcx>,
variant_path: D::Path,
variant: &'tcx VariantDef,
substs: SubstsRef<'tcx>
) -> Vec<(Place<'tcx>, Option<D::Path>)>
Returns the place and move path for each field of variant
,
(the move path is None
if the field is a rest field).
fn drop_subpath(
&mut self,
place: Place<'tcx>,
path: Option<D::Path>,
succ: BasicBlock,
unwind: Unwind
) -> BasicBlock
sourcefn drop_halfladder(
&mut self,
unwind_ladder: &[Unwind],
succ: BasicBlock,
fields: &[(Place<'tcx>, Option<D::Path>)]
) -> Vec<BasicBlock>
fn drop_halfladder(
&mut self,
unwind_ladder: &[Unwind],
succ: BasicBlock,
fields: &[(Place<'tcx>, Option<D::Path>)]
) -> Vec<BasicBlock>
Creates one-half of the drop ladder for a list of fields, and return the list of steps in it in reverse order, with the first step dropping 0 fields and so on.
unwind_ladder
is such a list of steps in reverse order,
which is called if the matching step of the drop glue panics.
fn drop_ladder_bottom(&mut self) -> (BasicBlock, Unwind)
sourcefn drop_ladder(
&mut self,
fields: Vec<(Place<'tcx>, Option<D::Path>)>,
succ: BasicBlock,
unwind: Unwind
) -> (BasicBlock, Unwind)
fn drop_ladder(
&mut self,
fields: Vec<(Place<'tcx>, Option<D::Path>)>,
succ: BasicBlock,
unwind: Unwind
) -> (BasicBlock, Unwind)
Creates a full drop ladder, consisting of 2 connected half-drop-ladders
For example, with 3 fields, the drop ladder is
.d0:
ELAB(drop location.0 [target=.d1, unwind=.c1])
.d1:
ELAB(drop location.1 [target=.d2, unwind=.c2])
.d2:
ELAB(drop location.2 [target=self.succ
, unwind=self.unwind
])
.c1:
ELAB(drop location.1 [target=.c2])
.c2:
ELAB(drop location.2 [target=self.unwind
])
NOTE: this does not clear the master drop flag, so you need
to point succ/unwind on a drop_ladder_bottom
.
fn open_drop_for_tuple(&mut self, tys: &[Ty<'tcx>]) -> BasicBlock
fn open_drop_for_box(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>
) -> BasicBlock
fn open_drop_for_adt(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>
) -> BasicBlock
fn open_drop_for_adt_contents(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>
) -> (BasicBlock, Unwind)
fn open_drop_for_multivariant(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
succ: BasicBlock,
unwind: Unwind
) -> (BasicBlock, Unwind)
fn adt_switch_block(
&mut self,
adt: AdtDef<'tcx>,
blocks: Vec<BasicBlock>,
values: &[u128],
succ: BasicBlock,
unwind: Unwind
) -> BasicBlock
fn destructor_call_block(
&mut self,
(succ, unwind): (BasicBlock, Unwind)
) -> BasicBlock
sourcefn drop_loop(
&mut self,
succ: BasicBlock,
cur: Local,
length_or_end: Place<'tcx>,
ety: Ty<'tcx>,
unwind: Unwind,
ptr_based: bool
) -> BasicBlock
fn drop_loop(
&mut self,
succ: BasicBlock,
cur: Local,
length_or_end: Place<'tcx>,
ety: Ty<'tcx>,
unwind: Unwind,
ptr_based: bool
) -> BasicBlock
Create a loop that drops an array:
loop-block:
can_go = cur == length_or_end
if can_go then succ else drop-block
drop-block:
if ptr_based {
ptr = cur
cur = cur.offset(1)
} else {
ptr = &raw mut P[cur]
cur = cur + 1
}
drop(ptr)
fn open_drop_for_array(
&mut self,
ety: Ty<'tcx>,
opt_size: Option<u64>
) -> BasicBlock
sourcefn drop_loop_pair(
&mut self,
ety: Ty<'tcx>,
ptr_based: bool,
length: Place<'tcx>
) -> BasicBlock
fn drop_loop_pair(
&mut self,
ety: Ty<'tcx>,
ptr_based: bool,
length: Place<'tcx>
) -> BasicBlock
Creates a pair of drop-loops of place
, which drops its contents, even
in the case of 1 panic. If ptr_based
, creates a pointer loop,
otherwise create an index loop.
sourcefn open_drop(&mut self) -> BasicBlock
fn open_drop(&mut self) -> BasicBlock
The slow-path - create an “open”, elaborated drop for a type
which is moved-out-of only partially, and patch bb
to a jump
to it. This must not be called on ADTs with a destructor,
as these can’t be moved-out-of, except for Box<T>
, which is
special-cased.
This creates a “drop ladder” that drops the needed fields of the ADT, both in the success case or if one of the destructors fail.
fn complete_drop(&mut self, succ: BasicBlock, unwind: Unwind) -> BasicBlock
sourcefn drop_flag_reset_block(
&mut self,
mode: DropFlagMode,
succ: BasicBlock,
unwind: Unwind
) -> BasicBlock
fn drop_flag_reset_block(
&mut self,
mode: DropFlagMode,
succ: BasicBlock,
unwind: Unwind
) -> BasicBlock
Creates a block that resets the drop flag. If mode
is deep, all children drop flags will
also be cleared.
fn elaborated_drop_block(&mut self) -> BasicBlock
sourcefn box_free_block(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
target: BasicBlock,
unwind: Unwind
) -> BasicBlock
fn box_free_block(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
target: BasicBlock,
unwind: Unwind
) -> BasicBlock
Creates a block that frees the backing memory of a Box
if its drop is required (either
statically or by checking its drop flag).
The contained value will not be dropped.
sourcefn unelaborated_free_block(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
target: BasicBlock,
unwind: Unwind
) -> BasicBlock
fn unelaborated_free_block(
&mut self,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
target: BasicBlock,
unwind: Unwind
) -> BasicBlock
Creates a block that frees the backing memory of a Box
(without dropping the contained
value).
fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock
fn goto_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock
sourcefn drop_flag_test_block(
&mut self,
on_set: BasicBlock,
on_unset: BasicBlock,
unwind: Unwind
) -> BasicBlock
fn drop_flag_test_block(
&mut self,
on_set: BasicBlock,
on_unset: BasicBlock,
unwind: Unwind
) -> BasicBlock
Returns the block to jump to in order to test the drop flag and execute the drop.
Depending on the required DropStyle
, this might be a generated block with an if
terminator (for dynamic/open drops), or it might be on_set
or on_unset
itself, in case
the drop can be statically determined.
fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock
fn new_temp(&mut self, ty: Ty<'tcx>) -> Local
fn constant_usize(&self, val: u16) -> Operand<'tcx>
fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx>
Trait Implementations
Auto Trait Implementations
impl<'l, 'b, 'tcx, D> !RefUnwindSafe for DropCtxt<'l, 'b, 'tcx, D>
impl<'l, 'b, 'tcx, D> !Send for DropCtxt<'l, 'b, 'tcx, D>
impl<'l, 'b, 'tcx, D> !Sync for DropCtxt<'l, 'b, 'tcx, D>
impl<'l, 'b, 'tcx, D> Unpin for DropCtxt<'l, 'b, 'tcx, D>where
<D as DropElaborator<'b, 'tcx>>::Path: Unpin,
impl<'l, 'b, 'tcx, D> !UnwindSafe for DropCtxt<'l, 'b, 'tcx, D>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Layout
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.