PureTryDrop

Trait PureTryDrop 

Source
pub trait PureTryDrop {
    type Error: Into<Error>;
    type FallbackTryDropStrategy: TryDropStrategy;
    type TryDropStrategy: FallibleTryDropStrategy;

    // Required methods
    fn fallback_try_drop_strategy(&self) -> &Self::FallbackTryDropStrategy;
    fn try_drop_strategy(&self) -> &Self::TryDropStrategy;
    unsafe fn try_drop(&mut self) -> Result<(), Self::Error>;

    // Provided method
    fn adapt(self) -> DropAdapter<Self>
       where Self: Sized { ... }
}
Expand description

A trait for types which can be dropped, but which may fail to do so.

This is a pure version of try drop, meaning that the drop strategies have to be explicitly specified, which means it does not depend on a global try drop strategy.

§Gotchas

Implementing this trait is not enough to make it droppable. In order for the try drop strategy to be run, you need to put your type in a DropAdapter.

An easier way to make your type droppable is to call PureTryDrop::adapt on it.

Required Associated Types§

Source

type Error: Into<Error>

The type of the error that may occur during drop.

Source

type FallbackTryDropStrategy: TryDropStrategy

The type which will be used if the drop strategy fails.

Source

type TryDropStrategy: FallibleTryDropStrategy

The type which will be used if dropping fails.

Required Methods§

Source

fn fallback_try_drop_strategy(&self) -> &Self::FallbackTryDropStrategy

Get a reference to the fallback try drop strategy.

Source

fn try_drop_strategy(&self) -> &Self::TryDropStrategy

Get a reference to the try drop strategy.

Source

unsafe fn try_drop(&mut self) -> Result<(), Self::Error>

Execute the fallible destructor for this type. This function is unsafe because if this is called outside of a Drop::drop context, once the scope of the object implementing trait ends, this function will be called twice, potentially resulting in a double-free.

Use DropAdapter to ensure that the destructor is only called once.

§Safety

The caller must ensure that this function is called within a Drop::drop context.

Provided Methods§

Source

fn adapt(self) -> DropAdapter<Self>
where Self: Sized,

Adapts this type to take advantage of the specified try drop strategies.

§Notes

If Self implements Copy, and you call this function, at first it seems like there would be a soundness hole:

use try_drop::{Infallible, PureTryDrop, TryDrop};

#[derive(Copy, Clone)]
struct T(usize);

impl TryDrop for T {
    type Error = Infallible;

    unsafe fn try_drop(&mut self) -> Result<(), Self::Error> {
        self.0 += 1;
        println!("{}", self.0);
        Ok(())
    }
}

// this is valid code and does not result in a compilation error
let t = T.adapt().adapt();

You’d think the output would be:

1
2

However, it’s actually:

1
1

This is because Self implicitly get copied. I may or may not have spent a large amount of time trying to get rid of this “soundness hole”.

Implementors§