> I suspect the difference is in how object lifetimes are handled & Rust's lack of a language-level concept of a constructor or a new keyword.
Object lifetimes certainly play a role. The data structure used by the shared pointer can be kept alive by a weak pointer, but you want to call the destructor of the embedded object when no more shared pointers point to it. If you just used a templated member the auto generated cleanup code would try to call the destructor when the data structure itself is disposed. That is too late if weak_ptrs where involved and you can't call the destructor manually before that without causing loads of FUN as the automated cleanup will try to destroy the object again later. With placement new the member object can be created and destroyed as needed without the language imposing any assumptions on the objects lifetime.
Object lifetimes certainly play a role. The data structure used by the shared pointer can be kept alive by a weak pointer, but you want to call the destructor of the embedded object when no more shared pointers point to it. If you just used a templated member the auto generated cleanup code would try to call the destructor when the data structure itself is disposed. That is too late if weak_ptrs where involved and you can't call the destructor manually before that without causing loads of FUN as the automated cleanup will try to destroy the object again later. With placement new the member object can be created and destroyed as needed without the language imposing any assumptions on the objects lifetime.