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.
- A
SafeManuallyDrop<FieldTy, ContainingType>, - with a (mandatory)
impl DropManually<FieldTy> for ContainingType {, - once it gets dropped / during its drop glue (e.g., from within a
ContainingType), - shall be running the
DropManually::drop_manually()logic on that ownedFieldTy.
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:
-
Use, instead of a
field: FieldTy, a wrappedfield: SafeManuallyDrop<FieldTy, ContainingType>,-
(Usually
Selfcan be used instead of having to spell out, verbatim, theContainingType.) -
(This wrapper type offers transparent
Deref{,Mut}, as well asFrom::from()and “.into()” conversions.)
-
-
then, provide the companion, mandatory,
impl DropManually<FieldTy> for ContainingType { -
Profit™ from the owned access to
FieldTyinside ofDropManually::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.- note that a direct
ManuallyDrop<FieldTy>would probably be better in this instance;
- note that a direct
- an
impl FnOnce()getting called (the()-call consumes ownership); - an owned argument
Sis fed to a function, such asSin animpl FnOnce(S); - types using owned type-state patterns, most notably
Transaction::{commit,roll_back}().
Required Methods§
fn drop_manually(_: FieldTy)
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".