Change:
The documentation for  reads, in part: This warning has sparked significant confusion, which seems to stem from there being no consensus of what actually is a "smart pointer". The warning should be either removed or rewritten in terms of well-understood properties. Relevant URLO discussions:
An alternative could be to actually define the term "smart pointer" somewhere. The reference contains a in section 4.1.13 on , but lacks a definition. However, it is at least questionable whether such a definition could reflect whether should or shouldn't be implemented and at the same time match the common understanding of the term (assuming there is one at all).
Hm from a teaching standpoint, I'd definitely agree the docs shouldn't be introducing jargon without first defining it. And in this case I'm uncertain of the benefit of introducing it at all. In Rust, is the term actually used outside of ? It may be better to directly explain what kinds of types should be implemented for and what would help "avoid confusion". That said, the fuzziness around the term "smart pointer" does allow leeway in interpretation, whereas a too strict definition may not properly reflect how is (or should be) used in practice.
Follow up: The Rust book does actually have a . And then the term is used in the next chapter on . Some quotes from the former:
Incidentally, since the inner 's implementation is sufficient.
Perhaps a better way is to describe when should or shouldn't be implemented. Then the term "smart pointer" or could (in the context of Rust) be defined as "anything that implements ", e.g. in the reference. Currently anything that implements could be seen as smart pointer (depending on how you define it). Given the warning in , this would currently be a circular definition: A smart pointer is something that implements , but should only be implemented for smart pointers. If the warning was removed, the Rust community and the Rust reference could provide a clear definition what a smart pointer (or smart reference, see link above) actually is: Something that implements .
Following my previous comment, the warning could be changed to something like: "Warning: Implementing on a data type will make this data type act like a smart pointer." Or: "turn it into a smart pointer." "This isn't always intended, e.g. when wrapping another type for other reasons."
I feel like actually writing out a definition of smart pointer could be helpful here. Something like "Implementing will often cause instances of the implementing type to be silently converted to the target type. Please consider whether this is desirable before implementing , and avoid implementing it if the distinction between the two types is important." This phrasing is awful, but maybe it captures some of what's intended?
While "smart pointer" was never a precise technical term in any language community, I think what the Deref docs are trying to get at by using the phrase is: A user/library-defined type which is generic over a type T, and which conceptually wraps a single T with indirection. So my strawman rewrite of this paragraph: would be something like this: The TRPL chapter on Smart Pointers I think is acceptable, since that intro-level writing contains a lot of similar simplifications and vague concepts that an expert user would eventually discard, but we can definitely tweak the introduction to make it clearer that "smart pointer" is not a precise term. For example, changing "We’ve already encountered a few smart pointers" to "We've already encountered a few types that could be considered smart pointers".
This is definitely an improvement, but it would be nice to elaborate some on "to avoid confusion:" How might this confusion manifest itself if is implemented improperly? There's also the question of whether any non-"pointer-like" types can reasonably implement . Is it reasonable for a newtype that enforces some property but stores its target value inline, for example: In many ways, this behaves like : It's a container for an owned value with some additional properties enforced by construction. Is this a reasonable use of or not, and how can that be made clear in the docs?
I think that's an assumption that isn't necessarily true. There have been different opinions whether a "smart pointer" needs to be generic (see also the aboved linked discussion thread ). Most prominent example is which, according to the Rust book, is a smart pointer to . If we would consider such non-generic types to not be smart pointers, it still makes sense to implement for some of them. There are several other examples such as (pointing/deref-ing to ), for example. This isn't just limited to types from the standard library but might also be applicable to other types. Introduction in : Also note that a is (much) more than a wrapper to .
Perhaps it could help to elaborate on the "confusion", rather than reference smart pointers. For example, it could discuss how any method you add to something which implements is a potential shadowing risk for something on the target. (And thus why -- which doesn't -- has a method , but -- which does -- has an associated function that's not a method.)
We discussed this in our T-libs meeting today and our consensus was that we would welcome a PR that clarifies this, but that we don't feel comfortable making a decisions regarding the discussion so far in the absence of such a PR that introduces concrete wording. We definitely agree with the general direction of clarifying when to use Deref and how it restricts your API design decisions going forward, and that we shouldn't center jargon terminology like "smart pointer".
Also relevant to the discussion: currently the standard library implements for s, including something like , which in the owned case features no pointer/indirection. In general, I find this whole warning to be a bit too opinionated and subjective, since, as we can see, it's difficult to come up with hard rules. I thus second more practical approach of: "beware that implementing and (inherent) methods can be footgunny or surprising; types that implement ought to strive not to feature other methods_".
See also Christopher Durham's attempt to define a smart pointer .
A bit more complete; here's how I currently lean towards defining a "smart pointer:" (From a crate.) Details are of course extremely fungible (and docs are still incomplete), but the main idea is that a "smart pointer" is "raw pointer + smarts," so it should be defined by conversions into/from a raw pointer. [^2]: The name is a pun on tartare being a raw meat dish. and were taken, but the connotation is still something raw which can be made safe with special care. (plz no squat) .
I've taken a crack at drafting something that I think it clearer and gives more helpful guidance: Comments very much welcome and if this direction seems good I will polish for proper review.

Discussion:
/// /// [dereferenceable types]: core::ops::Deref /// [pointed-to value]: core::ops::Deref::Target <del> /// ['`Deref` coercion']: core::ops::Deref#more-on-deref-coercion </del> <ins> /// ['`Deref` coercion']: core::ops::Deref#deref-coercion </ins> /// /// ``` /// let x = Box::new(5i32);

/// /// [mutably dereferenceable types]: core::ops::DerefMut /// [pointed-to value]: core::ops::Deref::Target <del> /// ['`Deref` coercion']: core::ops::DerefMut#more-on-deref-coercion </del> <ins> /// ['`Deref` coercion']: core::ops::DerefMut#mutable-deref-coercion </ins> /// /// ``` /// let mut x = Box::new(5i32);

/// In addition to being used for explicit dereferencing operations with the /// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly /// by the compiler in many circumstances. This mechanism is called <del> /// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used. </del> <ins> /// ["`Deref` coercion"][coercion]. In mutable contexts, [`DerefMut`] is used and /// mutable deref coercion similarly occurs. </ins> /// <del> /// Implementing `Deref` for smart pointers makes accessing the data behind them /// convenient, which is why they implement `Deref`. On the other hand, the /// rules regarding `Deref` and [`DerefMut`] were designed specifically to /// accommodate smart pointers. Because of this, **`Deref` should only be /// implemented for smart pointers** to avoid confusion. </del> <ins> /// **Warning:** Deref coercion is a powerful language feature which has /// far-reaching implications for every type that implements `Deref`. The /// compiler will silently insert calls to `Deref::deref`. For this reason, one /// should be careful about implementing `Deref` and only do so when deref /// coercion is desirable. See [below][implementing] for advice on when this is /// typically desirable or undesirable. </ins> /// <del> /// For similar reasons, **this trait should never fail**. Failure during /// dereferencing can be extremely confusing when `Deref` is invoked implicitly. </del> <ins> /// Types that implement `Deref` or `DerefMut` are often called "smart /// pointers" and the mechanism of deref coercion has been specifically designed /// to facilitate the pointer-like behaviour that name suggests. Often, the /// purpose of a "smart pointer" type is to change the ownership semantics /// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the /// storage semantics of a contained value (for example, [`Box`][box]). </ins> /// <del> /// Violating these requirements is a logic error. The behavior resulting from a logic error is not /// specified, but users of the trait must ensure that such logic errors do *not* result in /// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of this /// method. </del> <ins> /// # Deref coercion </ins> /// <del> /// # More on `Deref` coercion </del> <ins> /// If `T` implements `Deref<Target = U>`, and `v` is a value of type `T`, then: </ins> /// <del> /// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then: /// /// * In immutable contexts, `*x` (where `T` is neither a reference nor a raw pointer) ///   is equivalent to `*Deref::deref(&x)`. </del> <ins> /// * In immutable contexts, `*v` (where `T` is neither a reference nor a raw ///   pointer) is equivalent to `*Deref::deref(&v)`. </ins> /// * Values of type `&T` are coerced to values of type `&U` <del> /// * `T` implicitly implements all the (immutable) methods of the type `U`. </del> <ins> /// * `T` implicitly implements all the methods of the type `U` which take the ///   `&self` receiver. </ins> /// /// For more details, visit [the chapter in *The Rust Programming Language*][book] /// as well as the reference sections on [the dereference operator][ref-deref-op], <del> /// [method resolution] and [type coercions]. </del> <ins> /// [method resolution], and [type coercions]. /// /// # When to implement `Deref` or `DerefMut` /// /// The same advice applies to both deref traits. In general, deref traits /// **should** be implemented if: /// /// 1. a value of the type transparently behaves like a value of the target ///    type; /// 1. the implementation of the deref function is cheap; and /// 1. users of the type will not be surprised by any deref coercion behaviour. /// /// In general, deref traits **should not** be implemented if: /// /// 1. the deref implementations could fail unexpectedly; or /// 1. the type has methods that are likely to collide with methods on the ///    target type; or /// 1. committing to deref coercion as part of the public API is not desirable. /// /// Note that there's a large difference between implementing deref traits /// generically over many target types, and doing so only for specific target /// types. /// /// Generic implementations, such as for [`Box<T>`][box] (which is generic over /// every type and dereferences to `T`) should be careful to provide few or no /// methods, since the target type is unknown and therefore every method could /// collide with one on the target type, causing confusion for users. /// `impl<T> Box<T>` has no methods (though several associated functions), /// partly for this reason. /// /// Specific implementations, such as for [`String`][string] (whose `Deref` /// implementation has `Target = str`) can have many methods, since avoiding /// collision is much easier. `String` and `str` both have many methods, and /// `String` additionally behaves as if it has every method of `str` because of /// deref coercion. The implementing type may also be generic while the /// implementation is still specific in this sense; for example, [`Vec<T>`][vec] /// dereferences to `[T]`, so methods of `T` are not applicable. /// /// Consider also that deref coericion means that deref traits are a much larger /// part of a type's public API than any other trait as it is implicitly called /// by the compiler. Therefore, it is advisable to consider whether this is /// something you are comfortable supporting as a public API. /// /// The [`AsRef`] and [`Borrow`][core::borrow::Borrow] traits have very similar /// signatures to `Deref`. It may be desirable to implement either or both of /// these, whether in addition to or rather than deref traits. See their /// documentation for details. /// /// # Fallibility /// /// **This trait's method should never unexpectedly fail**. Deref coercion means /// the compiler will often insert calls to `Deref::deref` implicitly. Failure /// during dereferencing can be extremely confusing when `Deref` is invoked /// implicitly. In the majority of uses it should be infallible, though it may /// be acceptable to panic if the type is misused through programmer error, for /// example. /// /// However, infallibility is not enforced and therefore not guaranteed. /// As such, `unsafe` code should not rely on infallibility in general for /// soundness. </ins> /// /// [book]: ../../book/ch15-02-deref.html <del> /// [more]: #more-on-deref-coercion </del> <ins> /// [coercion]: #deref-coercion /// [implementing]: #when-to-implement-deref-or-derefmut </ins> /// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator /// [method resolution]: ../../reference/expressions/method-call-expr.html /// [type coercions]: ../../reference/type-coercions.html <ins> /// [box]: ../../alloc/boxed/struct.Box.html /// [string]: ../../alloc/string/struct.String.html /// [vec]: ../../alloc/vec/struct.Vec.html /// [rc]: ../../alloc/rc/struct.Rc.html /// [cow]: ../../alloc/borrow/enum.Cow.html </ins> /// /// # Examples ///

/// In addition to being used for explicit dereferencing operations with the /// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly /// by the compiler in many circumstances. This mechanism is called <del> /// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used. /// /// Implementing `DerefMut` for smart pointers makes mutating the data behind /// them convenient, which is why they implement `DerefMut`. On the other hand, /// the rules regarding [`Deref`] and `DerefMut` were designed specifically to /// accommodate smart pointers. Because of this, **`DerefMut` should only be /// implemented for smart pointers** to avoid confusion. </del> <ins> /// ["mutable deref coercion"][coercion]. In immutable contexts, [`Deref`] is used. </ins> /// <del> /// For similar reasons, **this trait should never fail**. Failure during /// dereferencing can be extremely confusing when `DerefMut` is invoked /// implicitly. </del> <ins> /// **Warning:** Deref coercion is a powerful language feature which has /// far-reaching implications for every type that implements `DerefMut`. The /// compiler will silently insert calls to `DerefMut::deref_mut`. For this /// reason, one should be careful about implementing `DerefMut` and only do so /// when mutable deref coercion is desirable. See [the `Deref` docs][implementing] /// for advice on when this is typically desirable or undesirable. </ins> /// <del> /// Violating these requirements is a logic error. The behavior resulting from a logic error is not /// specified, but users of the trait must ensure that such logic errors do *not* result in /// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of this /// method. </del> <ins> /// Types that implement `DerefMut` or `Deref` are often called "smart /// pointers" and the mechanism of deref coercion has been specifically designed /// to facilitate the pointer-like behaviour that name suggests. Often, the /// purpose of a "smart pointer" type is to change the ownership semantics /// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the /// storage semantics of a contained value (for example, [`Box`][box]). </ins> /// <del> /// # More on `Deref` coercion </del> <ins> /// # Mutable deref coercion </ins> /// <del> /// If `T` implements `DerefMut<Target = U>`, and `x` is a value of type `T`, </del> <ins> /// If `T` implements `DerefMut<Target = U>`, and `v` is a value of type `T`, </ins> /// then: /// <del> /// * In mutable contexts, `*x` (where `T` is neither a reference nor a raw pointer) ///   is equivalent to `*DerefMut::deref_mut(&mut x)`. </del> <ins> /// * In mutable contexts, `*v` (where `T` is neither a reference nor a raw pointer) ///   is equivalent to `*DerefMut::deref_mut(&mut v)`. </ins> /// * Values of type `&mut T` are coerced to values of type `&mut U` /// * `T` implicitly implements all the (mutable) methods of the type `U`. ///

/// as well as the reference sections on [the dereference operator][ref-deref-op], /// [method resolution] and [type coercions]. /// <ins> /// # Fallibility /// /// **This trait's method should never unexpectedly fail**. Deref coercion means /// the compiler will often insert calls to `DerefMut::deref_mut` implicitly. /// Failure during dereferencing can be extremely confusing when `DerefMut` is /// invoked implicitly. In the majority of uses it should be infallible, though /// it may be acceptable to panic if the type is misused through programmer /// error, for example. /// /// However, infallibility is not enforced and therefore not guaranteed. /// As such, `unsafe` code should not rely on infallibility in general for /// soundness. /// </ins> /// [book]: ../../book/ch15-02-deref.html <del> /// [more]: #more-on-deref-coercion </del> <ins> /// [coercion]: #mutable-deref-coercion /// [implementing]: Deref#when-to-implement-deref-or-derefmut </ins> /// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator /// [method resolution]: ../../reference/expressions/method-call-expr.html /// [type coercions]: ../../reference/type-coercions.html <ins> /// [box]: ../../alloc/boxed/struct.Box.html /// [string]: ../../alloc/string/struct.String.html /// [rc]: ../../alloc/rc/struct.Rc.html /// [cow]: ../../alloc/borrow/enum.Cow.html </ins> /// /// # Examples ///