Skip to main content

DropManually

Trait DropManually 

Source
pub trait DropManually<FieldTy> {
    // Required method
    fn drop_manually(_: FieldTy);
}
Expand description

The main/whole point of this whole crate and design: to expose owned access to a FieldTy when drop glue is being run.

  1. A SafeManuallyDrop<FieldTy, ContainingType>,
  2. with a (mandatory) impl DropManually<FieldTy> for ContainingType {,
  3. once it gets dropped / during its drop glue (e.g., from within a ContainingType),
  4. shall be running the DropManually::drop_manually() logic on that owned FieldTy.
use ::safe_manually_drop::SafeManuallyDrop;

struct Frobnicator {
    // …
}

struct Example {
    //    ^
    //    +--------------------------------+
    //                                     |
    string: SafeManuallyDrop<Frobnicator, Self>,
} //                                       |
//                                         +-------------vvvvvvv
impl ::safe_manually_drop::DropManually<Frobnicator> for Example {
    fn drop_manually(owned_frobnicator: Frobnicator) {
        //  owned access! 👆
        stuff(owned_frobnicator)
    }
}

In practice, this becomes the handy, 0-runtime-overhead, non-unsafe, tool to get owned access to a struct’s field (or group thereof) during drop glue.

Indeed, the recipe then becomes:

  1. Use, instead of a field: FieldTy, a wrapped field: SafeManuallyDrop<FieldTy, ContainingType>,

    • (Usually Self can be used instead of having to spell out, verbatim, the ContainingType.)

    • (This wrapper type offers transparent Deref{,Mut}, as well as From::from() and .into() conversions.)

  2. then, provide the companion, mandatory, impl DropManually<FieldTy> for ContainingType {

  3. Profit™ from the owned access to FieldTy inside of DropManually::drop_manually()’s body.

§OverrideDropGlue” rather than PrependDropGlue

Note that this new drop glue logic for FieldTy, defined in DropManually::drop_manually(), shall supersede / override its default drop glue.

use ::safe_manually_drop::prelude::*;

pub struct MyType(SafeManuallyDrop<String, Self>);

impl DropManually<String> for MyType {
    fn drop_manually(s: String) {
        // Notice the fully owned access to `s`.
        stuff(s)
        // Notably, if `s` is not moved out / "consumed",
        // then `s`' own drop glue (e.g., here, that of `String`) will be automagically
        // *implicitly* invoked when `s` goes out of scope at the end of the block.
        //
        // This may appear rather similar to the classic `Drop` trait, but there is
        // a huge difference: this function body had to *allow* for the implicit
        // drop and fall-out-of-scope to happen, by not having *consumed* the owned
        // `s: String` in some other way.
        //
        // To illustrate, the body could very well, for instance, `mem::forget(s)`,
        // and no `drop` of the `string` would happen, which is not something
        // *directly* doable with the `Drop` trait.
    }
}

fn example(it: MyType) {
    drop(it); // invokes the drop glue of `MyType`,
              // including the `Drop` impl `for SafeManuallyDrop<String, MyType>`
              // i.e., `<MyType as DropManually<String>>::drop_manually()`.
}

For instance: if, inside of DropManually::drop_manually(), the FieldTy is ::core::mem::forget()ten, then FieldTy’s own drop glue shall never actually run, much like when a ManuallyDrop<FieldTy> is drop()-ped/discarded.

With that being said, precisely because DropManually::drop_manually() receives an owned instance of FieldTy, this behavior is rather “opt-out”: that FieldTy owned instance runs out of scope when the function completes, so it will almost always get “dropped” / have its own drop glue being invoked.

The only exceptions are then when other, ownership-consuming, functions, get called on this value.

Typically:

  • ::core::mem::forget() to skip/bypass all of the drop glue altogether.
  • an impl FnOnce() getting called (the ()-call consumes ownership);
  • an owned argument S is fed to a function, such as S in an impl FnOnce(S);
  • types using owned type-state patterns, most notably Transaction::{commit,roll_back}().

Required Methods§

Source

fn drop_manually(_: FieldTy)

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§