> A language where any rule like "You should always free resources in advance in case the destructor doesn't run" is captured statically by a compiler error.
This only shows up if you're specifically opting into unsafe code by using the "unsafe" keyword. Rust doesn't (yet) try to ensure safety of unsafe code, because it's unsafe. As long as you don't step into unsafe code, you can ignore this entire article.
Which unsafe code is that? In the article, I don't see any use of "unsafe" in safe_forget[1] or either main[2] in the first part of the article.
[1] Which creates a reference-counted cycle containing the thing-to-be-forgotten, ensuring the finalizer is never called.
[2] The first main simply demonstrates that the destructor is never called, which is ok in itself but causes problems when you're doing smart things in the finalizers, as in the second main, where the code uses the destructors to ensure the threads are terminated and the programmer is assuming the borrow checker is going to warn them if the threads aren't terminated.
Right. That block is unsafe because it's doing unsafe things. (ptr::read and alloc::heap::deallocate)
But the use of Rc is kind of a red herring; if mem::forget is marked safe, then you don't need safe_forget because you can forget things (fail to execute their destructors, specifically) safely anyway.
The problem is that destructors aren't guaranteed; the bugs in the thready thing (and potentially unbounded other things) are symptoms. Drop needs big, red warning signs.
The power of a notation, and a type system, is in what it lets you not think about. The fact that destructors may not be called is, unfortunately, something you have to think about.
This only shows up if you're specifically opting into unsafe code by using the "unsafe" keyword. Rust doesn't (yet) try to ensure safety of unsafe code, because it's unsafe. As long as you don't step into unsafe code, you can ignore this entire article.