Skip to content

Commit

Permalink
Add documentation to more From::from implementations.
Browse files Browse the repository at this point in the history
For users looking at documentation through IDE popups, this gives them
relevant information rather than the generic trait documentation wording
“Performs the conversion”. For users reading the documentation for a
specific type for any reason, this informs them when the conversion may
allocate or copy significant memory versus when it is always a move or
cheap copy.

Notes on specific cases:
* The new documentation for `From<T> for T` explains that it is not a
  conversion at all.
* Also documented `impl<T, U> Into<U> for T where U: From<T>`, the other
  central blanket implementation of conversion.
* I did not add documentation to conversions of a specific error type to
  a more general error type.
* I did not add documentation to unstable code.

This change was prepared by searching for the text "From<... for" and so
may have missed some cases that for whatever reason did not match. I
also looked for `Into` impls but did not find any worth documenting by
the above criteria.
  • Loading branch information
kpreid committed Dec 4, 2021
1 parent 887999d commit 6fd5cf5
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 12 deletions.
2 changes: 2 additions & 0 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,8 @@ where

#[stable(feature = "std_collections_from_array", since = "1.56.0")]
impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {
/// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`.
///
/// ```
/// use std::collections::BTreeMap;
///
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/collections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,8 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {

#[stable(feature = "std_collections_from_array", since = "1.56.0")]
impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
/// Converts a `[T; N]` into a `BTreeSet<T>`.
///
/// ```
/// use std::collections::BTreeSet;
///
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/collections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1953,6 +1953,8 @@ impl<T: Hash> Hash for LinkedList<T> {

#[stable(feature = "std_collections_from_array", since = "1.56.0")]
impl<T, const N: usize> From<[T; N]> for LinkedList<T> {
/// Converts a `[T; N]` into a `LinkedList<T>`.
///
/// ```
/// use std::collections::LinkedList;
///
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3018,6 +3018,8 @@ impl<T, A: Allocator> From<VecDeque<T, A>> for Vec<T, A> {

#[stable(feature = "std_collections_from_array", since = "1.56.0")]
impl<T, const N: usize> From<[T; N]> for VecDeque<T> {
/// Converts a `[T; N]` into a `VecDeque<T>`.
///
/// ```
/// use std::collections::VecDeque;
///
Expand Down
9 changes: 5 additions & 4 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2908,17 +2908,18 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_from_array", since = "1.44.0")]
impl<T, const N: usize> From<[T; N]> for Vec<T> {
#[cfg(not(test))]
fn from(s: [T; N]) -> Vec<T> {
<[T]>::into_vec(box s)
}
/// Allocate a `Vec<T>` and move `s`'s items into it.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]);
/// ```
#[cfg(not(test))]
fn from(s: [T; N]) -> Vec<T> {
<[T]>::into_vec(box s)
}

#[cfg(test)]
fn from(s: [T; N]) -> Vec<T> {
crate::slice::into_vec(box s)
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ impl<T: Ord + Copy> Ord for Cell<T> {
#[stable(feature = "cell_from", since = "1.12.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for Cell<T> {
/// Creates a new `Cell<T>` containing the given value.
fn from(t: T) -> Cell<T> {
Cell::new(t)
}
Expand Down Expand Up @@ -1244,6 +1245,7 @@ impl<T: ?Sized + Ord> Ord for RefCell<T> {
#[stable(feature = "cell_from", since = "1.12.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for RefCell<T> {
/// Creates a new `RefCell<T>` containing the given value.
fn from(t: T) -> RefCell<T> {
RefCell::new(t)
}
Expand Down Expand Up @@ -1986,6 +1988,7 @@ impl<T: Default> Default for UnsafeCell<T> {
#[stable(feature = "cell_from", since = "1.12.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for UnsafeCell<T> {
/// Creates a new `UnsafeCell<T>` containing the given value.
fn from(t: T) -> UnsafeCell<T> {
UnsafeCell::new(t)
}
Expand Down
5 changes: 5 additions & 0 deletions library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,10 @@ impl<T, U> Into<U> for T
where
U: From<T>,
{
/// Calls `U::from(self)`.
///
/// That is, this conversion is whatever the implementation of
/// <code>[From]&lt;T&gt; for U</code> chooses to do.
fn into(self) -> U {
U::from(self)
}
Expand All @@ -547,6 +551,7 @@ where
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for T {
/// Returns the argument unchanged.
fn from(t: T) -> T {
t
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl<T: Eq> Eq for OnceCell<T> {}

#[unstable(feature = "once_cell", issue = "74465")]
impl<T> const From<T> for OnceCell<T> {
/// Creates a new `OnceCell<T>` which already contains the given `value`.
fn from(value: T) -> Self {
OnceCell { inner: UnsafeCell::new(Some(value)) }
}
Expand Down
6 changes: 6 additions & 0 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,9 @@ impl<T: ?Sized> const From<Unique<T>> for NonNull<T> {
#[stable(feature = "nonnull", since = "1.25.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T: ?Sized> const From<&mut T> for NonNull<T> {
/// Converts a `&mut T` to a `NonNull<T>`.
///
/// This conversion is safe and infallible since references cannot be null.
#[inline]
fn from(reference: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null.
Expand All @@ -724,6 +727,9 @@ impl<T: ?Sized> const From<&mut T> for NonNull<T> {
#[stable(feature = "nonnull", since = "1.25.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T: ?Sized> const From<&T> for NonNull<T> {
/// Converts a `&T` to a `NonNull<T>`.
///
/// This conversion is safe and infallible since references cannot be null.
#[inline]
fn from(reference: &T) -> Self {
// SAFETY: A reference cannot be null, so the conditions for
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/ptr/unique.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {

#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: ?Sized> const From<&mut T> for Unique<T> {
/// Converts a `&mut T` to a `Unique<T>`.
///
/// This conversion is infallible since references cannot be null.
#[inline]
fn from(reference: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null
Expand Down
1 change: 1 addition & 0 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@ impl const From<bool> for AtomicBool {
#[stable(feature = "atomic_from", since = "1.23.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<*mut T> for AtomicPtr<T> {
/// Converts a `*mut T` into an `AtomicPtr<T>`.
#[inline]
fn from(p: *mut T) -> Self {
Self::new(p)
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/task/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl<T, E> Poll<Option<Result<T, E>>> {
#[stable(feature = "futures_api", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for Poll<T> {
/// Convert to a `Ready` variant.
/// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`.
///
/// # Example
///
Expand Down
11 changes: 11 additions & 0 deletions library/std/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,8 @@ impl Borrow<CStr> for CString {

#[stable(feature = "cstring_from_cow_cstr", since = "1.28.0")]
impl<'a> From<Cow<'a, CStr>> for CString {
/// Converts a `Cow<'a, CStr>` into a `CString`, by copying the contents if they are
/// borrowed.
#[inline]
fn from(s: Cow<'a, CStr>) -> Self {
s.into_owned()
Expand All @@ -856,6 +858,8 @@ impl<'a> From<Cow<'a, CStr>> for CString {

#[stable(feature = "box_from_c_str", since = "1.17.0")]
impl From<&CStr> for Box<CStr> {
/// Converts a `&CStr` into a `Box<CStr>`,
/// by copying the contents into a newly allocated [`Box`].
fn from(s: &CStr) -> Box<CStr> {
let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
Expand All @@ -864,6 +868,8 @@ impl From<&CStr> for Box<CStr> {

#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, CStr>> for Box<CStr> {
/// Converts a `Cow<'a, CStr>` into a `Box<CStr>`,
/// by copying the contents if they are borrowed.
#[inline]
fn from(cow: Cow<'_, CStr>) -> Box<CStr> {
match cow {
Expand Down Expand Up @@ -960,6 +966,8 @@ impl From<CString> for Arc<CStr> {

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<&CStr> for Arc<CStr> {
/// Converts a `&CStr` into a `Arc<CStr>`,
/// by copying the contents into a newly allocated [`Arc`].
#[inline]
fn from(s: &CStr) -> Arc<CStr> {
let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul());
Expand All @@ -979,6 +987,8 @@ impl From<CString> for Rc<CStr> {

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<&CStr> for Rc<CStr> {
/// Converts a `&CStr` into a `Rc<CStr>`,
/// by copying the contents into a newly allocated [`Rc`].
#[inline]
fn from(s: &CStr) -> Rc<CStr> {
let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul());
Expand Down Expand Up @@ -1504,6 +1514,7 @@ impl ToOwned for CStr {

#[stable(feature = "cstring_asref", since = "1.7.0")]
impl From<&CStr> for CString {
/// Copies the contents of the `&CStr` into a newly allocated `CString`.
fn from(s: &CStr) -> CString {
s.to_owned()
}
Expand Down
12 changes: 12 additions & 0 deletions library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ impl From<String> for OsString {

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
/// Copies any value implementing <code>[AsRef]&lt;[OsStr]&gt;</code>
/// into a newly allocated [`OsString`].
fn from(s: &T) -> OsString {
s.as_ref().to_os_string()
}
Expand Down Expand Up @@ -861,6 +863,7 @@ impl OsStr {

#[stable(feature = "box_from_os_str", since = "1.17.0")]
impl From<&OsStr> for Box<OsStr> {
/// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
#[inline]
fn from(s: &OsStr) -> Box<OsStr> {
let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
Expand All @@ -870,6 +873,8 @@ impl From<&OsStr> for Box<OsStr> {

#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, OsStr>> for Box<OsStr> {
/// Converts a `Cow<'a, OsStr>` into a <code>[Box]&lt;[OsStr]&gt;</code>,
/// by copying the contents if they are borrowed.
#[inline]
fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
match cow {
Expand Down Expand Up @@ -918,6 +923,7 @@ impl From<OsString> for Arc<OsStr> {

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<&OsStr> for Arc<OsStr> {
/// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
#[inline]
fn from(s: &OsStr) -> Arc<OsStr> {
let arc = s.inner.into_arc();
Expand All @@ -937,6 +943,7 @@ impl From<OsString> for Rc<OsStr> {

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<&OsStr> for Rc<OsStr> {
/// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
#[inline]
fn from(s: &OsStr) -> Rc<OsStr> {
let rc = s.inner.into_rc();
Expand All @@ -946,6 +953,7 @@ impl From<&OsStr> for Rc<OsStr> {

#[stable(feature = "cow_from_osstr", since = "1.28.0")]
impl<'a> From<OsString> for Cow<'a, OsStr> {
/// Moves the string into a [`Cow::Owned`].
#[inline]
fn from(s: OsString) -> Cow<'a, OsStr> {
Cow::Owned(s)
Expand All @@ -954,6 +962,7 @@ impl<'a> From<OsString> for Cow<'a, OsStr> {

#[stable(feature = "cow_from_osstr", since = "1.28.0")]
impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
/// Converts the string reference into a [`Cow::Borrowed`].
#[inline]
fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
Cow::Borrowed(s)
Expand All @@ -962,6 +971,7 @@ impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {

#[stable(feature = "cow_from_osstr", since = "1.28.0")]
impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
/// Converts the string reference into a [`Cow::Borrowed`].
#[inline]
fn from(s: &'a OsString) -> Cow<'a, OsStr> {
Cow::Borrowed(s.as_os_str())
Expand All @@ -970,6 +980,8 @@ impl<'a> From<&'a OsString> for Cow<'a, OsStr> {

#[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
impl<'a> From<Cow<'a, OsStr>> for OsString {
/// Converts a `Cow<'a, OsStr>` into an [`OsString`],
/// by copying the contents if they are borrowed.
#[inline]
fn from(s: Cow<'a, OsStr>) -> Self {
s.into_owned()
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ impl From<Cow<'_, Path>> for Box<Path> {

#[stable(feature = "path_buf_from_box", since = "1.18.0")]
impl From<Box<Path>> for PathBuf {
/// Converts a `Box<Path>` into a `PathBuf`
/// Converts a <code>[Box]&lt;[Path]&gt;</code> into a [`PathBuf`].
///
/// This conversion does not allocate or copy memory.
#[inline]
Expand All @@ -1592,7 +1592,7 @@ impl From<Box<Path>> for PathBuf {

#[stable(feature = "box_from_path_buf", since = "1.20.0")]
impl From<PathBuf> for Box<Path> {
/// Converts a `PathBuf` into a `Box<Path>`
/// Converts a [`PathBuf`] into a <code>[Box]&lt;[Path]&gt;</code>.
///
/// This conversion currently should not allocate memory,
/// but this behavior is not guaranteed on all platforms or in all future versions.
Expand All @@ -1612,7 +1612,7 @@ impl Clone for Box<Path> {

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf {
/// Converts a borrowed `OsStr` to a `PathBuf`.
/// Converts a borrowed [`OsStr`] to a [`PathBuf`].
///
/// Allocates a [`PathBuf`] and copies the data into it.
#[inline]
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ impl fmt::Debug for Stdio {

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<ChildStdin> for Stdio {
/// Converts a `ChildStdin` into a `Stdio`
/// Converts a [`ChildStdin`] into a [`Stdio`].
///
/// # Examples
///
Expand Down Expand Up @@ -1318,7 +1318,7 @@ impl From<ChildStdin> for Stdio {

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<ChildStdout> for Stdio {
/// Converts a `ChildStdout` into a `Stdio`
/// Converts a [`ChildStdout`] into a [`Stdio`].
///
/// # Examples
///
Expand Down Expand Up @@ -1347,7 +1347,7 @@ impl From<ChildStdout> for Stdio {

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<ChildStderr> for Stdio {
/// Converts a `ChildStderr` into a `Stdio`
/// Converts a [`ChildStderr`] into a [`Stdio`].
///
/// # Examples
///
Expand Down Expand Up @@ -1378,7 +1378,7 @@ impl From<ChildStderr> for Stdio {

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<fs::File> for Stdio {
/// Converts a `File` into a `Stdio`
/// Converts a [`File`](fs::File) into a [`Stdio`].
///
/// # Examples
///
Expand Down

0 comments on commit 6fd5cf5

Please sign in to comment.