diff options
| author | bors <bors@rust-lang.org> | 2019-03-12 18:58:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-03-12 18:58:23 +0000 |
| commit | 7c19e1eed5418b8c02be65d678417b241ee01a3e (patch) | |
| tree | 10833a99ac6f165ef304c60f3c8b835c344884e4 /src | |
| parent | d06a020e2b100d8a22252d8877783d8869e5a9ad (diff) | |
| parent | db99a3bccdc21e80d832b061defe1002527c1c46 (diff) | |
| download | rust-7c19e1eed5418b8c02be65d678417b241ee01a3e.tar.gz rust-7c19e1eed5418b8c02be65d678417b241ee01a3e.zip | |
Auto merge of #58015 - icefoxen:tryfrom-docs, r=SimonSapin
Expand docs for `TryFrom` and `TryInto`. The examples are still lacking for now, both for module docs and for methods/impl's. Will be adding those in further pushes. Should hopefully resolve the doc concern in #33417 when finished?
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/convert.rs | 66 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 12 |
2 files changed, 72 insertions, 6 deletions
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 5ecfa9cde03..774d648558b 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -361,11 +361,17 @@ pub trait From<T>: Sized { /// An attempted conversion that consumes `self`, which may or may not be /// expensive. /// -/// 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. For more information on this, -/// see the documentation for [`Into`]. +/// Library authors should usually 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. For more information on this, see the +/// documentation for [`Into`]. +/// +/// # Implementing `TryInto` +/// +/// This suffers the same restrictions and reasoning as implementing +/// [`Into`], see there for details. /// /// [`TryFrom`]: trait.TryFrom.html /// [`Into`]: trait.Into.html @@ -380,7 +386,55 @@ pub trait TryInto<T>: Sized { fn try_into(self) -> Result<T, Self::Error>; } -/// Attempt to construct `Self` via a conversion. +/// Simple and safe type conversions that may fail in a controlled +/// way under some circumstances. It is the reciprocal of [`TryInto`]. +/// +/// This is useful when you are doing a type conversion that may +/// trivially succeed but may also need special handling. +/// For example, there is no way to convert an `i64` into an `i32` +/// using the [`From`] trait, because an `i64` may contain a value +/// that an `i32` cannot represent and so the conversion would lose data. +/// This might be handled by truncating the `i64` to an `i32` (essentially +/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning +/// `i32::MAX`, or by some other method. The `From` trait is intended +/// for perfect conversions, so the `TryFrom` trait informs the +/// programmer when a type conversion could go bad and lets them +/// decide how to handle it. +/// +/// # Generic Implementations +/// +/// - `TryFrom<T> for U` implies [`TryInto<U>`]` for T` +/// - [`try_from`] is reflexive, which means that `TryFrom<T> for T` +/// is implemented and cannot fail -- the associated `Error` type for +/// calling `T::try_from()` on a value of type `T` is `Infallible`. +/// When the `!` type is stablized `Infallible` and `!` will be +/// equivalent. +/// +/// # Examples +/// +/// As described, [`i32`] implements `TryFrom<i64>`: +/// +/// ``` +/// use std::convert::TryFrom; +/// +/// let big_number = 1_000_000_000_000i64; +/// // Silently truncates `big_number`, requires detecting +/// // and handling the truncation after the fact. +/// let smaller_number = big_number as i32; +/// assert_eq!(smaller_number, -727379968); +/// +/// // Returns an error because `big_number` is too big to +/// // fit in an `i32`. +/// let try_smaller_number = i32::try_from(big_number); +/// assert!(try_smaller_number.is_err()); +/// +/// // Returns `Ok(3)`. +/// let try_successful_smaller_number = i32::try_from(3); +/// assert!(try_successful_smaller_number.is_ok()); +/// ``` +/// +/// [`try_from`]: trait.TryFrom.html#tymethod.try_from +/// [`TryInto`]: trait.TryInto.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 98b5fcd3ee4..fb40bccee6a 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4442,6 +4442,9 @@ macro_rules! try_from_unbounded { impl TryFrom<$source> for $target { type Error = TryFromIntError; + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. #[inline] fn try_from(value: $source) -> Result<Self, Self::Error> { Ok(value as $target) @@ -4457,6 +4460,9 @@ macro_rules! try_from_lower_bounded { impl TryFrom<$source> for $target { type Error = TryFromIntError; + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. #[inline] fn try_from(u: $source) -> Result<$target, TryFromIntError> { if u >= 0 { @@ -4476,6 +4482,9 @@ macro_rules! try_from_upper_bounded { impl TryFrom<$source> for $target { type Error = TryFromIntError; + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. #[inline] fn try_from(u: $source) -> Result<$target, TryFromIntError> { if u > (<$target>::max_value() as $source) { @@ -4495,6 +4504,9 @@ macro_rules! try_from_both_bounded { impl TryFrom<$source> for $target { type Error = TryFromIntError; + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. #[inline] fn try_from(u: $source) -> Result<$target, TryFromIntError> { let min = <$target>::min_value() as $source; |
