Rust provides memory safe versions of them; e.g. using a unique_ptr after moving it leads to undefined behaviour. Rust also allows 100% safe references into the memory owned by those types (no possibility of accidentally returning a reference into memory that is freed).
Lastly, Rust's type system actually allows 'this value must be kept local to a thread local' to be expressed, meaning there are two shared_ptr equivalents:
- Arc (Atomic Reference Counting), which uses atomic instructions like shared_ptr
- Rc, which uses non-atomic instructions, and so has much less overhead.
Rust also has move-by-default semantics, so there's no extraneous reference counting due to implicit copying. (Which is particularly bad with the atomic instructions of shared_ptr.)