@@ -15,50 +15,33 @@ use crate::ptr;
1515/// be exposed through a public safe API.
1616/// Correspondingly, `ManuallyDrop::drop` is unsafe.
1717///
18- /// # Examples
18+ /// # `ManuallyDrop` and drop order.
1919///
20- /// This wrapper can be used to enforce a particular drop order on fields, regardless
21- /// of how they are defined in the struct:
20+ /// Rust has a well-defined [drop order] of values. To make sure that fields or
21+ /// locals are dropped in a specific order, reorder the declarations such that
22+ /// the implicit drop order is the correct one.
2223///
23- /// ```rust
24- /// use std::mem::ManuallyDrop;
25- /// struct Peach;
26- /// struct Banana;
27- /// struct Melon;
28- /// struct FruitBox {
29- /// // Immediately clear there’s something non-trivial going on with these fields.
30- /// peach: ManuallyDrop<Peach>,
31- /// melon: Melon, // Field that’s independent of the other two.
32- /// banana: ManuallyDrop<Banana>,
33- /// }
24+ /// It is possible to use `ManuallyDrop` to control the drop order, but this
25+ /// requires unsafe code and is hard to do correctly in the presence of
26+ /// unwinding.
3427///
35- /// impl Drop for FruitBox {
36- /// fn drop(&mut self) {
37- /// unsafe {
38- /// // Explicit ordering in which field destructors are run specified in the intuitive
39- /// // location – the destructor of the structure containing the fields.
40- /// // Moreover, one can now reorder fields within the struct however much they want.
41- /// ManuallyDrop::drop(&mut self.peach);
42- /// ManuallyDrop::drop(&mut self.banana);
43- /// }
44- /// // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
45- /// // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
46- /// }
47- /// }
48- /// ```
28+ /// For example, if you want to make sure that a specific field is dropped after
29+ /// the others, make it the last field of a struct:
4930///
50- /// However, care should be taken when using this pattern as it can lead to *leak amplification*.
51- /// In this example, if the `Drop` implementation for `Peach` were to panic, the `banana` field
52- /// would also be leaked.
31+ /// ```
32+ /// struct Context;
5333///
54- /// In contrast, the automatically-generated compiler drop implementation would have ensured
55- /// that all fields are dropped even in the presence of panics. This is especially important when
56- /// working with [pinned] data, where reusing the memory without calling the destructor could lead
57- /// to Undefined Behaviour.
34+ /// struct Widget {
35+ /// children: Vec<Widget>,
36+ /// // `context` will be dropped after `children`.
37+ /// // Rust guarantees that fields are dropped in the order of declaration.
38+ /// context: Context,
39+ /// }
40+ /// ```
5841///
42+ /// [drop order]: https://doc.rust-lang.org/reference/destructors.html
5943/// [`mem::zeroed`]: crate::mem::zeroed
6044/// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
61- /// [pinned]: crate::pin
6245#[ stable( feature = "manually_drop" , since = "1.20.0" ) ]
6346#[ lang = "manually_drop" ]
6447#[ derive( Copy , Clone , Debug , Default , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
0 commit comments