@@ -478,6 +478,40 @@ pub trait Into<T>: Sized {
478
478
/// - `From<T> for U` implies [`Into`]`<U> for T`
479
479
/// - `From` is reflexive, which means that `From<T> for T` is implemented
480
480
///
481
+ /// # When to implement `From`
482
+ ///
483
+ /// While there's no technical restrictions on which conversions can be done using
484
+ /// a `From` implementation, the general expectation is that the conversions
485
+ /// should typically be restricted as follows:
486
+ ///
487
+ /// * The conversion is *lossless*: it cannot fail and it's possible to recover
488
+ /// the original value. For example, `i32: From<u16>` exists, where the original
489
+ /// value can be recovered using `u16: TryFrom<i32>`. And `String: From<&str>`
490
+ /// exists, where you can get something equivalent to the original value via
491
+ /// `Deref`. But `From` cannot be used to convert from `u32` to `u16`, since
492
+ /// that cannot succeed in a lossless way.
493
+ ///
494
+ /// * The conversion is *value-preserving*: the conceptual kind and meaning of
495
+ /// the resulting value is the same, even though the Rust type and technical
496
+ /// representation might be different. For example `-1_i8 as u8` is *lossless*,
497
+ /// since `as` casting back can recover the original value, but that conversion
498
+ /// is *not* available via `From` because `-1` and `255` are different conceptual
499
+ /// values (despite being identical bit patterns technically). But
500
+ /// `f32: From<i16>` *is* available because `1_i16` and `1.0_f32` are conceptually
501
+ /// the same real number (despite having very different bit patterns technically).
502
+ /// `String: From<char>` is available because they're both *text*, but
503
+ /// `String: From<u32>` is *not* available, since `1` (a number) and `"1"`
504
+ /// (text) are too different. (Converting values to text is instead covered
505
+ /// by the [`Display`](crate::fmt::Display) trait.)
506
+ ///
507
+ /// * The conversion is *obvious*: it's the only reasonable conversion between
508
+ /// the two types. Otherwise it's better to have it be a named method or
509
+ /// constructor, like how [`str::as_bytes`] is a method and how integers have
510
+ /// methods like [`u32::from_ne_bytes`], [`u32::from_le_bytes`], and
511
+ /// [`u32::from_be_bytes`], none of which are `From` implementations. Whereas
512
+ /// there's only one reasonable way to wrap an [`Ipv6Addr`](crate::net::Ipv6Addr)
513
+ /// into an [`IpAddr`](crate::net::IpAddr), thus `IpAddr: From<Ipv6Addr>` exists.
514
+ ///
481
515
/// # Examples
482
516
///
483
517
/// [`String`] implements `From<&str>`:
0 commit comments