pub(crate) struct ElaborateDrops;
Expand description
During MIR building, Drop terminators are inserted in every place where a drop may occur. However, in this phase, the presence of these terminators does not guarantee that a destructor will run, as the target of the drop may be uninitialized. In general, the compiler cannot determine at compile time whether a destructor will run or not.
At a high level, this pass refines Drop to only run the destructor if the target is initialized. The way this is achieved is by inserting drop flags for every variable that may be dropped, and then using those flags to determine whether a destructor should run. Once this is complete, Drop terminators in the MIR correspond to a call to the “drop glue” or “drop shim” for the type of the dropped place.
This pass relies on dropped places having an associated move path, which is then used to determine the initialization status of the place and its descendants. It’s worth noting that a MIR containing a Drop without an associated move path is probably ill formed, as it would allow running a destructor on a place behind a reference:
fn drop_term<T>(t: &mut T) {
mir! {
{
Drop(*t, exit)
}
exit = {
Return()
}
}
}
Trait Implementations§
source§impl<'tcx> MirPass<'tcx> for ElaborateDrops
impl<'tcx> MirPass<'tcx> for ElaborateDrops
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>)
fn name(&self) -> &'static str
fn profiler_name(&self) -> &'static str
source§fn is_enabled(&self, _sess: &Session) -> bool
fn is_enabled(&self, _sess: &Session) -> bool
true
if this pass is enabled with the current combination of compiler flags.fn is_mir_dump_enabled(&self) -> bool
Auto Trait Implementations§
impl DynSend for ElaborateDrops
impl DynSync for ElaborateDrops
impl Freeze for ElaborateDrops
impl RefUnwindSafe for ElaborateDrops
impl Send for ElaborateDrops
impl Sync for ElaborateDrops
impl Unpin for ElaborateDrops
impl UnwindSafe for ElaborateDrops
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, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
source§impl<T> Filterable for T
impl<T> Filterable for T
source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§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 moresource§impl<P> IntoQueryParam<P> for P
impl<P> IntoQueryParam<P> for P
fn into_query_param(self) -> P
source§impl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
source§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
source§impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T
source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<T> ErasedDestructor for Twhere
T: 'static,
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: 0 bytes