Skip to content

Commit

Permalink
Auto merge of #58015 - icefoxen:tryfrom-docs, r=SimonSapin
Browse files Browse the repository at this point in the history
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?
  • Loading branch information
bors committed Mar 12, 2019
2 parents d06a020 + db99a3b commit 7c19e1e
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 6 deletions.
66 changes: 60 additions & 6 deletions src/libcore/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand All @@ -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) {
Expand All @@ -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;
Expand Down

0 comments on commit 7c19e1e

Please sign in to comment.