Smart pointers and containers are nowhere near memory safe, just enforcing their use gets you nowhere. `std::vector::operator[](size_t)` doesn't check bounds, `std::unique_ptr::operator*()` doesn't check null.
> Imo the strong point of rust is compile error if you try to use an obj after move (unlike c++ with undef behavior
The state of a value after being moved is defined by the move constructor. It is unspecified by the spec, but it's generally not undefined behavior.