Skip to content

Commit 9bf28e0

Browse files
authored
Rollup merge of rust-lang#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 rust-lang#33417 when finished?
2 parents 7e001e5 + 5dce719 commit 9bf28e0

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-6
lines changed

src/libcore/convert.rs

+61-6
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,17 @@ pub trait From<T>: Sized {
361361
/// An attempted conversion that consumes `self`, which may or may not be
362362
/// expensive.
363363
///
364-
/// Library authors should not directly implement this trait, but should prefer
365-
/// implementing the [`TryFrom`] trait, which offers greater flexibility and
366-
/// provides an equivalent `TryInto` implementation for free, thanks to a
367-
/// blanket implementation in the standard library. For more information on this,
368-
/// see the documentation for [`Into`].
364+
/// Library authors should usually not directly implement this trait,
365+
/// but should prefer implementing the [`TryFrom`] trait, which offers
366+
/// greater flexibility and provides an equivalent `TryInto`
367+
/// implementation for free, thanks to a blanket implementation in the
368+
/// standard library. For more information on this, see the
369+
/// documentation for [`Into`].
370+
///
371+
/// # Implementing `TryInto`
372+
///
373+
/// This suffers the same restrictions and reasoning as implementing
374+
/// [`Into`], see there for details.
369375
///
370376
/// [`TryFrom`]: trait.TryFrom.html
371377
/// [`Into`]: trait.Into.html
@@ -380,7 +386,56 @@ pub trait TryInto<T>: Sized {
380386
fn try_into(self) -> Result<T, Self::Error>;
381387
}
382388

383-
/// Attempt to construct `Self` via a conversion.
389+
/// Simple and safe type conversions that may fail in a controlled
390+
/// way under some circumstances. It is the reciprocal of [`TryInto`].
391+
///
392+
/// This is useful when you are doing a type conversion that may
393+
/// trivially succeed but may also need special handling.
394+
/// For example, there is no way to convert an `i64` into an `i32`
395+
/// using the [`From`] trait, because an `i64` may contain a value
396+
/// that an `i32` cannot represent and so the conversion would lose data.
397+
/// This might be handled by truncating the `i64` to an `i32` (essentially
398+
/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning
399+
/// `i32::MAX`, or by some other method. The `From` trait is intended
400+
/// for perfect conversions, so the `TryFrom` trait informs the
401+
/// programmer when a type conversion could go bad and lets them
402+
/// decide how to handle it.
403+
///
404+
/// # Generic Implementations
405+
///
406+
/// - `TryFrom<T> for U` implies [`TryInto<U>`]` for T`
407+
/// - [`try_from`] is reflexive, which means that `TryFrom<T> for T`
408+
/// is implemented and cannot fail -- the associated `Error` type for
409+
/// calling `T::try_from()` on a value of type `T` is `Infallible`.
410+
/// When the `!` type is stablized `Infallible` and `!` will be
411+
/// equivalent.
412+
///
413+
/// # Examples
414+
///
415+
/// As described, [`i32`] implements `TryFrom<i64>`:
416+
///
417+
/// ```
418+
/// #![feature(try_from)]
419+
/// use std::convert::TryFrom;
420+
///
421+
/// let big_number = 1_000_000_000_000i64;
422+
/// // Silently truncates `big_number`, requires detecting
423+
/// // and handling the truncation after the fact.
424+
/// let smaller_number = big_number as i32;
425+
/// assert_eq!(smaller_number, -727379968);
426+
///
427+
/// // Returns an error because `big_number` is too big to
428+
/// // fit in an `i32`.
429+
/// let try_smaller_number = i32::try_from(big_number);
430+
/// assert!(try_smaller_number.is_err());
431+
///
432+
/// // Returns `Ok(3)`.
433+
/// let try_successful_smaller_number = i32::try_from(3);
434+
/// assert!(try_successful_smaller_number.is_ok());
435+
/// ```
436+
///
437+
/// [`try_from`]: trait.TryFrom.html#tymethod.try_from
438+
/// [`TryInto`]: trait.TryInto.html
384439
#[stable(feature = "try_from", since = "1.34.0")]
385440
pub trait TryFrom<T>: Sized {
386441
/// The type returned in the event of a conversion error.

src/libcore/num/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -4544,6 +4544,9 @@ macro_rules! try_from_unbounded {
45444544
impl TryFrom<$source> for $target {
45454545
type Error = TryFromIntError;
45464546

4547+
/// Try to create the target number type from a source
4548+
/// number type. This returns an error if the source value
4549+
/// is outside of the range of the target type.
45474550
#[inline]
45484551
fn try_from(value: $source) -> Result<Self, Self::Error> {
45494552
Ok(value as $target)
@@ -4559,6 +4562,9 @@ macro_rules! try_from_lower_bounded {
45594562
impl TryFrom<$source> for $target {
45604563
type Error = TryFromIntError;
45614564

4565+
/// Try to create the target number type from a source
4566+
/// number type. This returns an error if the source value
4567+
/// is outside of the range of the target type.
45624568
#[inline]
45634569
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
45644570
if u >= 0 {
@@ -4578,6 +4584,9 @@ macro_rules! try_from_upper_bounded {
45784584
impl TryFrom<$source> for $target {
45794585
type Error = TryFromIntError;
45804586

4587+
/// Try to create the target number type from a source
4588+
/// number type. This returns an error if the source value
4589+
/// is outside of the range of the target type.
45814590
#[inline]
45824591
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
45834592
if u > (<$target>::max_value() as $source) {
@@ -4597,6 +4606,9 @@ macro_rules! try_from_both_bounded {
45974606
impl TryFrom<$source> for $target {
45984607
type Error = TryFromIntError;
45994608

4609+
/// Try to create the target number type from a source
4610+
/// number type. This returns an error if the source value
4611+
/// is outside of the range of the target type.
46004612
#[inline]
46014613
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
46024614
let min = <$target>::min_value() as $source;

0 commit comments

Comments
 (0)