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.
[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.