about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-12 18:58:23 +0000
committerbors <bors@rust-lang.org>2019-03-12 18:58:23 +0000
commit7c19e1eed5418b8c02be65d678417b241ee01a3e (patch)
tree10833a99ac6f165ef304c60f3c8b835c344884e4 /src
parentd06a020e2b100d8a22252d8877783d8869e5a9ad (diff)
parentdb99a3bccdc21e80d832b061defe1002527c1c46 (diff)
downloadrust-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.rs66
-rw-r--r--src/libcore/num/mod.rs12
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;