diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 21c75ad339511..11a360ff900fe 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -169,6 +169,40 @@ pub trait AsMut { /// - [`From`][From]` for U` implies `Into for T` /// - [`into`] is reflexive, which means that `Into for T` is implemented /// +/// # Implementing `Into` +/// +/// There is one exception to implementing `Into`, and it's kind of esoteric. +/// If the destination type is not part of the current crate, and it uses a +/// generic variable, then you can't implement `From` directly. For example, +/// take this crate: +/// +/// ```compile_fail +/// struct Wrapper(Vec); +/// impl From> for Vec { +/// fn from(w: Wrapper) -> Vec { +/// w.0 +/// } +/// } +/// ``` +/// +/// To fix this, you can implement `Into` directly: +/// +/// ``` +/// struct Wrapper(Vec); +/// impl Into> for Wrapper { +/// fn into(self) -> Vec { +/// self.0 +/// } +/// } +/// ``` +/// +/// This won't always allow the conversion: for example, `try!` and `?` +/// always use `From`. However, in most cases, people use `Into` to do the +/// conversions, and this will allow that. +/// +/// In almost all cases, you should try to implement `From`, then fall back +/// to `Into` if `From` can't be implemented. +/// /// # Examples /// /// [`String`] implements `Into>`: @@ -285,9 +319,11 @@ pub trait From: Sized { /// Library authors should not directly implement this trait, but should prefer /// implementing the [`TryFrom`] trait, which offers greater flexibility and /// provides an equivalent `TryInto` implementation for free, thanks to a -/// blanket implementation in the standard library. +/// blanket implementation in the standard library. For more information on this, +/// see the documentation for [`Into`]. /// /// [`TryFrom`]: trait.TryFrom.html +/// [`Into`]: trait.Into.html #[unstable(feature = "try_from", issue = "33417")] pub trait TryInto: Sized { /// The type returned in the event of a conversion error.