What are smart pointers?

Deref's documentation certainly has added to this discussion, and I think the documentation should be fixed in either case.

However, the term "smart pointer" doesn't only appear in the context of Deref. I would even say that it's one of Rust's major peculiarities to utilize "smart pointers" such as

but also other types that might fall into this category such as

Not wanting to imply all of these should be considered smart pointers, but some for sure. No wonder, the term "smart pointer" (or the generalized term "pointer type") also appears in the reference and repeatedly pops up in discussions (which was actually the trigger that made me rise the question).

Being interested in Rust and modern computer programming languages in general, i'm interested in the used terminology, and I don't think this discussion is "moot" after Deref's doc has been fixed. (Besides, the reference uses the terminology as well.)

However, I also understand that this sort of discussion doesn't interest everyone, and that's totally fine.

Having said the above, I think it makes sense to differentiate between the two questions:

  • When and when not to implement Deref
  • What are "smart pointers"

The question when to implement Deref is an important one (and one that may be of more practical value for most people here rather than debating about "academic" terminology). In that context, the ticket created by @2e71828 contains a reference to another discussion (Understanding the perils of Deref) which I haven't read yet. It may also deserve further discussion / documentation / etc., but I meanwhile think that it's best to leave that question out when trying to define what a smart pointer is.

That said, I'm still interested in debating the issue of the terminology "smart pointer" further (for the reasons explained above), but I'm not sure if it's possible to make any progress here. I'll give it a try, however, and throw in some new (updated) hypotheses:

  • Smart pointers are entirely generic in regard to their target, which means String is not a smart pointer.
  • Smart pointers do not always provide a fail-safe (or non-blocking) dereferencing mechanism, which particularly means that Mutex and RefCell but also Weak or Option could be considered smart pointers, and also means that in not all smart pointers can implement Deref in Rust (as Deref::deref should never fail, at least in Rust).
    Note: I'm very unsure on this, and maybe in the context of Rust it makes sense to demand never-failing dereferencing, as it's also the case with ordinary references. Perhaps it makes sense to think about a term like "smart references", which demand fail-safe deref?
  • Smart pointers do not always point to values on the heap.
  • Wrappers which are intended to change the behavior of the wrapped type (newtype pattern) go beyond of what a smart pointer usually does and thus are not considered smart pointers.

I'm not sure if "storage" is the right term. When I think of storage, I think of "wrappers". A Cow::Borrow doesn't store anything. It points to something. Also the Cow::Owned points to something (but adds some "smartness" to dispose of the value when the Cow goes out of scope).

But I do like what you wrote with "the T being pointed at is far more important to the user than the fact that it's wrapped by something else." It's a bit vague though, and it might rule out Mutex and MutexGuard as it's a very important property of these that they actually perform locking.

Interesting fact. Also note that Pin<P> doesn't impose any bounds on P (only in methods / implementations).

Right now this might be an implication of Deref's documentation. But I think that should be changed (for the reasons that came up in this thread). In particular, such a definition would rule out Weak being considered a smart pointer, and it would imply that non-generic types such as String are a smart pointer (which I don't think anymore they are).