Trait druid::piet::cairo::glib::bitflags::_core::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.

Required Methods§

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

Given that a panic! will call drop as it unwinds, any panic! in a drop implementation will likely abort.

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§

source§

impl Drop for TargetGuard<'_>

§

impl Drop for Context

§

impl Drop for Device

§

impl Drop for MappedImageSurface

§

impl Drop for Path

§

impl Drop for Pattern

§

impl Drop for RectangleList

§

impl Drop for Region

§

impl Drop for Surface

§

impl Drop for ObjectRef

§

impl Drop for PropertyNotificationFreezeGuard

§

impl Drop for EnumClass

§

impl Drop for FlagsClass

§

impl Drop for GString

§

impl Drop for IConv

§

impl Drop for SendValue

§

impl Drop for ThreadPool

§

impl Drop for Value

§

impl Drop for VariantType

§

impl Drop for HashTable

§

impl Drop for druid::piet::cairo::glib::translate::List

§

impl Drop for PtrArray

§

impl Drop for druid::piet::cairo::glib::translate::SList

1.36.0 · source§

impl Drop for Waker

1.13.0 · source§

impl Drop for CString

1.6.0 · source§

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

1.63.0 · source§

impl Drop for OwnedFd

source§

impl Drop for Error

source§

impl Drop for DefaultGuard

source§

impl Drop for EnteredSpan

source§

impl Drop for Span

§

impl Drop for ApplicationBusyGuard

§

impl Drop for ApplicationHoldGuard

§

impl Drop for Ast

A custom Drop impl is used for Ast such that it uses constant stack space but heap space proportional to the depth of the Ast.

§

impl Drop for ClassSet

A custom Drop impl is used for ClassSet such that it uses constant stack space but heap space proportional to the depth of the ClassSet.

§

impl Drop for Enter

§

impl Drop for FileAttributeInfo

§

impl Drop for FileFilterInfo

§

impl Drop for Hir

A custom Drop impl is used for HirKind such that it uses constant stack space but heap space proportional to the depth of the total Hir.

§

impl<'a> Drop for ImageSurfaceData<'a>

§

impl<'a> Drop for MainContextAcquireGuard<'a>

source§

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

§

impl<'a, T> Drop for ClassRef<'a, T>where T: IsClass,

§

impl<'a, T> Drop for InterfaceRef<'a, T>where T: IsInterface,

source§

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

§

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

source§

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

source§

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

source§

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

source§

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

source§

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

§

impl<'list> Drop for AttrIterator<'list>

§

impl<'text> Drop for ScriptIter<'text>

§

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

§

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

§

impl<A, N> Drop for Chunk<A, N>where N: ChunkLength<A>,

§

impl<A, N> Drop for SparseChunk<A, N>where N: Bits + ChunkLength<A>,

§

impl<A, T> Drop for InlineArray<A, T>

§

impl<F, O, T> Drop for GioInfallibleFuture<F, O, T>

§

impl<F, O, T, E> Drop for GioFuture<F, O, T, E>

§

impl<Fut> Drop for FuturesUnordered<Fut>

§

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

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 alloc::collections::btree::map::IntoIter<K, V, A>where A: Allocator + Clone,

source§

impl<K, V, F, A> Drop for alloc::collections::btree::map::DrainFilter<'_, K, V, F, A>where A: Allocator + Clone, F: FnMut(&K, &mut V) -> bool,

source§

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

§

impl<T> Drop for OnceBox<T>

§

impl<T> Drop for druid::piet::cairo::glib::List<T>where T: GlibPtrDefault + FromGlibPtrFull<<T as GlibPtrDefault>::GlibType> + FromGlibPtrNone<<T as GlibPtrDefault>::GlibType>,

§

impl<T> Drop for PtrSlice<T>where T: GlibPtrDefault + FromGlibPtrFull<<T as GlibPtrDefault>::GlibType> + FromGlibPtrNone<<T as GlibPtrDefault>::GlibType>,

§

impl<T> Drop for druid::piet::cairo::glib::Receiver<T>

§

impl<T> Drop for druid::piet::cairo::glib::SList<T>where T: GlibPtrDefault + FromGlibPtrFull<<T as GlibPtrDefault>::GlibType> + FromGlibPtrNone<<T as GlibPtrDefault>::GlibType>,

§

impl<T> Drop for druid::piet::cairo::glib::Sender<T>

§

impl<T> Drop for Slice<T>where T: 'static,

§

impl<T> Drop for druid::piet::cairo::glib::SyncSender<T>

§

impl<T> Drop for WeakRef<T>where T: ObjectType,

§

impl<T> Drop for ThreadGuard<T>

source§

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

1.12.0 · source§

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

source§

impl<T> Drop for LinkedList<T>

source§

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

1.4.0 · source§

impl<T> Drop for alloc::rc::Weak<T>where T: ?Sized,

source§

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

1.4.0 · source§

impl<T> Drop for alloc::sync::Weak<T>where T: ?Sized,

source§

impl<T> Drop for std::sync::mpsc::Receiver<T>

source§

impl<T> Drop for std::sync::mpsc::Sender<T>

source§

impl<T> Drop for std::sync::mpsc::SyncSender<T>

source§

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

source§

impl<T> Drop for OnceLock<T>

source§

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

source§

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

§

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

§

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

§

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

§

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

§

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

§

impl<T> Drop for Receiver<T>

§

impl<T> Drop for Receiver<T>

§

impl<T> Drop for Sender<T>

§

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

§

impl<T> Drop for UnboundedReceiver<T>

source§

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

1.6.0 · source§

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

source§

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

1.6.0 · source§

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

source§

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

source§

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

source§

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

source§

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

source§

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

§

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

§

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

source§

impl<T, F> Drop for alloc::collections::linked_list::DrainFilter<'_, T, F>where F: FnMut(&mut T) -> bool,

source§

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

source§

impl<T, F, A> Drop for alloc::collections::btree::set::DrainFilter<'_, T, F, A>where A: Allocator + Clone, F: FnMut(&T) -> bool,

source§

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

§

impl<T, MM> Drop for Boxed<T, MM>where T: 'static, MM: BoxedMemoryManager<T>,

§

impl<T, MM> Drop for druid::piet::cairo::glib::shared::Shared<T, MM>where MM: SharedMemoryManager<T>,

§

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

source§

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

source§

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

1.40.0 · source§

impl<T, const N: usize> Drop for druid::piet::cairo::glib::bitflags::_core::array::IntoIter<T, N>

source§

impl<W> Drop for BufWriter<W>where W: Write,

source§

impl<W> Drop for GzEncoder<W>where W: Write,

§

impl<W> Drop for Encoder<W>where W: Write,

§

impl<W> Drop for EncoderWriter<W>where W: Write,

§

impl<W> Drop for StreamWriter<'_, W>where W: Write,

§

impl<W> Drop for Writer<W>where W: Write,