Hi
So the other day while reading 1.63 release blog I noticed the inclusion of scoped types. By my understanding the reason we need to have scopes rather than a threadHandle, that waits until the appropriate thread is finished when dropped is because of the ability to forget in std::mem - Rust. As discussed in the nomicon Leaking - The Rustonomicon section we in general need to assume that a drop call may not happen. This as discussed in the nomicon leads to several complications when designing certain types. This lead to me wondering if there was a way to create types that gets around this issue.
So here's the idea:
We add a new auto trait
auto trait Forgettable {}
Which is implemented for all base types. I will call types which are T : !Forgettable
a unforgettable type and make it undefined behavior to completely forget a unforgettable type (may still need it for unforgettable types in certain cases).
We also modify std's forget function into two functions (also need to alter some other std::mem functions in similar ways)
fn forget<T: Forgettable>(t:T) {
// safe as T is forgettable
unsafe { forget_unchecked(t) }
}
unsafe fn forget_unchecked<T>(t: T) {
// same as current forget
// ...
}
With the above implemented then I believe we have a Rust in which if a type T
is unforgettable then there are four possible scenarios in regard to its destruction in safe code:
- Drop is called on
T
. -
T
lasts forever e.g. memory leak. -
T
is decomposed into its component parts. -
T
is transformed with something like safe transmute.
Case 4 I assume if this was ever fully implemented will have a way to restrict such an ability for our type.
Case 3 can be managed with controlling access to our types and being careful with the methods we write for types.
Case 2 isn't avoidable I believe but if the type lasts forever it can be reflected by including a lifetime in the type. As this lifetime must be larger than the lifetime of T
itself it should then become the 'static
lifetime in the case (not 100% on this point, please correct me if incorrect) which can then be used in the bounds. (see scope
type in std::thread for an example of this lifetime trick).
Case 1 is the case we want.
As such we can therefore write types which offer much greater guarantees and control in regards to how the are destroyed.
So is this actually possible or have I made a mistake somewhere. Any feedback or corrections to misunderstandings I've made would be appreciated.
Thanks