Trait sp_std::ops::Drop

1.0.0 · source ·
pub trait Drop {
    // Required method
    fn drop(&mut self);
}
Expand description

Custom code within the destructor.

When a value is no longer needed, Rust will run a “destructor” on that value. The most common way that a value is no longer needed is when it goes out of scope. Destructors may still run in other circumstances, but we’re going to focus on scope for the examples here. To learn about some of those other cases, please see the reference section on destructors.

This destructor consists of two components:

  • A call to Drop::drop for that value, if this special Drop trait is implemented for its type.
  • The automatically generated “drop glue” which recursively calls the destructors of all the fields of this value.

As Rust automatically calls the destructors of all contained fields, you don’t have to implement Drop in most cases. But there are some cases where it is useful, for example for types which directly manage a resource. That resource may be memory, it may be a file descriptor, it may be a network socket. Once a value of that type is no longer going to be used, it should “clean up” its resource by freeing the memory or closing the file or socket. This is the job of a destructor, and therefore the job of Drop::drop.

§Examples

To see destructors in action, let’s take a look at the following program:

struct HasDrop;

impl Drop for HasDrop {
    fn drop(&mut self) {
        println!("Dropping HasDrop!");
    }
}

struct HasTwoDrops {
    one: HasDrop,
    two: HasDrop,
}

impl Drop for HasTwoDrops {
    fn drop(&mut self) {
        println!("Dropping HasTwoDrops!");
    }
}

fn main() {
    let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
    println!("Running!");
}

Rust will first call Drop::drop for _x and then for both _x.one and _x.two, meaning that running this will print

Running!
Dropping HasTwoDrops!
Dropping HasDrop!
Dropping HasDrop!

Even if we remove the implementation of Drop for HasTwoDrop, the destructors of its fields are still called. This would result in

Running!
Dropping HasDrop!
Dropping HasDrop!

§You cannot call Drop::drop yourself

Because Drop::drop is used to clean up a value, it may be dangerous to use this value after the method has been called. As Drop::drop does not take ownership of its input, Rust prevents misuse by not allowing you to call Drop::drop directly.

In other words, if you tried to explicitly call Drop::drop in the above example, you’d get a compiler error.

If you’d like to explicitly call the destructor of a value, mem::drop can be used instead.

§Drop order

Which of our two HasDrop drops first, though? For structs, it’s the same order that they’re declared: first one, then two. If you’d like to try this yourself, you can modify HasDrop above to contain some data, like an integer, and then use it in the println! inside of Drop. This behavior is guaranteed by the language.

Unlike for structs, local variables are dropped in reverse order:

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("Dropping Foo!")
    }
}

struct Bar;

impl Drop for Bar {
    fn drop(&mut self) {
        println!("Dropping Bar!")
    }
}

fn main() {
    let _foo = Foo;
    let _bar = Bar;
}

This will print

Dropping Bar!
Dropping Foo!

Please see the reference for the full rules.

§Copy and Drop are exclusive

You cannot implement both Copy and Drop on the same type. Types that are Copy get implicitly duplicated by the compiler, making it very hard to predict when, and how often destructors will be executed. As such, these types cannot have destructors.

§Drop check

Dropping interacts with the borrow checker in subtle ways: when a type T is being implicitly dropped as some variable of this type goes out of scope, the borrow checker needs to ensure that calling T’s destructor at this moment is safe. In particular, it also needs to be safe to recursively drop all the fields of T. For example, it is crucial that code like the following is being rejected:

use std::cell::Cell;

struct S<'a>(Cell<Option<&'a S<'a>>>, Box<i32>);
impl Drop for S<'_> {
    fn drop(&mut self) {
        if let Some(r) = self.0.get() {
            // Print the contents of the `Box` in `r`.
            println!("{}", r.1);
        }
    }
}

fn main() {
    // Set up two `S` that point to each other.
    let s1 = S(Cell::new(None), Box::new(42));
    let s2 = S(Cell::new(Some(&s1)), Box::new(42));
    s1.0.set(Some(&s2));
    // Now they both get dropped. But whichever is the 2nd one
    // to be dropped will access the `Box` in the first one,
    // which is a use-after-free!
}

The Nomicon discusses the need for drop check in more detail.

To reject such code, the “drop check” analysis determines which types and lifetimes need to still be live when T gets dropped. The exact details of this analysis are not yet stably guaranteed and subject to change. Currently, the analysis works as follows:

  • If T has no drop glue, then trivially nothing is required to be live. This is the case if neither T nor any of its (recursive) fields have a destructor (impl Drop). PhantomData and ManuallyDrop are considered to never have a destructor, no matter their field type.
  • If T has drop glue, then, for all types U that are owned by any field of T, recursively add the types and lifetimes that need to be live when U gets dropped. The set of owned types is determined by recursively traversing T:
    • Recursively descend through PhantomData, Box, tuples, and arrays (including arrays of length 0).
    • Stop at reference and raw pointer types as well as function pointers and function items; they do not own anything.
    • Stop at non-composite types (type parameters that remain generic in the current context and base types such as integers and bool); these types are owned.
    • When hitting an ADT with impl Drop, stop there; this type is owned.
    • When hitting an ADT without impl Drop, recursively descend to its fields. (For an enum, consider all fields of all variants.)
  • Furthermore, if T implements Drop, then all generic (lifetime and type) parameters of T must be live.

In the above example, the last clause implies that 'a must be live when S<'a> is dropped, and hence the example is rejected. If we remove the impl Drop, the liveness requirement disappears and the example is accepted.

There exists an unstable way for a type to opt-out of the last clause; this is called “drop check eyepatch” or may_dangle. For more details on this nightly-only feature, see the discussion in the Nomicon.

Required Methods§

1.0.0 · source

fn drop(&mut self)

Executes the destructor for this type.

This method is called implicitly when the value goes out of scope, and cannot be called explicitly (this is compiler error E0040). However, the mem::drop function in the prelude can be used to call the argument’s Drop implementation.

When this method has been called, self has not yet been deallocated. That only happens after the method is over. If this wasn’t the case, self would be a dangling reference.

§Panics

Implementations should generally avoid panic!ing, because drop() may itself be called during unwinding due to a panic, and if the drop() panics in that situation (a “double panic”), this will likely abort the program. It is possible to check panicking() first, which may be desirable for a Drop implementation that is reporting a bug of the kind “you didn’t finish using this before it was dropped”; but most types should simply clean up their owned allocations or other resources and return normally from drop(), regardless of what state they are in.

Note that even if this panics, the value is considered to be dropped; you must not cause drop to be called again. This is normally automatically handled by the compiler, but when using unsafe code, can sometimes occur unintentionally, particularly when using ptr::drop_in_place.

Implementors§

1.13.0 · source§

impl Drop for CString

1.6.0 · source§

impl Drop for alloc::string::Drain<'_>

source§

impl Drop for LocalWaker

1.36.0 · source§

impl Drop for Waker

1.63.0 · source§

impl Drop for OwnedFd

source§

impl<'a, T, A> Drop for DrainSorted<'a, T, A>
where T: Ord, A: Allocator,

source§

impl<'f> Drop for VaListImpl<'f>

source§

impl<A> Drop for RepeatN<A>

1.21.0 · source§

impl<I, A> Drop for Splice<'_, I, A>
where I: Iterator, A: Allocator,

1.7.0 · source§

impl<K, V, A> Drop for BTreeMap<K, V, A>
where A: Allocator + Clone,

1.7.0 · source§

impl<K, V, A> Drop for sp_std::collections::btree_map::IntoIter<K, V, A>
where A: Allocator + Clone,

source§

impl<T> Drop for ThinBox<T>
where T: ?Sized,

source§

impl<T> Drop for MappedMutexGuard<'_, T>
where T: ?Sized,

source§

impl<T> Drop for MappedRwLockReadGuard<'_, T>
where T: ?Sized,

source§

impl<T> Drop for MappedRwLockWriteGuard<'_, T>
where T: ?Sized,

1.0.0 · source§

impl<T> Drop for MutexGuard<'_, T>
where T: ?Sized,

1.70.0 · source§

impl<T> Drop for OnceLock<T>

source§

impl<T> Drop for ReentrantLockGuard<'_, T>
where T: ?Sized,

1.0.0 · source§

impl<T> Drop for RwLockReadGuard<'_, T>
where T: ?Sized,

1.0.0 · source§

impl<T> Drop for RwLockWriteGuard<'_, T>
where T: ?Sized,

1.0.0 · source§

impl<T, A> Drop for Box<T, A>
where A: Allocator, T: ?Sized,

1.6.0 · source§

impl<T, A> Drop for sp_std::collections::vec_deque::Drain<'_, T, A>
where A: Allocator,

1.0.0 · source§

impl<T, A> Drop for VecDeque<T, A>
where A: Allocator,

1.0.0 · source§

impl<T, A> Drop for Rc<T, A>
where A: Allocator, T: ?Sized,

source§

impl<T, A> Drop for UniqueRc<T, A>
where A: Allocator, T: ?Sized,

1.4.0 · source§

impl<T, A> Drop for sp_std::rc::Weak<T, A>
where A: Allocator, T: ?Sized,

1.0.0 · source§

impl<T, A> Drop for Arc<T, A>
where A: Allocator, T: ?Sized,

1.4.0 · source§

impl<T, A> Drop for sp_std::sync::Weak<T, A>
where A: Allocator, T: ?Sized,

1.6.0 · source§

impl<T, A> Drop for sp_std::vec::Drain<'_, T, A>
where A: Allocator,

1.0.0 · source§

impl<T, A> Drop for sp_std::vec::IntoIter<T, A>
where A: Allocator,

1.0.0 · source§

impl<T, A> Drop for Vec<T, A>
where A: Allocator,

1.12.0 · source§

impl<T, A> Drop for PeekMut<'_, T, A>
where T: Ord, A: Allocator,

1.0.0 · source§

impl<T, A> Drop for LinkedList<T, A>
where A: Allocator,

1.80.0 · source§

impl<T, F> Drop for LazyLock<T, F>

source§

impl<T, F, A> Drop for ExtractIf<'_, T, F, A>
where A: Allocator, F: FnMut(&mut T) -> bool,

1.40.0 · source§

impl<T, const N: usize> Drop for core::array::iter::IntoIter<T, N>

1.0.0 · source§

impl<W> Drop for BufWriter<W>
where W: Write + ?Sized,

impl Drop for Aes128

impl Drop for Aes128Dec

impl Drop for Aes128Enc

impl Drop for Aes192

impl Drop for Aes192Dec

impl Drop for Aes192Enc

impl Drop for Aes256

impl Drop for Aes256Dec

impl Drop for Aes256Enc

impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A>

impl<T, A: Allocator> Drop for Drain<'_, T, A>

impl<T, A: Allocator> Drop for IntoIter<T, A>

impl<T, A: Allocator> Drop for Vec<T, A>

impl<T: ?Sized, A: Allocator> Drop for Box<T, A>

impl Drop for Error

impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP>

impl<T, const CAP: usize> Drop for ArrayVec<T, CAP>

impl<T, const CAP: usize> Drop for IntoIter<T, CAP>

impl<T> Drop for Receiver<T>

impl<T> Drop for Sender<T>

impl Drop for BacktraceFrameFmt<'_, '_, '_>

impl<M, T, O> Drop for BitRef<'_, M, T, O>
where M: Mutability, T: BitStore, O: BitOrder,

impl<T, O> Drop for BitBox<T, O>
where T: BitStore, O: BitOrder,

impl<T, O> Drop for BitVec<T, O>
where T: BitStore, O: BitOrder,

impl<T, O> Drop for Drain<'_, T, O>
where T: BitStore, O: BitOrder,

impl<T, O, I> Drop for Splice<'_, T, O, I>
where T: BitStore, O: BitOrder, I: Iterator<Item = bool>,

impl Drop for Bump

impl Drop for Bytes

impl Drop for BytesMut

impl<T> Drop for Injector<T>

impl Drop for Guard

impl Drop for LocalHandle

impl<T: ?Sized + Pointable> Drop for Owned<T>

impl<T> Drop for ArrayQueue<T>

impl<T> Drop for SegQueue<T>

impl Drop for WaitGroup

impl<T> Drop for AtomicCell<T>

impl<T: ?Sized> Drop for ShardedLockWriteGuard<'_, T>

impl<'a> Drop for Encoder<'a>

impl Drop for SigningKey

impl<C> Drop for BlindedScalar<C>
where C: CurveArithmetic,

impl<C> Drop for SecretKey<C>
where C: Curve,

impl Drop for Event

impl<T> Drop for FileGuard<T>
where T: Deref<Target = File>,

impl<T> Drop for Fragile<T>

impl<T> Drop for Sticky<T>

impl<'a> Drop for StorageNoopGuard<'a>

impl<A: AssetId, B: Balance, OnDrop: HandleImbalanceDrop<A, B>, OppositeOnDrop: HandleImbalanceDrop<A, B>> Drop for Imbalance<A, B, OnDrop, OppositeOnDrop>

impl<B: Balance, OnDrop: HandleImbalanceDrop<B>, OppositeOnDrop: HandleImbalanceDrop<B>> Drop for Imbalance<B, OnDrop, OppositeOnDrop>

impl<F: FilterStack<T>, T> Drop for ClearFilterGuard<F, T>

impl<F: FilterStack<T>, T> Drop for FilterStackGuard<F, T>

impl<T> Drop for Receiver<T>

impl<T> Drop for UnboundedReceiver<T>

impl<T> Drop for Receiver<T>

impl<T> Drop for Sender<T>

impl Drop for Enter

impl Drop for ThreadPool

impl<T> Drop for LocalFutureObj<'_, T>

impl Drop for Delay

impl<Fut> Drop for Shared<Fut>
where Fut: Future,

impl<Fut> Drop for FuturesUnordered<Fut>

impl<T> Drop for BiLockGuard<'_, T>

impl<T: ?Sized> Drop for MutexGuard<'_, T>

impl<T: ?Sized> Drop for MutexLockFuture<'_, T>

impl<T: ?Sized> Drop for OwnedMutexGuard<T>

impl<T: ?Sized, U: ?Sized> Drop for MappedMutexGuard<'_, T, U>

impl<T, N> Drop for GenericArrayIter<T, N>
where N: ArrayLength<T>,

impl Drop for RecvStream

impl<T, A: Allocator> Drop for RawDrain<'_, T, A>

impl<T, A: Allocator> Drop for RawIntoIter<T, A>

impl<T, A: Allocator> Drop for RawTable<T, A>

impl<'a, K, V> Drop for Drain<'a, K, V>

impl<K, V> Drop for IntoIter<K, V>

impl<K, V, S> Drop for LinkedHashMap<K, V, S>

impl<'a, T> Drop for Drain<'a, T>

impl<'a, T> Drop for ValueDrain<'a, T>

impl<T> Drop for IntoIter<T>

impl Drop for GaiFuture

impl<I, K, V, S> Drop for Splice<'_, I, K, V, S>
where I: Iterator<Item = (K, V)>, K: Hash + Eq, S: BuildHasher,

impl<'a, I> Drop for Chunk<'a, I>
where I: Iterator, I::Item: 'a,

impl<'a, K, I, F> Drop for Group<'a, K, I, F>
where I: Iterator, I::Item: 'a,

impl Drop for Client

impl<Notif> Drop for Subscription<Notif>

impl<T> Drop for Chan<T>

impl Drop for Connection

impl<'a, K, V> Drop for Drain<'a, K, V>

impl<K, V> Drop for IntoIter<K, V>

impl<K, V, S> Drop for LinkedHashMap<K, V, S>

impl<T> Drop for Connection<T>

impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> Drop for MappedReentrantMutexGuard<'a, R, G, T>

impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> Drop for ReentrantMutexGuard<'a, R, G, T>

impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T>

impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T>

impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockReadGuard<'a, R, T>

impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockWriteGuard<'a, R, T>

impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockReadGuard<'a, R, T>

impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockWriteGuard<'a, R, T>

impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Drop for RwLockUpgradableReadGuard<'a, R, T>

impl<K, V, S> Drop for LruCache<K, V, S>

impl Drop for Span

impl<'a> Drop for Log<'a>

impl Drop for Context

impl Drop for Context

impl Drop for Context

impl Drop for Socket

impl Drop for SignalFd

impl<T> Drop for OnceBox<T>

impl Drop for Db

impl Drop for Fd

impl Drop for Mmap

impl Drop for Handle

impl<'a> Drop for Drain<'a>

impl<'a, T: Ord + Send> Drop for Drain<'a, T>

impl<'a, T: Send> Drop for Drain<'a, T>

impl<'data, T: Send> Drop for Drain<'data, T>

impl Drop for ThreadPool

impl Drop for Ast

impl Drop for ClassSet

impl Drop for Hir

impl Drop for PerfContext

impl Drop for DBPath

impl Drop for Options

impl Drop for ReadOptions

impl<'a> Drop for BoundColumnFamily<'a>

impl<'a> Drop for DBPinnableSlice<'a>

impl<'a> Drop for SstFileWriter<'a>

impl<'a, D: DBAccess> Drop for DBRawIteratorWithThreadMode<'a, D>

impl<'a, D: DBAccess> Drop for SnapshotWithThreadMode<'a, D>

impl<'db> Drop for Checkpoint<'db>

impl<'db, DB> Drop for Transaction<'db, DB>

impl<T: ThreadMode> Drop for TransactionDB<T>

impl<T: ThreadMode, I: DBInner> Drop for DBCommon<T, I>

impl<const TRANSACTION: bool> Drop for WriteBatchWithTransaction<TRANSACTION>

impl Drop for SafeString

impl Drop for SafeVec

impl Drop for AeadKey

impl Drop for Tag

impl Drop for OkmBlock

impl<Block: BlockT> Drop for UnpinHandleInner<Block>

impl<B: BlockT> Drop for RefTrackingState<B>

impl<'a, T> Drop for SharedDataLocked<'a, T>

impl<B: BlockT> Drop for BasicQueue<B>

impl Drop for SecretKey

impl Drop for Server

impl<'a, T> Drop for ReadySinkEvent<'a, T>

impl<M, R> Drop for Receiver<M, R>
where R: Unsubscribe,

impl<'a, K, V, L, S> Drop for Drain<'a, K, V, L, S>
where K: PartialEq + Hash, S: BuildHasher, L: Limiter<K, V>,

impl Drop for Keypair

impl<T, F, S> Drop for ScopeGuard<T, F, S>
where F: FnOnce(T), S: Strategy,

impl<C: Context> Drop for Secp256k1<C>

impl<S> Drop for Secret<S>
where S: Zeroize,

impl<T> Drop for SendWrapper<T>

impl<'a, T, C> Drop for Ref<'a, T, C>
where T: Clear + Default, C: Config,

impl<'a, T, C> Drop for RefMut<'a, T, C>
where T: Clear + Default, C: Config,

impl<'a, T, C: Config> Drop for Entry<'a, T, C>

impl<T, C> Drop for OwnedRef<T, C>
where T: Clear + Default, C: Config,

impl<T, C> Drop for OwnedRefMut<T, C>
where T: Clear + Default, C: Config,

impl<T, C> Drop for OwnedEntry<T, C>
where C: Config,

impl<'a, T: 'a + Array> Drop for Drain<'a, T>

impl<A: Array> Drop for IntoIter<A>

impl<A: Array> Drop for SmallVec<A>

impl<W: Write> Drop for FrameEncoder<W>

impl Drop for Pair

impl<F: FnOnce()> Drop for DeferGuard<F>

impl Drop for AbortGuard

impl<'a, 'b, L: Lockable> Drop for StorageLockGuard<'a, 'b, L>

impl<'a, B, H, Exec> Drop for StateMachine<'a, B, H, Exec>
where H: Hasher, B: Backend<H>,

impl<H: Hasher> Drop for LocalTrieCache<H>

impl<T, R> Drop for Once<T, R>

impl Drop for Spinner

impl<T, G> Drop for Lazy<T, G>

impl<T, G> Drop for LockedLazy<T, G>

impl<T, G> Drop for UnSyncLazy<T, G>

impl<T, G> Drop for UnSyncLockedLazy<T, G>

impl Drop for TempDir

impl Drop for TempPath

impl<T: Send> Drop for ThreadLocal<T>

impl<'p, 's, T: Default> Drop for SliceVecDrain<'p, 's, T>

impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop for ArrayVecSplice<'p, A, I>

impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop for TinyVecSplice<'p, A, I>

impl Drop for Runtime

impl Drop for Notified<'_>

impl Drop for SemaphorePermit<'_>

impl Drop for AbortHandle

impl Drop for LocalSet

impl<'a, T: ?Sized> Drop for MappedMutexGuard<'a, T>

impl<'a, T: ?Sized> Drop for RwLockMappedWriteGuard<'a, T>

impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T>

impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T>

impl<T> Drop for Receiver<T>

impl<T> Drop for Sender<T>

impl<T> Drop for OwnedPermit<T>

impl<T> Drop for Permit<'_, T>

impl<T> Drop for PermitIterator<'_, T>

impl<T> Drop for WeakSender<T>

impl<T> Drop for WeakUnboundedSender<T>

impl<T> Drop for Receiver<T>

impl<T> Drop for Sender<T>

impl<T> Drop for OnceCell<T>

impl<T> Drop for Receiver<T>

impl<T> Drop for Sender<T>

impl<T> Drop for JoinHandle<T>

impl<T> Drop for JoinSet<T>

impl<T: 'static, F> Drop for TaskLocalFuture<T, F>

impl<T: AsRawFd> Drop for AsyncFd<T>

impl<T: ?Sized> Drop for MutexGuard<'_, T>

impl<T: ?Sized> Drop for OwnedMutexGuard<T>

impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U>

impl<T: ?Sized, U: ?Sized> Drop for OwnedRwLockMappedWriteGuard<T, U>

impl<T: ?Sized, U: ?Sized> Drop for OwnedRwLockReadGuard<T, U>

impl Drop for DropGuard

impl Drop for EnteredSpan

impl Drop for Span

impl<'a> Drop for Entered<'a>

impl<T> Drop for Instrumented<T>

impl<'a, L> Drop for TrieDBMut<'a, L>
where L: TrieLayout,

impl<'a, T> Drop for Locked<'a, T>

impl<'a> Drop for PathSegmentsMut<'a>

impl<'a> Drop for UrlQuery<'a>

impl<F: FnMut(&str)> Drop for LossyDecoder<F>

impl Drop for Taker

impl Drop for JsValue

impl<T> Drop for Closure<T>
where T: ?Sized,

impl Drop for Delay

impl Drop for Timer

impl<T> Drop for Store<T>

impl Drop for CodeMemory

impl Drop for JitDumpFile

impl Drop for Table

impl Drop for Mmap

impl Drop for VMExternRef

impl<T> Drop for Connection<T>

impl<Z> Drop for Zeroizing<Z>
where Z: Zeroize,

impl<W, F> Drop for AutoFlushDecoder<'_, W, F>
where W: Write, F: FnMut(Result<()>),

impl<W: Write, F: FnMut(Result<W>)> Drop for AutoFinishEncoder<'_, W, F>

impl Drop for DCtx<'_>

impl<'a> Drop for CCtx<'a>

impl<'a> Drop for CDict<'a>

impl<'a> Drop for DDict<'a>