Hi dear Rustaceans, I'm new to this forum and this is the first time I participate in a discussion about language desin, so please forgive me if I made obvious mistakes.
Background
The Forget trait idea has been proposed by several people independently, including Fixing the `Drop` trait bound, Pre-Pre-RFC: Forget trait, in a reddit thread, in a review comment.
It was part of a bigger idea in most cases, and when it was independently proposed in Pre-Pre-RFC: Forget trait, comments seem to imply lacking motivation and the discusstion drifted to linear types which faded like other threads.
I recently hit a use case where Forget is valuable and I'd like to share my case with you.
Design
Forget would be an unsafe auto trait:
pub unsafe auto trait Forget { }
T is Forget when std::mem::forget is a no-op.
This means:
- Primitive types (i32, fn, pointer, shared reference, unit...) are
Forget. - A type is
Forgetif all of its components areForgetand it is notDrop.
It must not be implemented manually (not sure about this) and is a super trait of Copy.
Copy is modified to:
pub trait Copy: Clone + Forget { }
Is it just Copy?
No. Copy is opt-in. Users can choose to not implement Copy when a type is actually Forget.
Without the Forget trait, we can't tell the difference between can't implement Copy and choose not to implement Copy.
Is it just !Drop?
No. !Drop is a "super trait" of Forget. When a type has drop glue but is not Drop, it's not Forget.
Is it backwards compatible?
Looks like so to me. Copy can't be implemented on non-Forget types now.
Motivation
I was writing a 3D renderer based on wgpu. wgpu, like any other graphics libraries, exposes interfaces accepting raw &[u8] buffers and a type descriptor (for example IndexFormat). My abstraction for this is type_erased_vec - Rust.
A type T can be put into TypeErasedVec when it's Forget, because the Drop implementation of TypeErasedVec lacks type information and doesn't run T's destructor.
Now I used the bound T: Copy, which is overly restrictive as expalined before. I can't see a workaround without Forget.
I expect this situation happening often when people manage memory manually and need to know if some memory can be simply deallocated without running user code.
That's it! Any feedback will be appreciated!