First thing first, as you picked up, my definition of smart pointer is a little sloppy, forgot to say "It needs to manage the caller defined type"
But,I went through your reply and I think what's happening here is that C++ and Rust has a slightly different view on how a smart pointer should behave, and that Rust seems to have a way stricter requirement on what it calls smart pointer.
One of the point you made is that in Rust, for a smart pointer T, it must implement Deref/DerefMut to &U. And by definition of the implementation of Deref/DerefMut, it must also always succeed in coercing to &U. You made a similar note for Option<&U> as well, as it is not able to always be able to deref to &U. However, I do not believe that is a strictly requirement as we can see there are examples in both C++ and Rust that breaks that rule:
- std::rc/sync::Weak - Weak Pointer does no implement Deref as they are not guarantee to be able to grab the inner U due to the possibility that the last of the Rc/Arc might have already been dropped. But it is widely considered to be smart pointer. This applies to C++ version as well.
- std::optional - You've noted that Option does not match the Deref behavior in Rust, but std::optional in C++ actually does implement * and -> overload for it. So in essence, std::optional behave way more like a pointer. Of course, we can argue if that is the right thing to do, but what I'm saying is that C++ expect smart pointer to behave like pointer (* const U), while Rust's Deref expect smart pointer to behave like references (&U).
And for a continuation of my "$0.02"
Because "Smart Pointer" ends up describing way too broadly on what it does. It is really mostly describe that you are holding a "Singular" that may have prerequisite/action on the creation of the view (e.g. MutexGuard/RefMut) and/or on the access of the element (e.g. Weak/Cow/Option<&U>) and/or on the end of access (e.g. MutexGuard/RefMut). This is why I said Rust &/&mut behave suspiciously like a smart pointer, as it has all three of those elements (e.g. share XOR mut on create, only &mut access &mut functions and new &mut only after all share/mut access dropped).
Sure, you can restrict the definition to what Rust had described, but what you really ended up is defining that T implementing Deref/DerefMut to the specification and semantic.
At this point, giving it the name "Smart Pointer" is not very useful.
And like I mentioned before, those rules you gave ended up classifying both MutexGuard and Box in the same category. One which I would actually treat more like &U, while the other I would treat more like a structure member.