diff options
| author | Mark Simulacrum <mark.simulacrum@gmail.com> | 2017-05-31 10:52:44 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-31 10:52:44 -0600 |
| commit | d5a7fd585fd3f0e98c99db74cf5071efdbd1a59a (patch) | |
| tree | 3ce1b1d7f0647e2adfc079bd61be88498e6b2444 /src/libcore | |
| parent | fd7b44b78e39c71e5049a210a0c84a8931835cc3 (diff) | |
| parent | 54bbe23b2efe238044faa2679cb318e8253f0370 (diff) | |
| download | rust-d5a7fd585fd3f0e98c99db74cf5071efdbd1a59a.tar.gz rust-d5a7fd585fd3f0e98c99db74cf5071efdbd1a59a.zip | |
Rollup merge of #42126 - clarcharr:into_docs, r=steveklabnik
Clarify docs on implementing Into. This was suggested by @dtolnay in #40380. This explicitly clarifies in what circumstances you should implement `Into` instead of `From`.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/convert.rs | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 21c75ad3395..11a360ff900 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -169,6 +169,40 @@ pub trait AsMut<T: ?Sized> { /// - [`From<T>`][From]` for U` implies `Into<U> for T` /// - [`into`] is reflexive, which means that `Into<T> 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<T>(Vec<T>); +/// impl<T> From<Wrapper<T>> for Vec<T> { +/// fn from(w: Wrapper<T>) -> Vec<T> { +/// w.0 +/// } +/// } +/// ``` +/// +/// To fix this, you can implement `Into` directly: +/// +/// ``` +/// struct Wrapper<T>(Vec<T>); +/// impl<T> Into<Vec<T>> for Wrapper<T> { +/// fn into(self) -> Vec<T> { +/// 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<Vec<u8>>`: @@ -285,9 +319,11 @@ pub trait From<T>: 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<T>: Sized { /// The type returned in the event of a conversion error. |
