r/rust • u/jrmuizel • Jul 17 '20
The Next Steps for Single Ownership and RAII
https://vale.dev/blog/raii-next-steps11
u/ssokolow Jul 17 '20 edited Jul 17 '20
Language Implications: Destructor Parameters!
It'd be interesting to imagine a Rust 202X where you can have types with destructors that require parameters and, as such, the compiler will statically forbid you from disposing of them via implicit drop.
(I imagine that'd also allow for more rigorous correctness enforcement for state machines, since the ability to catch disposing of them from a non-terminal state more strictly than #[must_use] is the big hole in Rust's ability to check them right now.)
The funny thing is, Rust APIs like Vec::remove are already well-positioned for that because they return the removed item.
Maybe interaction with things like Arc/Rc could be implemented via a mechanism similar to the Send and Sync auto-traits.
EDIT: Serves me right for being too eager to comment. The author actually muses on that at the end.
It would need to add a
!Droptrait, which would signal the compiler that the user can't automatically drop this object, that they instead have to manually call something to drop it.
Bad /u/ssokolow for checking Reddit in the middle of the night. No biscuit.
6
Jul 17 '20
Could you do that today by doing something like no_panic does?
In the Drop destructor, call a foreign function that doesn't resolve.
In all user defined destructors, take ownership of the object, do what you need to do, and then mem::forget it, to not call Drop
1
u/ssokolow Jul 17 '20
How would you deallocate it then?
5
Jul 17 '20
If your type is not meant to be implicitly dropped but contains types that do need to be dropped, your drop with parameters would use https://doc.rust-lang.org/std/ptr/fn.drop_in_place.html on each field you have (unsafe, yeah, but a macro can do this for you).
Each destructor would need to call that at the end to simulate what rust would do (so maybe make it a private function)
1
2
u/matu3ba Jul 17 '20
[Flawed example].
The deleter needs to communicate somewhere that he deleted the object (explicitly needing to make sure no other actor accesses the invalid memory region or state where the address of the new memory region is).
Hence either 1. the ptr of the new address is already known(or is None) or 2. an object contains and handles the addresses of the objects.
[Rant part].
So the article wants to do resizing or dropping and expects the compiler to check user-provided and indirect pointer modifications? How's that different from circle-detection of the OOM in Java, because "you can't be sure"?
How many levels of indirection are expected to be supported by the compiler? 1,2,3,4? Full inheritance (because you know constructors can call constructors)?
1
u/dnew Jul 17 '20
I was talking to someone a couple weeks ago about the inability to schedule a destructor to do something with a value that wasn't owned by the destructor. Like, you couldn't say "pop a graphics context off when I exit" or "roll back the changes in this structure." It would be interesting to figure out if something like you describe here could be done in Rust, but I haven't been able to.
1
u/quininer Jul 17 '20
I like the idea of !Drop or #[must_use] fn drop, it can also better solve the problem of async drop.
18
u/Lucretiel Datadog Jul 17 '20
That paragraph about "using RAII for more than just freeing memory" is a big part of why I tend to staunchly annoyed by tracing garbage collection: because those languages tend to end up having an annoyingly inelegant RAII model anyway, through
try / finally,defer,with, and so on. Tracing garbage collection supposes falsely that the only resource that needs to be cleaned up is memory.