]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #89869 - kpreid:from-doc, r=yaahc
authorMatthias Krüger <matthias.krueger@famsik.de>
Thu, 17 Feb 2022 05:29:57 +0000 (06:29 +0100)
committerGitHub <noreply@github.com>
Thu, 17 Feb 2022 05:29:57 +0000 (06:29 +0100)
Add documentation to more `From::from` implementations.

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.
* The new documentation for construction of maps and sets from arrays of keys mentions the handling of duplicates. Future work could be to do this for *all* code paths that convert an iterable to a map or set.
* 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.

15 files changed:
1  2 
library/alloc/src/collections/btree/map.rs
library/alloc/src/collections/btree/set.rs
library/alloc/src/collections/linked_list.rs
library/alloc/src/collections/vec_deque/mod.rs
library/alloc/src/vec/mod.rs
library/core/src/cell.rs
library/core/src/convert/mod.rs
library/core/src/lazy.rs
library/core/src/ptr/non_null.rs
library/core/src/ptr/unique.rs
library/core/src/sync/atomic.rs
library/std/src/ffi/c_str.rs
library/std/src/ffi/os_str.rs
library/std/src/path.rs
library/std/src/process.rs

index cdb961d4cfbc5e697ebf49635231e5959aca84a3,f015e081ea3dedc5588df99d2abd0e2db7025c12..67f5b386ecd7fd05a58f1baccabb51695e863853
@@@ -16,10 -16,7 +16,10 @@@ use super::node::{self, marker, ForceRe
  use super::search::SearchResult::*;
  
  mod entry;
 +
 +#[stable(feature = "rust1", since = "1.0.0")]
  pub use entry::{Entry, OccupiedEntry, OccupiedError, VacantEntry};
 +
  use Entry::*;
  
  /// Minimum number of elements in a node that is not a root.
@@@ -34,7 -31,7 +34,7 @@@ pub(super) const MIN_LEN: usize = node:
  // An empty map is represented either by the absence of a root node or by a
  // root node that is an empty leaf.
  
 -/// A map based on a [B-Tree].
 +/// An ordered map based on a [B-Tree].
  ///
  /// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing
  /// the amount of work performed in a search. In theory, a binary search tree (BST) is the optimal
  /// incorrect results, aborts, memory leaks, or non-termination) but will not be undefined
  /// behavior.
  ///
 +/// Iterators obtained from functions such as [`BTreeMap::iter`], [`BTreeMap::values`], or
 +/// [`BTreeMap::keys`] produce their items in order by key, and take worst-case logarithmic and
 +/// amortized constant time per item returned.
 +///
  /// [B-Tree]: https://en.wikipedia.org/wiki/B-tree
  /// [`Cell`]: core::cell::Cell
  /// [`RefCell`]: core::cell::RefCell
@@@ -1098,8 -1091,10 +1098,8 @@@ impl<K, V> BTreeMap<K, V> 
      /// ```
      /// use std::collections::BTreeMap;
      ///
 -    /// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"]
 -    ///     .iter()
 -    ///     .map(|&s| (s, 0))
 -    ///     .collect();
 +    /// let mut map: BTreeMap<&str, i32> =
 +    ///     [("Alice", 0), ("Bob", 0), ("Carol", 0), ("Cheryl", 0)].into();
      /// for (_, balance) in map.range_mut("B".."Cheryl") {
      ///     *balance += 100;
      /// }
      /// let mut count: BTreeMap<&str, usize> = BTreeMap::new();
      ///
      /// // count the number of occurrences of letters in the vec
 -    /// for x in vec!["a", "b", "a", "c", "a", "b"] {
 +    /// for x in ["a", "b", "a", "c", "a", "b"] {
      ///     *count.entry(x).or_insert(0) += 1;
      /// }
      ///
      /// let mut map: BTreeMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
      /// let evens: BTreeMap<_, _> = map.drain_filter(|k, _v| k % 2 == 0).collect();
      /// let odds = map;
 -    /// assert_eq!(evens.keys().copied().collect::<Vec<_>>(), vec![0, 2, 4, 6]);
 -    /// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), vec![1, 3, 5, 7]);
 +    /// assert_eq!(evens.keys().copied().collect::<Vec<_>>(), [0, 2, 4, 6]);
 +    /// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), [1, 3, 5, 7]);
      /// ```
      #[unstable(feature = "btree_drain_filter", issue = "70530")]
      pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F>
      pub(crate) fn bulk_build_from_sorted_iter<I>(iter: I) -> Self
      where
          K: Ord,
 -        I: Iterator<Item = (K, V)>,
 +        I: IntoIterator<Item = (K, V)>,
      {
          let mut root = Root::new();
          let mut length = 0;
 -        root.bulk_push(DedupSortedIter::new(iter), &mut length);
 +        root.bulk_push(DedupSortedIter::new(iter.into_iter()), &mut length);
          BTreeMap { root: Some(root), length }
      }
  }
@@@ -1949,7 -1944,7 +1949,7 @@@ impl<K: Ord, V> FromIterator<(K, V)> fo
  
          // use stable sort to preserve the insertion order.
          inputs.sort_by(|a, b| a.0.cmp(&b.0));
 -        BTreeMap::bulk_build_from_sorted_iter(inputs.into_iter())
 +        BTreeMap::bulk_build_from_sorted_iter(inputs)
      }
  }
  
@@@ -2052,6 -2047,8 +2052,8 @@@ wher
  
  #[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;
      ///
  
          // use stable sort to preserve the insertion order.
          arr.sort_by(|a, b| a.0.cmp(&b.0));
 -        BTreeMap::bulk_build_from_sorted_iter(core::array::IntoIter::new(arr))
 +        BTreeMap::bulk_build_from_sorted_iter(arr)
      }
  }
  
@@@ -2112,11 -2109,10 +2114,11 @@@ impl<K, V> BTreeMap<K, V> 
      /// ```
      /// use std::collections::BTreeMap;
      ///
 -    /// let mut map = BTreeMap::new();
 -    /// map.insert("a", 1);
 -    /// map.insert("b", 2);
 -    /// map.insert("c", 3);
 +    /// let mut map = BTreeMap::from([
 +    ///    ("a", 1),
 +    ///    ("b", 2),
 +    ///    ("c", 3),
 +    /// ]);
      ///
      /// // add 10 to the value if the key isn't "a"
      /// for (key, value) in map.iter_mut() {
index 31df4e98ed746884fca583ba22b16855cd476406,ec4ed85437287bcabd1b756c7d9d6b8c5629f70f..a4315be74e36c27bea4195f1d80574042e089a85
@@@ -15,7 -15,7 +15,7 @@@ use super::Recover
  
  // FIXME(conventions): implement bounded iterators
  
 -/// A set based on a B-Tree.
 +/// An ordered set based on a B-Tree.
  ///
  /// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
  /// benefits and drawbacks.
@@@ -27,9 -27,6 +27,9 @@@
  /// incorrect results, aborts, memory leaks, or non-termination) but will not be undefined
  /// behavior.
  ///
 +/// Iterators returned by [`BTreeSet::iter`] produce their items in order, and take worst-case
 +/// logarithmic and amortized constant time per item returned.
 +///
  /// [`Ord`]: core::cmp::Ord
  /// [`Cell`]: core::cell::Cell
  /// [`RefCell`]: core::cell::RefCell
@@@ -158,7 -155,7 +158,7 @@@ enum DifferenceInner<'a, T: 'a> 
          self_iter: Iter<'a, T>,
          other_set: &'a BTreeSet<T>,
      },
 -    Iterate(Iter<'a, T>), // simply produce all values in `self`
 +    Iterate(Iter<'a, T>), // simply produce all elements in `self`
  }
  
  #[stable(feature = "collection_debug", since = "1.17.0")]
@@@ -210,7 -207,7 +210,7 @@@ enum IntersectionInner<'a, T: 'a> 
          small_iter: Iter<'a, T>,
          large_set: &'a BTreeSet<T>,
      },
 -    Answer(Option<&'a T>), // return a specific value or emptiness
 +    Answer(Option<&'a T>), // return a specific element or emptiness
  }
  
  #[stable(feature = "collection_debug", since = "1.17.0")]
@@@ -298,8 -295,8 +298,8 @@@ impl<T> BTreeSet<T> 
          Range { iter: self.map.range(range) }
      }
  
 -    /// Visits the values representing the difference,
 -    /// i.e., the values that are in `self` but not in `other`,
 +    /// Visits the elements representing the difference,
 +    /// i.e., the elements that are in `self` but not in `other`,
      /// in ascending order.
      ///
      /// # Examples
          }
      }
  
 -    /// Visits the values representing the symmetric difference,
 -    /// i.e., the values that are in `self` or in `other` but not in both,
 +    /// Visits the elements representing the symmetric difference,
 +    /// i.e., the elements that are in `self` or in `other` but not in both,
      /// in ascending order.
      ///
      /// # Examples
          SymmetricDifference(MergeIterInner::new(self.iter(), other.iter()))
      }
  
 -    /// Visits the values representing the intersection,
 -    /// i.e., the values that are both in `self` and `other`,
 +    /// Visits the elements representing the intersection,
 +    /// i.e., the elements that are both in `self` and `other`,
      /// in ascending order.
      ///
      /// # Examples
          }
      }
  
 -    /// Visits the values representing the union,
 -    /// i.e., all the values in `self` or `other`, without duplicates,
 +    /// Visits the elements representing the union,
 +    /// i.e., all the elements in `self` or `other`, without duplicates,
      /// in ascending order.
      ///
      /// # Examples
          Union(MergeIterInner::new(self.iter(), other.iter()))
      }
  
 -    /// Clears the set, removing all values.
 +    /// Clears the set, removing all elements.
      ///
      /// # Examples
      ///
          self.map.clear()
      }
  
 -    /// Returns `true` if the set contains a value.
 +    /// Returns `true` if the set contains an element equal to the value.
      ///
 -    /// The value may be any borrowed form of the set's value type,
 +    /// The value may be any borrowed form of the set's element type,
      /// but the ordering on the borrowed form *must* match the
 -    /// ordering on the value type.
 +    /// ordering on the element type.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
 +    /// let set = BTreeSet::from([1, 2, 3]);
      /// assert_eq!(set.contains(&1), true);
      /// assert_eq!(set.contains(&4), false);
      /// ```
          self.map.contains_key(value)
      }
  
 -    /// Returns a reference to the value in the set, if any, that is equal to the given value.
 +    /// Returns a reference to the element in the set, if any, that is equal to
 +    /// the value.
      ///
 -    /// The value may be any borrowed form of the set's value type,
 +    /// The value may be any borrowed form of the set's element type,
      /// but the ordering on the borrowed form *must* match the
 -    /// ordering on the value type.
 +    /// ordering on the element type.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
 +    /// let set = BTreeSet::from([1, 2, 3]);
      /// assert_eq!(set.get(&2), Some(&2));
      /// assert_eq!(set.get(&4), None);
      /// ```
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let a: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
 +    /// let a = BTreeSet::from([1, 2, 3]);
      /// let mut b = BTreeSet::new();
      ///
      /// assert_eq!(a.is_disjoint(&b), true);
      }
  
      /// Returns `true` if the set is a subset of another,
 -    /// i.e., `other` contains at least all the values in `self`.
 +    /// i.e., `other` contains at least all the elements in `self`.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let sup: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
 +    /// let sup = BTreeSet::from([1, 2, 3]);
      /// let mut set = BTreeSet::new();
      ///
      /// assert_eq!(set.is_subset(&sup), true);
      }
  
      /// Returns `true` if the set is a superset of another,
 -    /// i.e., `self` contains at least all the values in `other`.
 +    /// i.e., `self` contains at least all the elements in `other`.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let sub: BTreeSet<_> = [1, 2].iter().cloned().collect();
 +    /// let sub = BTreeSet::from([1, 2]);
      /// let mut set = BTreeSet::new();
      ///
      /// assert_eq!(set.is_superset(&sub), false);
          other.is_subset(self)
      }
  
 -    /// Returns a reference to the first value in the set, if any.
 -    /// This value is always the minimum of all values in the set.
 +    /// Returns a reference to the first element in the set, if any.
 +    /// This element is always the minimum of all elements in the set.
      ///
      /// # Examples
      ///
          self.map.first_key_value().map(|(k, _)| k)
      }
  
 -    /// Returns a reference to the last value in the set, if any.
 -    /// This value is always the maximum of all values in the set.
 +    /// Returns a reference to the last element in the set, if any.
 +    /// This element is always the maximum of all elements in the set.
      ///
      /// # Examples
      ///
          self.map.last_key_value().map(|(k, _)| k)
      }
  
 -    /// Removes the first value from the set and returns it, if any.
 -    /// The first value is always the minimum value in the set.
 +    /// Removes the first element from the set and returns it, if any.
 +    /// The first element is always the minimum element in the set.
      ///
      /// # Examples
      ///
          self.map.pop_first().map(|kv| kv.0)
      }
  
 -    /// Removes the last value from the set and returns it, if any.
 -    /// The last value is always the maximum value in the set.
 +    /// Removes the last element from the set and returns it, if any.
 +    /// The last element is always the maximum element in the set.
      ///
      /// # Examples
      ///
  
      /// Adds a value to the set.
      ///
 -    /// If the set did not have this value present, `true` is returned.
 +    /// If the set did not have an equal element present, `true` is returned.
      ///
 -    /// If the set did have this value present, `false` is returned, and the
 -    /// entry is not updated. See the [module-level documentation] for more.
 +    /// If the set did have an equal element present, `false` is returned, and
 +    /// the entry is not updated. See the [module-level documentation] for more.
      ///
      /// [module-level documentation]: index.html#insert-and-complex-keys
      ///
          self.map.insert(value, ()).is_none()
      }
  
 -    /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
 -    /// one. Returns the replaced value.
 +    /// Adds a value to the set, replacing the existing element, if any, that is
 +    /// equal to the value. Returns the replaced element.
      ///
      /// # Examples
      ///
          Recover::replace(&mut self.map, value)
      }
  
 -    /// Removes a value from the set. Returns whether the value was
 -    /// present in the set.
 +    /// If the set contains an element equal to the value, removes it from the
 +    /// set and drops it. Returns whether such an element was present.
      ///
 -    /// The value may be any borrowed form of the set's value type,
 +    /// The value may be any borrowed form of the set's element type,
      /// but the ordering on the borrowed form *must* match the
 -    /// ordering on the value type.
 +    /// ordering on the element type.
      ///
      /// # Examples
      ///
          self.map.remove(value).is_some()
      }
  
 -    /// Removes and returns the value in the set, if any, that is equal to the given one.
 +    /// Removes and returns the element in the set, if any, that is equal to
 +    /// the value.
      ///
 -    /// The value may be any borrowed form of the set's value type,
 +    /// The value may be any borrowed form of the set's element type,
      /// but the ordering on the borrowed form *must* match the
 -    /// ordering on the value type.
 +    /// ordering on the element type.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let mut set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
 +    /// let mut set = BTreeSet::from([1, 2, 3]);
      /// assert_eq!(set.take(&2), Some(2));
      /// assert_eq!(set.take(&2), None);
      /// ```
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let xs = [1, 2, 3, 4, 5, 6];
 -    /// let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
 +    /// let mut set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
      /// // Keep only the even numbers.
      /// set.retain(|&k| k % 2 == 0);
      /// assert!(set.iter().eq([2, 4, 6].iter()));
          self.map.append(&mut other.map);
      }
  
 -    /// Splits the collection into two at the given value. Returns everything after the given value,
 -    /// including the value.
 +    /// Splits the collection into two at the value. Returns a new collection
 +    /// with all elements greater than or equal to the value.
      ///
      /// # Examples
      ///
          BTreeSet { map: self.map.split_off(value) }
      }
  
 -    /// Creates an iterator that visits all values in ascending order and uses a closure
 -    /// to determine if a value should be removed.
 +    /// Creates an iterator that visits all elements in ascending order and
 +    /// uses a closure to determine if an element should be removed.
      ///
 -    /// If the closure returns `true`, the value is removed from the set and yielded. If
 -    /// the closure returns `false`, or panics, the value remains in the set and will
 -    /// not be yielded.
 +    /// If the closure returns `true`, the element is removed from the set and
 +    /// yielded. If the closure returns `false`, or panics, the element remains
 +    /// in the set and will not be yielded.
      ///
 -    /// If the iterator is only partially consumed or not consumed at all, each of the
 -    /// remaining values is still subjected to the closure and removed and dropped if it
 -    /// returns `true`.
 +    /// If the iterator is only partially consumed or not consumed at all, each
 +    /// of the remaining elements is still subjected to the closure and removed
 +    /// and dropped if it returns `true`.
      ///
 -    /// It is unspecified how many more values will be subjected to the closure if a
 -    /// panic occurs in the closure, or if a panic occurs while dropping a value, or if
 -    /// the `DrainFilter` itself is leaked.
 +    /// It is unspecified how many more elements will be subjected to the
 +    /// closure if a panic occurs in the closure, or if a panic occurs while
 +    /// dropping an element, or if the `DrainFilter` itself is leaked.
      ///
      /// # Examples
      ///
          DrainFilter { pred, inner: self.map.drain_filter_inner() }
      }
  
 -    /// Gets an iterator that visits the values in the `BTreeSet` in ascending order.
 +    /// Gets an iterator that visits the elements in the `BTreeSet` in ascending
 +    /// order.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let set: BTreeSet<usize> = [1, 2, 3].iter().cloned().collect();
 +    /// let set = BTreeSet::from([1, 2, 3]);
      /// let mut set_iter = set.iter();
      /// assert_eq!(set_iter.next(), Some(&1));
      /// assert_eq!(set_iter.next(), Some(&2));
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let set: BTreeSet<usize> = [3, 1, 2].iter().cloned().collect();
 +    /// let set = BTreeSet::from([3, 1, 2]);
      /// let mut set_iter = set.iter();
      /// assert_eq!(set_iter.next(), Some(&1));
      /// assert_eq!(set_iter.next(), Some(&2));
@@@ -1097,6 -1092,8 +1097,8 @@@ impl<T: Ord> FromIterator<T> for BTreeS
  
  #[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;
      ///
  
          // use stable sort to preserve the insertion order.
          arr.sort();
 -        let iter = core::array::IntoIter::new(arr).map(|k| (k, ()));
 +        let iter = IntoIterator::into_iter(arr).map(|k| (k, ()));
          let map = BTreeMap::bulk_build_from_sorted_iter(iter);
          BTreeSet { map }
      }
@@@ -1129,7 -1126,7 +1131,7 @@@ impl<T> IntoIterator for BTreeSet<T> 
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
 +    /// let set = BTreeSet::from([1, 2, 3, 4]);
      ///
      /// let v: Vec<_> = set.into_iter().collect();
      /// assert_eq!(v, [1, 2, 3, 4]);
@@@ -1248,8 -1245,8 +1250,8 @@@ impl<T: Ord + Clone> Sub<&BTreeSet<T>> 
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
 -    /// let b: BTreeSet<_> = vec![3, 4, 5].into_iter().collect();
 +    /// let a = BTreeSet::from([1, 2, 3]);
 +    /// let b = BTreeSet::from([3, 4, 5]);
      ///
      /// let result = &a - &b;
      /// let result_vec: Vec<_> = result.into_iter().collect();
@@@ -1271,8 -1268,8 +1273,8 @@@ impl<T: Ord + Clone> BitXor<&BTreeSet<T
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
 -    /// let b: BTreeSet<_> = vec![2, 3, 4].into_iter().collect();
 +    /// let a = BTreeSet::from([1, 2, 3]);
 +    /// let b = BTreeSet::from([2, 3, 4]);
      ///
      /// let result = &a ^ &b;
      /// let result_vec: Vec<_> = result.into_iter().collect();
@@@ -1294,8 -1291,8 +1296,8 @@@ impl<T: Ord + Clone> BitAnd<&BTreeSet<T
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
 -    /// let b: BTreeSet<_> = vec![2, 3, 4].into_iter().collect();
 +    /// let a = BTreeSet::from([1, 2, 3]);
 +    /// let b = BTreeSet::from([2, 3, 4]);
      ///
      /// let result = &a & &b;
      /// let result_vec: Vec<_> = result.into_iter().collect();
@@@ -1317,8 -1314,8 +1319,8 @@@ impl<T: Ord + Clone> BitOr<&BTreeSet<T>
      /// ```
      /// use std::collections::BTreeSet;
      ///
 -    /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
 -    /// let b: BTreeSet<_> = vec![3, 4, 5].into_iter().collect();
 +    /// let a = BTreeSet::from([1, 2, 3]);
 +    /// let b = BTreeSet::from([3, 4, 5]);
      ///
      /// let result = &a | &b;
      /// let result_vec: Vec<_> = result.into_iter().collect();
index 4a07d5d4bed10aa2efb84907cde4c220a0972188,30b07c0aebe0131d8e171af28bab3bb475dbb55f..d81f24e72024d5ea7688ca30fd44e5cbffb8386b
@@@ -417,7 -417,7 +417,7 @@@ impl<T> LinkedList<T> 
      /// let list: LinkedList<u32> = LinkedList::new();
      /// ```
      #[inline]
 -    #[rustc_const_stable(feature = "const_linked_list_new", since = "1.32.0")]
 +    #[rustc_const_stable(feature = "const_linked_list_new", since = "1.39.0")]
      #[stable(feature = "rust1", since = "1.0.0")]
      #[must_use]
      pub const fn new() -> Self {
@@@ -1953,6 -1953,8 +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;
      ///
      /// assert_eq!(list1, list2);
      /// ```
      fn from(arr: [T; N]) -> Self {
 -        core::array::IntoIter::new(arr).collect()
 +        Self::from_iter(arr)
      }
  }
  
index db2ad5e8d285c60d4c01dd09741bad248a09abe8,061e2758e49855cf5798800440cecca62a6ac925..763175fc0451f07861189357e870bd8b91496e1b
@@@ -1,4 -1,4 +1,4 @@@
 -//! A double-ended queue implemented with a growable ring buffer.
 +//! A double-ended queue (deque) implemented with a growable ring buffer.
  //!
  //! This queue has *O*(1) amortized inserts and removals from both ends of the
  //! container. It also has *O*(1) indexing like a vector. The contained elements
@@@ -156,7 -156,7 +156,7 @@@ unsafe impl<#[may_dangle] T, A: Allocat
  
  #[stable(feature = "rust1", since = "1.0.0")]
  impl<T> Default for VecDeque<T> {
 -    /// Creates an empty `VecDeque<T>`.
 +    /// Creates an empty deque.
      #[inline]
      fn default() -> VecDeque<T> {
          VecDeque::new()
@@@ -483,14 -483,14 +483,14 @@@ impl<T, A: Allocator> VecDeque<T, A> 
  }
  
  impl<T> VecDeque<T> {
 -    /// Creates an empty `VecDeque`.
 +    /// Creates an empty deque.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let vector: VecDeque<u32> = VecDeque::new();
 +    /// let deque: VecDeque<u32> = VecDeque::new();
      /// ```
      #[inline]
      #[stable(feature = "rust1", since = "1.0.0")]
          VecDeque::new_in(Global)
      }
  
 -    /// Creates an empty `VecDeque` with space for at least `capacity` elements.
 +    /// Creates an empty deque with space for at least `capacity` elements.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
 +    /// let deque: VecDeque<u32> = VecDeque::with_capacity(10);
      /// ```
      #[inline]
      #[stable(feature = "rust1", since = "1.0.0")]
  }
  
  impl<T, A: Allocator> VecDeque<T, A> {
 -    /// Creates an empty `VecDeque`.
 +    /// Creates an empty deque.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let vector: VecDeque<u32> = VecDeque::new();
 +    /// let deque: VecDeque<u32> = VecDeque::new();
      /// ```
      #[inline]
      #[unstable(feature = "allocator_api", issue = "32838")]
          VecDeque::with_capacity_in(INITIAL_CAPACITY, alloc)
      }
  
 -    /// Creates an empty `VecDeque` with space for at least `capacity` elements.
 +    /// Creates an empty deque with space for at least `capacity` elements.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
 +    /// let deque: VecDeque<u32> = VecDeque::with_capacity(10);
      /// ```
      #[unstable(feature = "allocator_api", issue = "32838")]
      pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque<T, A> {
          unsafe { ptr::swap(self.ptr().add(ri), self.ptr().add(rj)) }
      }
  
 -    /// Returns the number of elements the `VecDeque` can hold without
 +    /// Returns the number of elements the deque can hold without
      /// reallocating.
      ///
      /// # Examples
      }
  
      /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
 -    /// given `VecDeque`. Does nothing if the capacity is already sufficient.
 +    /// given deque. Does nothing if the capacity is already sufficient.
      ///
      /// Note that the allocator may give the collection more space than it requests. Therefore
      /// capacity can not be relied upon to be precisely minimal. Prefer [`reserve`] if future
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
 +    /// let mut buf: VecDeque<i32> = [1].into();
      /// buf.reserve_exact(10);
      /// assert!(buf.capacity() >= 11);
      /// ```
      }
  
      /// Reserves capacity for at least `additional` more elements to be inserted in the given
 -    /// `VecDeque`. The collection may reserve more space to avoid frequent reallocations.
 +    /// deque. The collection may reserve more space to avoid frequent reallocations.
      ///
      /// # Panics
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
 +    /// let mut buf: VecDeque<i32> = [1].into();
      /// buf.reserve(10);
      /// assert!(buf.capacity() >= 11);
      /// ```
      }
  
      /// Tries to reserve the minimum capacity for exactly `additional` more elements to
 -    /// be inserted in the given `VecDeque<T>`. After calling `try_reserve_exact`,
 +    /// be inserted in the given deque. After calling `try_reserve_exact`,
      /// capacity will be greater than or equal to `self.len() + additional`.
      /// Does nothing if the capacity is already sufficient.
      ///
      /// Note that the allocator may give the collection more space than it
      /// requests. Therefore, capacity can not be relied upon to be precisely
 -    /// minimal. Prefer [`reserve`] if future insertions are expected.
 +    /// minimal. Prefer [`try_reserve`] if future insertions are expected.
      ///
 -    /// [`reserve`]: VecDeque::reserve
 +    /// [`try_reserve`]: VecDeque::try_reserve
      ///
      /// # Errors
      ///
      }
  
      /// Tries to reserve capacity for at least `additional` more elements to be inserted
 -    /// in the given `VecDeque<T>`. The collection may reserve more space to avoid
 +    /// in the given deque. The collection may reserve more space to avoid
      /// frequent reallocations. After calling `try_reserve`, capacity will be
      /// greater than or equal to `self.len() + additional`. Does nothing if
      /// capacity is already sufficient.
          Ok(())
      }
  
 -    /// Shrinks the capacity of the `VecDeque` as much as possible.
 +    /// Shrinks the capacity of the deque as much as possible.
      ///
      /// It will drop down as close as possible to the length but the allocator may still inform the
 -    /// `VecDeque` that there is space for a few more elements.
 +    /// deque that there is space for a few more elements.
      ///
      /// # Examples
      ///
          self.shrink_to(0);
      }
  
 -    /// Shrinks the capacity of the `VecDeque` with a lower bound.
 +    /// Shrinks the capacity of the deque with a lower bound.
      ///
      /// The capacity will remain at least as large as both the length
      /// and the supplied value.
          }
      }
  
 -    /// Shortens the `VecDeque`, keeping the first `len` elements and dropping
 +    /// Shortens the deque, keeping the first `len` elements and dropping
      /// the rest.
      ///
 -    /// If `len` is greater than the `VecDeque`'s current length, this has no
 +    /// If `len` is greater than the deque's current length, this has no
      /// effect.
      ///
      /// # Examples
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn iter_mut(&mut self) -> IterMut<'_, T> {
          // SAFETY: The internal `IterMut` safety invariant is established because the
 -        // `ring` we create is a dereferencable slice for lifetime '_.
 +        // `ring` we create is a dereferenceable slice for lifetime '_.
          let ring = ptr::slice_from_raw_parts_mut(self.ptr(), self.cap());
  
          unsafe { IterMut::new(ring, self.tail, self.head, PhantomData) }
      }
  
      /// Returns a pair of slices which contain, in order, the contents of the
 -    /// `VecDeque`.
 +    /// deque.
      ///
      /// If [`make_contiguous`] was previously called, all elements of the
 -    /// `VecDeque` will be in the first slice and the second slice will be empty.
 +    /// deque will be in the first slice and the second slice will be empty.
      ///
      /// [`make_contiguous`]: VecDeque::make_contiguous
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut vector = VecDeque::new();
 +    /// let mut deque = VecDeque::new();
      ///
 -    /// vector.push_back(0);
 -    /// vector.push_back(1);
 -    /// vector.push_back(2);
 +    /// deque.push_back(0);
 +    /// deque.push_back(1);
 +    /// deque.push_back(2);
      ///
 -    /// assert_eq!(vector.as_slices(), (&[0, 1, 2][..], &[][..]));
 +    /// assert_eq!(deque.as_slices(), (&[0, 1, 2][..], &[][..]));
      ///
 -    /// vector.push_front(10);
 -    /// vector.push_front(9);
 +    /// deque.push_front(10);
 +    /// deque.push_front(9);
      ///
 -    /// assert_eq!(vector.as_slices(), (&[9, 10][..], &[0, 1, 2][..]));
 +    /// assert_eq!(deque.as_slices(), (&[9, 10][..], &[0, 1, 2][..]));
      /// ```
      #[inline]
      #[stable(feature = "deque_extras_15", since = "1.5.0")]
      }
  
      /// Returns a pair of slices which contain, in order, the contents of the
 -    /// `VecDeque`.
 +    /// deque.
      ///
      /// If [`make_contiguous`] was previously called, all elements of the
 -    /// `VecDeque` will be in the first slice and the second slice will be empty.
 +    /// deque will be in the first slice and the second slice will be empty.
      ///
      /// [`make_contiguous`]: VecDeque::make_contiguous
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut vector = VecDeque::new();
 +    /// let mut deque = VecDeque::new();
      ///
 -    /// vector.push_back(0);
 -    /// vector.push_back(1);
 +    /// deque.push_back(0);
 +    /// deque.push_back(1);
      ///
 -    /// vector.push_front(10);
 -    /// vector.push_front(9);
 +    /// deque.push_front(10);
 +    /// deque.push_front(9);
      ///
 -    /// vector.as_mut_slices().0[0] = 42;
 -    /// vector.as_mut_slices().1[0] = 24;
 -    /// assert_eq!(vector.as_slices(), (&[42, 10][..], &[24, 1][..]));
 +    /// deque.as_mut_slices().0[0] = 42;
 +    /// deque.as_mut_slices().1[0] = 24;
 +    /// assert_eq!(deque.as_slices(), (&[42, 10][..], &[24, 1][..]));
      /// ```
      #[inline]
      #[stable(feature = "deque_extras_15", since = "1.5.0")]
          }
      }
  
 -    /// Returns the number of elements in the `VecDeque`.
 +    /// Returns the number of elements in the deque.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut v = VecDeque::new();
 -    /// assert_eq!(v.len(), 0);
 -    /// v.push_back(1);
 -    /// assert_eq!(v.len(), 1);
 +    /// let mut deque = VecDeque::new();
 +    /// assert_eq!(deque.len(), 0);
 +    /// deque.push_back(1);
 +    /// assert_eq!(deque.len(), 1);
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn len(&self) -> usize {
          count(self.tail, self.head, self.cap())
      }
  
 -    /// Returns `true` if the `VecDeque` is empty.
 +    /// Returns `true` if the deque is empty.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut v = VecDeque::new();
 -    /// assert!(v.is_empty());
 -    /// v.push_front(1);
 -    /// assert!(!v.is_empty());
 +    /// let mut deque = VecDeque::new();
 +    /// assert!(deque.is_empty());
 +    /// deque.push_front(1);
 +    /// assert!(!deque.is_empty());
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn is_empty(&self) -> bool {
          (tail, head)
      }
  
 -    /// Creates an iterator that covers the specified range in the `VecDeque`.
 +    /// Creates an iterator that covers the specified range in the deque.
      ///
      /// # Panics
      ///
      /// Panics if the starting point is greater than the end point or if
 -    /// the end point is greater than the length of the vector.
 +    /// the end point is greater than the length of the deque.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let v: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
 -    /// let range = v.range(2..).copied().collect::<VecDeque<_>>();
 +    /// let deque: VecDeque<_> = [1, 2, 3].into();
 +    /// let range = deque.range(2..).copied().collect::<VecDeque<_>>();
      /// assert_eq!(range, [3]);
      ///
      /// // A full range covers all contents
 -    /// let all = v.range(..);
 +    /// let all = deque.range(..);
      /// assert_eq!(all.len(), 3);
      /// ```
      #[inline]
          }
      }
  
 -    /// Creates an iterator that covers the specified mutable range in the `VecDeque`.
 +    /// Creates an iterator that covers the specified mutable range in the deque.
      ///
      /// # Panics
      ///
      /// Panics if the starting point is greater than the end point or if
 -    /// the end point is greater than the length of the vector.
 +    /// the end point is greater than the length of the deque.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut v: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
 -    /// for v in v.range_mut(2..) {
 +    /// let mut deque: VecDeque<_> = [1, 2, 3].into();
 +    /// for v in deque.range_mut(2..) {
      ///   *v *= 2;
      /// }
 -    /// assert_eq!(v, vec![1, 2, 6]);
 +    /// assert_eq!(deque, [1, 2, 6]);
      ///
      /// // A full range covers all contents
 -    /// for v in v.range_mut(..) {
 +    /// for v in deque.range_mut(..) {
      ///   *v *= 2;
      /// }
 -    /// assert_eq!(v, vec![2, 4, 12]);
 +    /// assert_eq!(deque, [2, 4, 12]);
      /// ```
      #[inline]
      #[stable(feature = "deque_range", since = "1.51.0")]
          let (tail, head) = self.range_tail_head(range);
  
          // SAFETY: The internal `IterMut` safety invariant is established because the
 -        // `ring` we create is a dereferencable slice for lifetime '_.
 +        // `ring` we create is a dereferenceable slice for lifetime '_.
          let ring = ptr::slice_from_raw_parts_mut(self.ptr(), self.cap());
  
          unsafe { IterMut::new(ring, tail, head, PhantomData) }
      }
  
      /// Creates a draining iterator that removes the specified range in the
 -    /// `VecDeque` and yields the removed items.
 +    /// deque and yields the removed items.
      ///
      /// Note 1: The element range is removed even if the iterator is not
      /// consumed until the end.
      /// # Panics
      ///
      /// Panics if the starting point is greater than the end point or if
 -    /// the end point is greater than the length of the vector.
 +    /// the end point is greater than the length of the deque.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut v: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
 -    /// let drained = v.drain(2..).collect::<VecDeque<_>>();
 +    /// let mut deque: VecDeque<_> = [1, 2, 3].into();
 +    /// let drained = deque.drain(2..).collect::<VecDeque<_>>();
      /// assert_eq!(drained, [3]);
 -    /// assert_eq!(v, [1, 2]);
 +    /// assert_eq!(deque, [1, 2]);
      ///
      /// // A full range clears all contents
 -    /// v.drain(..);
 -    /// assert!(v.is_empty());
 +    /// deque.drain(..);
 +    /// assert!(deque.is_empty());
      /// ```
      #[inline]
      #[stable(feature = "drain", since = "1.6.0")]
          unsafe { Drain::new(drain_head, head, iter, deque) }
      }
  
 -    /// Clears the `VecDeque`, removing all values.
 +    /// Clears the deque, removing all values.
      ///
      /// # Examples
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut v = VecDeque::new();
 -    /// v.push_back(1);
 -    /// v.clear();
 -    /// assert!(v.is_empty());
 +    /// let mut deque = VecDeque::new();
 +    /// deque.push_back(1);
 +    /// deque.clear();
 +    /// assert!(deque.is_empty());
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      #[inline]
          self.truncate(0);
      }
  
 -    /// Returns `true` if the `VecDeque` contains an element equal to the
 +    /// Returns `true` if the deque contains an element equal to the
      /// given value.
      ///
      /// # Examples
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut vector: VecDeque<u32> = VecDeque::new();
 +    /// let mut deque: VecDeque<u32> = VecDeque::new();
      ///
 -    /// vector.push_back(0);
 -    /// vector.push_back(1);
 +    /// deque.push_back(0);
 +    /// deque.push_back(1);
      ///
 -    /// assert_eq!(vector.contains(&1), true);
 -    /// assert_eq!(vector.contains(&10), false);
 +    /// assert_eq!(deque.contains(&1), true);
 +    /// assert_eq!(deque.contains(&10), false);
      /// ```
      #[stable(feature = "vec_deque_contains", since = "1.12.0")]
      pub fn contains(&self, x: &T) -> bool
          a.contains(x) || b.contains(x)
      }
  
 -    /// Provides a reference to the front element, or `None` if the `VecDeque` is
 +    /// Provides a reference to the front element, or `None` if the deque is
      /// empty.
      ///
      /// # Examples
      }
  
      /// Provides a mutable reference to the front element, or `None` if the
 -    /// `VecDeque` is empty.
 +    /// deque is empty.
      ///
      /// # Examples
      ///
          self.get_mut(0)
      }
  
 -    /// Provides a reference to the back element, or `None` if the `VecDeque` is
 +    /// Provides a reference to the back element, or `None` if the deque is
      /// empty.
      ///
      /// # Examples
      }
  
      /// Provides a mutable reference to the back element, or `None` if the
 -    /// `VecDeque` is empty.
 +    /// deque is empty.
      ///
      /// # Examples
      ///
          self.get_mut(self.len().wrapping_sub(1))
      }
  
 -    /// Removes the first element and returns it, or `None` if the `VecDeque` is
 +    /// Removes the first element and returns it, or `None` if the deque is
      /// empty.
      ///
      /// # Examples
          }
      }
  
 -    /// Removes the last element from the `VecDeque` and returns it, or `None` if
 +    /// Removes the last element from the deque and returns it, or `None` if
      /// it is empty.
      ///
      /// # Examples
          }
      }
  
 -    /// Prepends an element to the `VecDeque`.
 +    /// Prepends an element to the deque.
      ///
      /// # Examples
      ///
          }
      }
  
 -    /// Appends an element to the back of the `VecDeque`.
 +    /// Appends an element to the back of the deque.
      ///
      /// # Examples
      ///
          self.tail <= self.head
      }
  
 -    /// Removes an element from anywhere in the `VecDeque` and returns it,
 +    /// Removes an element from anywhere in the deque and returns it,
      /// replacing it with the first element.
      ///
      /// This does not preserve ordering, but is *O*(1).
          self.pop_front()
      }
  
 -    /// Removes an element from anywhere in the `VecDeque` and returns it, replacing it with the
 -    /// last element.
 +    /// Removes an element from anywhere in the deque and returns it,
 +    /// replacing it with the last element.
      ///
      /// This does not preserve ordering, but is *O*(1).
      ///
          self.pop_back()
      }
  
 -    /// Inserts an element at `index` within the `VecDeque`, shifting all elements with indices
 -    /// greater than or equal to `index` towards the back.
 +    /// Inserts an element at `index` within the deque, shifting all elements
 +    /// with indices greater than or equal to `index` towards the back.
      ///
      /// Element at index 0 is the front of the queue.
      ///
      /// # Panics
      ///
 -    /// Panics if `index` is greater than `VecDeque`'s length
 +    /// Panics if `index` is greater than deque's length
      ///
      /// # Examples
      ///
          }
      }
  
 -    /// Removes and returns the element at `index` from the `VecDeque`.
 +    /// Removes and returns the element at `index` from the deque.
      /// Whichever end is closer to the removal point will be moved to make
      /// room, and all the affected elements will be moved to new positions.
      /// Returns `None` if `index` is out of bounds.
          elem
      }
  
 -    /// Splits the `VecDeque` into two at the given index.
 +    /// Splits the deque into two at the given index.
      ///
      /// Returns a newly allocated `VecDeque`. `self` contains elements `[0, at)`,
 -    /// and the returned `VecDeque` contains elements `[at, len)`.
 +    /// and the returned deque contains elements `[at, len)`.
      ///
      /// Note that the capacity of `self` does not change.
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
 +    /// let mut buf: VecDeque<_> = [1, 2, 3].into();
      /// let buf2 = buf.split_off(1);
      /// assert_eq!(buf, [1]);
      /// assert_eq!(buf2, [2, 3]);
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut buf: VecDeque<_> = vec![1, 2].into_iter().collect();
 -    /// let mut buf2: VecDeque<_> = vec![3, 4].into_iter().collect();
 +    /// let mut buf: VecDeque<_> = [1, 2].into();
 +    /// let mut buf2: VecDeque<_> = [3, 4].into();
      /// buf.append(&mut buf2);
      /// assert_eq!(buf, [1, 2, 3, 4]);
      /// assert_eq!(buf2, []);
      pub fn retain<F>(&mut self, mut f: F)
      where
          F: FnMut(&T) -> bool,
 +    {
 +        self.retain_mut(|elem| f(elem));
 +    }
 +
 +    /// Retains only the elements specified by the predicate.
 +    ///
 +    /// In other words, remove all elements `e` such that `f(&e)` returns false.
 +    /// This method operates in place, visiting each element exactly once in the
 +    /// original order, and preserves the order of the retained elements.
 +    ///
 +    /// # Examples
 +    ///
 +    /// ```
 +    /// #![feature(vec_retain_mut)]
 +    ///
 +    /// use std::collections::VecDeque;
 +    ///
 +    /// let mut buf = VecDeque::new();
 +    /// buf.extend(1..5);
 +    /// buf.retain_mut(|x| if *x % 2 == 0 {
 +    ///     *x += 1;
 +    ///     true
 +    /// } else {
 +    ///     false
 +    /// });
 +    /// assert_eq!(buf, [3, 5]);
 +    /// ```
 +    #[unstable(feature = "vec_retain_mut", issue = "90829")]
 +    pub fn retain_mut<F>(&mut self, mut f: F)
 +    where
 +        F: FnMut(&mut T) -> bool,
      {
          let len = self.len();
          let mut idx = 0;
  
          // Stage 1: All values are retained.
          while cur < len {
 -            if !f(&self[cur]) {
 +            if !f(&mut self[cur]) {
                  cur += 1;
                  break;
              }
          }
          // Stage 2: Swap retained value into current idx.
          while cur < len {
 -            if !f(&self[cur]) {
 +            if !f(&mut self[cur]) {
                  cur += 1;
                  continue;
              }
              cur += 1;
              idx += 1;
          }
 -        // Stage 3: Trancate all values after idx.
 +        // Stage 3: Truncate all values after idx.
          if cur != idx {
              self.truncate(idx);
          }
          debug_assert!(!self.is_full());
      }
  
 -    /// Modifies the `VecDeque` in-place so that `len()` is equal to `new_len`,
 +    /// Modifies the deque in-place so that `len()` is equal to `new_len`,
      /// either by removing excess elements from the back or by appending
      /// elements generated by calling `generator` to the back.
      ///
      ///
      /// Once the internal storage is contiguous, the [`as_slices`] and
      /// [`as_mut_slices`] methods will return the entire contents of the
 -    /// `VecDeque` in a single slice.
 +    /// deque in a single slice.
      ///
      /// [`as_slices`]: VecDeque::as_slices
      /// [`as_mut_slices`]: VecDeque::as_mut_slices
          }
      }
  
 -    /// Binary searches this sorted `VecDeque` for a given element.
 +    /// Binary searches the sorted deque for a given element.
      ///
      /// If the value is found then [`Result::Ok`] is returned, containing the
      /// index of the matching element. If there are multiple matches, then any
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
 +    /// let deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
      ///
      /// assert_eq!(deque.binary_search(&13),  Ok(9));
      /// assert_eq!(deque.binary_search(&4),   Err(7));
      /// assert!(matches!(r, Ok(1..=4)));
      /// ```
      ///
 -    /// If you want to insert an item to a sorted `VecDeque`, while maintaining
 +    /// If you want to insert an item to a sorted deque, while maintaining
      /// sort order:
      ///
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let mut deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
 +    /// let mut deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
      /// let num = 42;
      /// let idx = deque.binary_search(&num).unwrap_or_else(|x| x);
      /// deque.insert(idx, num);
          self.binary_search_by(|e| e.cmp(x))
      }
  
 -    /// Binary searches this sorted `VecDeque` with a comparator function.
 +    /// Binary searches the sorted deque with a comparator function.
      ///
      /// The comparator function should implement an order consistent
 -    /// with the sort order of the underlying `VecDeque`, returning an
 -    /// order code that indicates whether its argument is `Less`,
 -    /// `Equal` or `Greater` than the desired target.
 +    /// with the sort order of the deque, returning an order code that
 +    /// indicates whether its argument is `Less`, `Equal` or `Greater`
 +    /// than the desired target.
      ///
      /// If the value is found then [`Result::Ok`] is returned, containing the
      /// index of the matching element. If there are multiple matches, then any
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
 +    /// let deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
      ///
      /// assert_eq!(deque.binary_search_by(|x| x.cmp(&13)),  Ok(9));
      /// assert_eq!(deque.binary_search_by(|x| x.cmp(&4)),   Err(7));
          }
      }
  
 -    /// Binary searches this sorted `VecDeque` with a key extraction function.
 +    /// Binary searches the sorted deque with a key extraction function.
      ///
 -    /// Assumes that the `VecDeque` is sorted by the key, for instance with
 +    /// Assumes that the deque is sorted by the key, for instance with
      /// [`make_contiguous().sort_by_key()`] using the same key extraction function.
      ///
      /// If the value is found then [`Result::Ok`] is returned, containing the
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let deque: VecDeque<_> = vec![(0, 0), (2, 1), (4, 1), (5, 1),
 +    /// let deque: VecDeque<_> = [(0, 0), (2, 1), (4, 1), (5, 1),
      ///          (3, 1), (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
      ///          (1, 21), (2, 34), (4, 55)].into();
      ///
      /// For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0
      /// (all odd numbers are at the start, all even at the end).
      ///
 -    /// If this deque is not partitioned, the returned result is unspecified and meaningless,
 +    /// If the deque is not partitioned, the returned result is unspecified and meaningless,
      /// as this method performs a kind of binary search.
      ///
      /// See also [`binary_search`], [`binary_search_by`], and [`binary_search_by_key`].
      /// ```
      /// use std::collections::VecDeque;
      ///
 -    /// let deque: VecDeque<_> = vec![1, 2, 3, 3, 5, 6, 7].into();
 +    /// let deque: VecDeque<_> = [1, 2, 3, 3, 5, 6, 7].into();
      /// let i = deque.partition_point(|&x| x < 5);
      ///
      /// assert_eq!(i, 4);
  }
  
  impl<T: Clone, A: Allocator> VecDeque<T, A> {
 -    /// Modifies the `VecDeque` in-place so that `len()` is equal to new_len,
 +    /// Modifies the deque in-place so that `len()` is equal to new_len,
      /// either by removing excess elements from the back or by appending clones of `value`
      /// to the back.
      ///
@@@ -2878,7 -2847,7 +2878,7 @@@ impl<T, A: Allocator> IntoIterator for 
      type Item = T;
      type IntoIter = IntoIter<T, A>;
  
 -    /// Consumes the `VecDeque` into a front-to-back iterator yielding elements by
 +    /// Consumes the deque into a front-to-back iterator yielding elements by
      /// value.
      fn into_iter(self) -> IntoIter<T, A> {
          IntoIter::new(self)
@@@ -3049,6 -3018,8 +3049,8 @@@ impl<T, A: Allocator> From<VecDeque<T, 
  
  #[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;
      ///
index bd3262b51d4807b1363a88b3b66d7519b050ea90,0cc4a55dc99c926a694424e89c70f88453dd991f..3dc3eee4133b6413f2bfaa4b4059b06cb585b426
@@@ -148,7 -148,7 +148,7 @@@ use self::spec_extend::SpecExtend
  #[cfg(not(no_global_oom_handling))]
  mod spec_extend;
  
 -/// A contiguous growable array type, written as `Vec<T>` and pronounced 'vector'.
 +/// A contiguous growable array type, written as `Vec<T>`, short for 'vector'.
  ///
  /// # Examples
  ///
@@@ -822,7 -822,7 +822,7 @@@ impl<T, A: Allocator> Vec<T, A> 
      ///
      /// # Panics
      ///
 -    /// Panics if the new capacity overflows `usize`.
 +    /// Panics if the new capacity exceeds `isize::MAX` bytes.
      ///
      /// # Examples
      ///
      ///
      /// Note that the allocator may give the collection more space than it
      /// requests. Therefore, capacity can not be relied upon to be precisely
 -    /// minimal. Prefer [`reserve`] if future insertions are expected.
 +    /// minimal. Prefer [`try_reserve`] if future insertions are expected.
      ///
 -    /// [`reserve`]: Vec::reserve
 +    /// [`try_reserve`]: Vec::try_reserve
      ///
      /// # Errors
      ///
      ///
      /// Note: Because this shifts over the remaining elements, it has a
      /// worst-case performance of *O*(*n*). If you don't need the order of elements
 -    /// to be preserved, use [`swap_remove`] instead.
 +    /// to be preserved, use [`swap_remove`] instead. If you'd like to remove
 +    /// elements from the beginning of the `Vec`, consider using
 +    /// [`VecDeque::pop_front`] instead.
      ///
      /// [`swap_remove`]: Vec::swap_remove
 +    /// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
      ///
      /// # Panics
      ///
  
          let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len };
  
 -        // process_one return a bool indicates whether the processing element should be retained.
 -        #[inline(always)]
 -        fn process_one<F, T, A: Allocator, const DELETED: bool>(
 +        fn process_loop<F, T, A: Allocator, const DELETED: bool>(
 +            original_len: usize,
              f: &mut F,
              g: &mut BackshiftOnDrop<'_, T, A>,
 -        ) -> bool
 -        where
 +        ) where
              F: FnMut(&mut T) -> bool,
          {
 -            // SAFETY: Unchecked element must be valid.
 -            let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) };
 -            if !f(cur) {
 -                // Advance early to avoid double drop if `drop_in_place` panicked.
 -                g.processed_len += 1;
 -                g.deleted_cnt += 1;
 -                // SAFETY: We never touch this element again after dropped.
 -                unsafe { ptr::drop_in_place(cur) };
 -                // We already advanced the counter.
 -                return false;
 -            }
 -            if DELETED {
 -                // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
 -                // We use copy for move, and never touch this element again.
 -                unsafe {
 -                    let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
 -                    ptr::copy_nonoverlapping(cur, hole_slot, 1);
 +            while g.processed_len != original_len {
 +                // SAFETY: Unchecked element must be valid.
 +                let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) };
 +                if !f(cur) {
 +                    // Advance early to avoid double drop if `drop_in_place` panicked.
 +                    g.processed_len += 1;
 +                    g.deleted_cnt += 1;
 +                    // SAFETY: We never touch this element again after dropped.
 +                    unsafe { ptr::drop_in_place(cur) };
 +                    // We already advanced the counter.
 +                    if DELETED {
 +                        continue;
 +                    } else {
 +                        break;
 +                    }
 +                }
 +                if DELETED {
 +                    // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
 +                    // We use copy for move, and never touch this element again.
 +                    unsafe {
 +                        let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
 +                        ptr::copy_nonoverlapping(cur, hole_slot, 1);
 +                    }
                  }
 +                g.processed_len += 1;
              }
 -            g.processed_len += 1;
 -            return true;
          }
  
          // Stage 1: Nothing was deleted.
 -        while g.processed_len != original_len {
 -            if !process_one::<F, T, A, false>(&mut f, &mut g) {
 -                break;
 -            }
 -        }
 +        process_loop::<F, T, A, false>(original_len, &mut f, &mut g);
  
          // Stage 2: Some elements were deleted.
 -        while g.processed_len != original_len {
 -            process_one::<F, T, A, true>(&mut f, &mut g);
 -        }
 +        process_loop::<F, T, A, true>(original_len, &mut f, &mut g);
  
          // All item are processed. This can be optimized to `set_len` by LLVM.
          drop(g);
                      let ptr = self.vec.as_mut_ptr();
                      let len = self.vec.len();
  
 -                    /* How many items were left when `same_bucket` paniced.
 +                    /* How many items were left when `same_bucket` panicked.
                       * Basically vec[read..].len() */
                      let items_left = len.wrapping_sub(self.read);
  
      /// Removes the last element from a vector and returns it, or [`None`] if it
      /// is empty.
      ///
 +    /// If you'd like to pop the first element, consider using
 +    /// [`VecDeque::pop_front`] instead.
 +    ///
 +    /// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
 +    ///
      /// # Examples
      ///
      /// ```
      /// # Examples
      ///
      /// ```
 -    /// #![feature(vec_spare_capacity, maybe_uninit_extra)]
 -    ///
      /// // Allocate vector big enough for 10 elements.
      /// let mut v = Vec::with_capacity(10);
      ///
      ///
      /// assert_eq!(&v, &[0, 1, 2]);
      /// ```
 -    #[unstable(feature = "vec_spare_capacity", issue = "75017")]
 +    #[stable(feature = "vec_spare_capacity", since = "1.60.0")]
      #[inline]
      pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
          // Note:
      /// # Examples
      ///
      /// ```
 -    /// #![feature(vec_split_at_spare, maybe_uninit_extra)]
 +    /// #![feature(vec_split_at_spare)]
      ///
      /// let mut v = vec![1, 1, 2];
      ///
      unsafe fn split_at_spare_mut_with_len(
          &mut self,
      ) -> (&mut [T], &mut [MaybeUninit<T>], &mut usize) {
 -        let Range { start: ptr, end: spare_ptr } = self.as_mut_ptr_range();
 +        let ptr = self.as_mut_ptr();
 +        // SAFETY:
 +        // - `ptr` is guaranteed to be valid for `self.len` elements
 +        // - but the allocation extends out to `self.buf.capacity()` elements, possibly
 +        // uninitialized
 +        let spare_ptr = unsafe { ptr.add(self.len) };
          let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
          let spare_len = self.buf.capacity() - self.len;
  
          // SAFETY:
 -        // - `ptr` is guaranteed to be valid for `len` elements
 +        // - `ptr` is guaranteed to be valid for `self.len` elements
          // - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
          unsafe {
              let initialized = slice::from_raw_parts_mut(ptr, self.len);
@@@ -2207,7 -2199,7 +2207,7 @@@ impl<T: Clone, A: Allocator> Vec<T, A> 
      /// Clones and appends all elements in a slice to the `Vec`.
      ///
      /// Iterates over the slice `other`, clones each element, and then appends
 -    /// it to this `Vec`. The `other` vector is traversed in-order.
 +    /// it to this `Vec`. The `other` slice is traversed in-order.
      ///
      /// Note that this function is same as [`extend`] except that it is
      /// specialized to work with slices instead. If and when Rust gets
@@@ -2283,6 -2275,16 +2283,6 @@@ impl<T: Clone> ExtendWith<T> for Extend
      }
  }
  
 -struct ExtendDefault;
 -impl<T: Default> ExtendWith<T> for ExtendDefault {
 -    fn next(&mut self) -> T {
 -        Default::default()
 -    }
 -    fn last(self) -> T {
 -        Default::default()
 -    }
 -}
 -
  struct ExtendFunc<F>(F);
  impl<T, F: FnMut() -> T> ExtendWith<T> for ExtendFunc<F> {
      fn next(&mut self) -> T {
@@@ -2684,11 -2686,11 +2684,11 @@@ impl<T, A: Allocator> Vec<T, A> 
      /// # Examples
      ///
      /// ```
 -    /// let mut v = vec![1, 2, 3];
 -    /// let new = [7, 8];
 -    /// let u: Vec<_> = v.splice(..2, new).collect();
 -    /// assert_eq!(v, &[7, 8, 3]);
 -    /// assert_eq!(u, &[1, 2]);
 +    /// let mut v = vec![1, 2, 3, 4];
 +    /// let new = [7, 8, 9];
 +    /// let u: Vec<_> = v.splice(1..3, new).collect();
 +    /// assert_eq!(v, &[1, 7, 8, 9, 4]);
 +    /// assert_eq!(u, &[2, 3]);
      /// ```
      #[cfg(not(no_global_oom_handling))]
      #[inline]
@@@ -2906,10 -2908,6 +2906,6 @@@ 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)
@@@ -3010,12 -3013,14 +3011,12 @@@ impl<T, A: Allocator, const N: usize> T
      /// # Examples
      ///
      /// ```
 -    /// use std::convert::TryInto;
      /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
      /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
      /// ```
      ///
      /// If the length doesn't match, the input comes back in `Err`:
      /// ```
 -    /// use std::convert::TryInto;
      /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
      /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
      /// ```
      /// If you're fine with just getting a prefix of the `Vec<T>`,
      /// you can call [`.truncate(N)`](Vec::truncate) first.
      /// ```
 -    /// use std::convert::TryInto;
      /// let mut v = String::from("hello world").into_bytes();
      /// v.sort();
      /// v.truncate(2);
diff --combined library/core/src/cell.rs
index feb9455565844ae5ae127568fb80eae4bc6ee170,235e43a3048d8110284744941546dadf8c08cce9..aef7ad77568036d29752182ea18a404ae1fc711b
@@@ -315,6 -315,7 +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)
      }
@@@ -898,7 -899,7 +899,7 @@@ impl<T: ?Sized> RefCell<T> 
                  Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b })
              }
              None => Err(BorrowError {
 -                // If a borrow occured, then we must already have an outstanding borrow,
 +                // If a borrow occurred, then we must already have an outstanding borrow,
                  // so `borrowed_at` will be `Some`
                  #[cfg(feature = "debug_refcell")]
                  location: self.borrowed_at.get().unwrap(),
                  Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b })
              }
              None => Err(BorrowMutError {
 -                // If a borrow occured, then we must already have an outstanding borrow,
 +                // If a borrow occurred, then we must already have an outstanding borrow,
                  // so `borrowed_at` will be `Some`
                  #[cfg(feature = "debug_refcell")]
                  location: self.borrowed_at.get().unwrap(),
              Ok(unsafe { &*self.value.get() })
          } else {
              Err(BorrowError {
 -                // If a borrow occured, then we must already have an outstanding borrow,
 +                // If a borrow occurred, then we must already have an outstanding borrow,
                  // so `borrowed_at` will be `Some`
                  #[cfg(feature = "debug_refcell")]
                  location: self.borrowed_at.get().unwrap(),
@@@ -1244,6 -1245,7 +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)
      }
@@@ -1310,7 -1312,11 +1312,7 @@@ impl Clone for BorrowRef<'_> 
  ///
  /// See the [module-level documentation](self) for more.
  #[stable(feature = "rust1", since = "1.0.0")]
 -#[cfg_attr(
 -    not(bootstrap),
 -    must_not_suspend = "holding a Ref across suspend \
 -                      points can cause BorrowErrors"
 -)]
 +#[must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors"]
  pub struct Ref<'b, T: ?Sized + 'b> {
      value: &'b T,
      borrow: BorrowRef<'b>,
@@@ -1688,7 -1694,11 +1690,7 @@@ impl<'b> BorrowRefMut<'b> 
  ///
  /// See the [module-level documentation](self) for more.
  #[stable(feature = "rust1", since = "1.0.0")]
 -#[cfg_attr(
 -    not(bootstrap),
 -    must_not_suspend = "holding a RefMut across suspend \
 -                      points can cause BorrowErrors"
 -)]
 +#[must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors"]
  pub struct RefMut<'b, T: ?Sized + 'b> {
      value: &'b mut T,
      borrow: BorrowRefMut<'b>,
@@@ -1959,7 -1969,6 +1961,7 @@@ impl<T: ?Sized> UnsafeCell<T> 
      /// ```
      #[inline(always)]
      #[stable(feature = "unsafe_cell_raw_get", since = "1.56.0")]
 +    #[rustc_const_stable(feature = "unsafe_cell_raw_get", since = "1.56.0")]
      pub const fn raw_get(this: *const Self) -> *mut T {
          // We can just cast the pointer from `UnsafeCell<T>` to `T` because of
          // #[repr(transparent)]. This exploits libstd's special status, there is
@@@ -1979,6 -1988,7 +1981,7 @@@ impl<T: Default> Default for UnsafeCell
  #[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)
      }
index 5566c2ffe87deeed0a75bb26e745f2527cd5e079,de23dda1d0f4dc0f7dbff4b97c2deec45f17e4f7..0ceedf936333d6d4659998664d0e0b89d6b8d168
@@@ -91,7 -91,7 +91,7 @@@ pub use num::FloatToInt
  /// ```rust
  /// use std::convert::identity;
  ///
 -/// let iter = vec![Some(1), None, Some(3)].into_iter();
 +/// let iter = [Some(1), None, Some(3)].into_iter();
  /// let filtered = iter.filter_map(identity).collect::<Vec<_>>();
  /// assert_eq!(vec![1, 3], filtered);
  /// ```
@@@ -426,6 -426,8 +426,6 @@@ pub trait TryInto<T>: Sized 
  /// `TryFrom<T>` can be implemented as follows:
  ///
  /// ```
 -/// use std::convert::TryFrom;
 -///
  /// struct GreaterThanZero(i32);
  ///
  /// impl TryFrom<i32> for GreaterThanZero {
  /// 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.
@@@ -481,10 -485,9 +481,10 @@@ pub trait TryFrom<T>: Sized 
  
  // As lifts over &
  #[stable(feature = "rust1", since = "1.0.0")]
 -impl<T: ?Sized, U: ?Sized> AsRef<U> for &T
 +#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 +impl<T: ?Sized, U: ?Sized> const AsRef<U> for &T
  where
 -    T: AsRef<U>,
 +    T: ~const AsRef<U>,
  {
      fn as_ref(&self) -> &U {
          <T as AsRef<U>>::as_ref(*self)
  
  // As lifts over &mut
  #[stable(feature = "rust1", since = "1.0.0")]
 -impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T
 +#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 +impl<T: ?Sized, U: ?Sized> const AsRef<U> for &mut T
  where
 -    T: AsRef<U>,
 +    T: ~const AsRef<U>,
  {
      fn as_ref(&self) -> &U {
          <T as AsRef<U>>::as_ref(*self)
  
  // AsMut lifts over &mut
  #[stable(feature = "rust1", since = "1.0.0")]
 -impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T
 +#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 +impl<T: ?Sized, U: ?Sized> const AsMut<U> for &mut T
  where
 -    T: AsMut<U>,
 +    T: ~const AsMut<U>,
  {
      fn as_mut(&mut self) -> &mut U {
          (*self).as_mut()
  
  // From implies Into
  #[stable(feature = "rust1", since = "1.0.0")]
 -impl<T, U> Into<U> for T
 +#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 +impl<T, U> const Into<U> for T
  where
 -    U: From<T>,
 +    U: ~const 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)
      }
  #[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
      }
@@@ -570,10 -575,9 +575,10 @@@ impl<T> const From<!> for T 
  
  // TryFrom implies TryInto
  #[stable(feature = "try_from", since = "1.34.0")]
 -impl<T, U> TryInto<U> for T
 +#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 +impl<T, U> const TryInto<U> for T
  where
 -    U: TryFrom<T>,
 +    U: ~const TryFrom<T>,
  {
      type Error = U::Error;
  
  // Infallible conversions are semantically equivalent to fallible conversions
  // with an uninhabited error type.
  #[stable(feature = "try_from", since = "1.34.0")]
 -impl<T, U> TryFrom<U> for T
 +#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 +impl<T, U> const TryFrom<U> for T
  where
 -    U: Into<T>,
 +    U: ~const Into<T>,
  {
      type Error = Infallible;
  
diff --combined library/core/src/lazy.rs
index 788f0cce01ba838a83f57f92cbf4d482c00739bc,6e08a7d24c6b0e2c074b1b2c3dbb887232641553..88826782a3d607318a61348d4ad666b9392c830e
@@@ -75,6 -75,7 +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)) }
      }
@@@ -102,7 -103,8 +103,7 @@@ impl<T> OnceCell<T> 
      /// Returns `None` if the cell is empty.
      #[unstable(feature = "once_cell", issue = "74465")]
      pub fn get_mut(&mut self) -> Option<&mut T> {
 -        // SAFETY: Safe because we have unique access
 -        unsafe { &mut *self.inner.get() }.as_mut()
 +        self.inner.get_mut().as_mut()
      }
  
      /// Sets the contents of the cell to `value`.
index 3f5d3f62c96044b587868088eb7c5bad076a163e,84ffd8bc8e2041d0d290501acde13763f11efc0f..0aa8e9960a8dd706db63cd1575f4a4ced3804880
@@@ -109,7 -109,7 +109,7 @@@ impl<T: Sized> NonNull<T> 
      ///
      /// * The pointer must be properly aligned.
      ///
 -    /// * It must be "dereferencable" in the sense defined in [the module documentation].
 +    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
      ///
      /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
      ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
      #[inline]
      #[must_use]
      #[unstable(feature = "ptr_as_uninit", issue = "75402")]
 -    pub unsafe fn as_uninit_ref<'a>(&self) -> &'a MaybeUninit<T> {
 +    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
 +    pub const unsafe fn as_uninit_ref<'a>(&self) -> &'a MaybeUninit<T> {
          // SAFETY: the caller must guarantee that `self` meets all the
          // requirements for a reference.
          unsafe { &*self.cast().as_ptr() }
      ///
      /// * The pointer must be properly aligned.
      ///
 -    /// * It must be "dereferencable" in the sense defined in [the module documentation].
 +    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
      ///
      /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
      ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
      #[inline]
      #[must_use]
      #[unstable(feature = "ptr_as_uninit", issue = "75402")]
 -    pub unsafe fn as_uninit_mut<'a>(&mut self) -> &'a mut MaybeUninit<T> {
 +    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
 +    pub const unsafe fn as_uninit_mut<'a>(&mut self) -> &'a mut MaybeUninit<T> {
          // SAFETY: the caller must guarantee that `self` meets all the
          // requirements for a reference.
          unsafe { &mut *self.cast().as_ptr() }
@@@ -211,9 -209,8 +211,9 @@@ impl<T: ?Sized> NonNull<T> 
      /// }
      /// ```
      #[stable(feature = "nonnull", since = "1.25.0")]
 +    #[rustc_const_unstable(feature = "const_nonnull_new", issue = "93235")]
      #[inline]
 -    pub fn new(ptr: *mut T) -> Option<Self> {
 +    pub const fn new(ptr: *mut T) -> Option<Self> {
          if !ptr.is_null() {
              // SAFETY: The pointer is already checked and is not null
              Some(unsafe { Self::new_unchecked(ptr) })
      ///
      /// * The pointer must be properly aligned.
      ///
 -    /// * It must be "dereferencable" in the sense defined in [the module documentation].
 +    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
      ///
      /// * The pointer must point to an initialized instance of `T`.
      ///
      ///
      /// [the module documentation]: crate::ptr#safety
      #[stable(feature = "nonnull", since = "1.25.0")]
 +    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
      #[must_use]
      #[inline]
 -    pub unsafe fn as_ref<'a>(&self) -> &'a T {
 +    pub const unsafe fn as_ref<'a>(&self) -> &'a T {
          // SAFETY: the caller must guarantee that `self` meets all the
          // requirements for a reference.
          unsafe { &*self.as_ptr() }
      ///
      /// * The pointer must be properly aligned.
      ///
 -    /// * It must be "dereferencable" in the sense defined in [the module documentation].
 +    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
      ///
      /// * The pointer must point to an initialized instance of `T`.
      ///
      ///
      /// [the module documentation]: crate::ptr#safety
      #[stable(feature = "nonnull", since = "1.25.0")]
 +    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
      #[must_use]
      #[inline]
 -    pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
 +    pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
          // SAFETY: the caller must guarantee that `self` meets all the
          // requirements for a mutable reference.
          unsafe { &mut *self.as_ptr() }
@@@ -539,8 -534,7 +539,8 @@@ impl<T> NonNull<[T]> 
      #[inline]
      #[must_use]
      #[unstable(feature = "ptr_as_uninit", issue = "75402")]
 -    pub unsafe fn as_uninit_slice<'a>(&self) -> &'a [MaybeUninit<T>] {
 +    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
 +    pub const unsafe fn as_uninit_slice<'a>(&self) -> &'a [MaybeUninit<T>] {
          // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
          unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) }
      }
      #[inline]
      #[must_use]
      #[unstable(feature = "ptr_as_uninit", issue = "75402")]
 -    pub unsafe fn as_uninit_slice_mut<'a>(&self) -> &'a mut [MaybeUninit<T>] {
 +    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
 +    pub const unsafe fn as_uninit_slice_mut<'a>(&self) -> &'a mut [MaybeUninit<T>] {
          // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
          unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) }
      }
      /// Returns a raw pointer to an element or subslice, without doing bounds
      /// checking.
      ///
 -    /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
 +    /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
      /// is *[undefined behavior]* even if the resulting pointer is not used.
      ///
      /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
      where
          I: SliceIndex<[T]>,
      {
 -        // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
 +        // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
          // As a consequence, the resulting pointer cannot be null.
          unsafe { NonNull::new_unchecked(self.as_ptr().get_unchecked_mut(index)) }
      }
@@@ -721,6 -714,9 +721,9 @@@ impl<T: ?Sized> const From<Unique<T>> f
  #[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.
  #[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
index f5c624c225f26350b17c0b04cf36c928bb7fdc44,f88d4b72fcf6bfe523ad2bb006a001e368c66bb7..661d111c99d5294b7d7bf79db10aad7c5bb2b936
@@@ -92,7 -92,7 +92,7 @@@ impl<T: ?Sized> Unique<T> 
  
      /// Creates a new `Unique` if `ptr` is non-null.
      #[inline]
 -    pub fn new(ptr: *mut T) -> Option<Self> {
 +    pub const fn new(ptr: *mut T) -> Option<Self> {
          if !ptr.is_null() {
              // SAFETY: The pointer has already been checked and is not null.
              Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
      /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
      #[must_use]
      #[inline]
 -    pub unsafe fn as_ref(&self) -> &T {
 +    pub const unsafe fn as_ref(&self) -> &T {
          // SAFETY: the caller must guarantee that `self` meets all the
          // requirements for a reference.
          unsafe { &*self.as_ptr() }
      /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
      #[must_use]
      #[inline]
 -    pub unsafe fn as_mut(&mut self) -> &mut T {
 +    pub const unsafe fn as_mut(&mut self) -> &mut T {
          // SAFETY: the caller must guarantee that `self` meets all the
          // requirements for a mutable reference.
          unsafe { &mut *self.as_ptr() }
@@@ -178,6 -178,9 +178,9 @@@ impl<T: ?Sized> fmt::Pointer for Unique
  
  #[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
index 792016902aebe925b42f2e11bd7682f9c59263c3,93cdab59e44294fad63451fbe650d591df7afabe..9ee88dd601493a03f910e583dd674801a0bf811c
@@@ -131,7 -131,6 +131,7 @@@ use crate::hint::spin_loop
  /// loads and stores of `u8`.
  #[cfg(target_has_atomic_load_store = "8")]
  #[stable(feature = "rust1", since = "1.0.0")]
 +#[rustc_diagnostic_item = "AtomicBool"]
  #[repr(C, align(1))]
  pub struct AtomicBool {
      v: UnsafeCell<u8>,
@@@ -334,10 -333,10 +334,10 @@@ impl AtomicBool 
      #[inline]
      #[cfg(target_has_atomic_equal_alignment = "8")]
      #[unstable(feature = "atomic_from_mut", issue = "76314")]
 -    pub fn from_mut(v: &mut bool) -> &Self {
 +    pub fn from_mut(v: &mut bool) -> &mut Self {
          // SAFETY: the mutable reference guarantees unique ownership, and
          // alignment of both `bool` and `Self` is 1.
 -        unsafe { &*(v as *mut bool as *mut Self) }
 +        unsafe { &mut *(v as *mut bool as *mut Self) }
      }
  
      /// Consumes the atomic and returns the contained value.
@@@ -935,14 -934,14 +935,14 @@@ impl<T> AtomicPtr<T> 
      #[inline]
      #[cfg(target_has_atomic_equal_alignment = "ptr")]
      #[unstable(feature = "atomic_from_mut", issue = "76314")]
 -    pub fn from_mut(v: &mut *mut T) -> &Self {
 +    pub fn from_mut(v: &mut *mut T) -> &mut Self {
          use crate::mem::align_of;
          let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
          // SAFETY:
          //  - the mutable reference guarantees unique ownership.
          //  - the alignment of `*mut T` and `Self` is the same on all platforms
          //    supported by rust, as verified above.
 -        unsafe { &*(v as *mut *mut T as *mut Self) }
 +        unsafe { &mut *(v as *mut *mut T as *mut Self) }
      }
  
      /// Consumes the atomic and returns the contained value.
@@@ -1295,6 -1294,7 +1295,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)
@@@ -1448,14 -1448,14 +1449,14 @@@ macro_rules! atomic_int 
              #[inline]
              #[$cfg_align]
              #[unstable(feature = "atomic_from_mut", issue = "76314")]
 -            pub fn from_mut(v: &mut $int_type) -> &Self {
 +            pub fn from_mut(v: &mut $int_type) -> &mut Self {
                  use crate::mem::align_of;
                  let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
                  // SAFETY:
                  //  - the mutable reference guarantees unique ownership.
                  //  - the alignment of `$int_type` and `Self` is the
                  //    same, as promised by $cfg_align and verified above.
 -                unsafe { &*(v as *mut $int_type as *mut Self) }
 +                unsafe { &mut *(v as *mut $int_type as *mut Self) }
              }
  
              /// Consumes the atomic and returns the contained value.
index c3f024026efad027534fa69de42ec34e28b16ee9,62b6eefbe1866432817b53ee0f0b5f71bbf0ee79..6e70d5ca02d7532f48359ce5bc2cb98f129a294c
@@@ -373,61 -373,38 +373,61 @@@ impl CString 
      /// the position of the nul byte.
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
 -        trait SpecIntoVec {
 -            fn into_vec(self) -> Vec<u8>;
 +        trait SpecNewImpl {
 +            fn spec_new_impl(self) -> Result<CString, NulError>;
          }
 -        impl<T: Into<Vec<u8>>> SpecIntoVec for T {
 -            default fn into_vec(self) -> Vec<u8> {
 -                self.into()
 +
 +        impl<T: Into<Vec<u8>>> SpecNewImpl for T {
 +            default fn spec_new_impl(self) -> Result<CString, NulError> {
 +                let bytes: Vec<u8> = self.into();
 +                match memchr::memchr(0, &bytes) {
 +                    Some(i) => Err(NulError(i, bytes)),
 +                    None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
 +                }
              }
          }
 -        // Specialization for avoiding reallocation.
 -        impl SpecIntoVec for &'_ [u8] {
 -            fn into_vec(self) -> Vec<u8> {
 -                let mut v = Vec::with_capacity(self.len() + 1);
 -                v.extend(self);
 -                v
 +
 +        // Specialization for avoiding reallocation
 +        #[inline(always)] // Without that it is not inlined into specializations
 +        fn spec_new_impl_bytes(bytes: &[u8]) -> Result<CString, NulError> {
 +            // We cannot have such large slice that we would overflow here
 +            // but using `checked_add` allows LLVM to assume that capacity never overflows
 +            // and generate twice shorter code.
 +            // `saturating_add` doesn't help for some reason.
 +            let capacity = bytes.len().checked_add(1).unwrap();
 +
 +            // Allocate before validation to avoid duplication of allocation code.
 +            // We still need to allocate and copy memory even if we get an error.
 +            let mut buffer = Vec::with_capacity(capacity);
 +            buffer.extend(bytes);
 +
 +            // Check memory of self instead of new buffer.
 +            // This allows better optimizations if lto enabled.
 +            match memchr::memchr(0, bytes) {
 +                Some(i) => Err(NulError(i, buffer)),
 +                None => Ok(unsafe { CString::from_vec_unchecked(buffer) }),
              }
          }
 -        impl SpecIntoVec for &'_ str {
 -            fn into_vec(self) -> Vec<u8> {
 -                let mut v = Vec::with_capacity(self.len() + 1);
 -                v.extend(self.as_bytes());
 -                v
 +
 +        impl SpecNewImpl for &'_ [u8] {
 +            fn spec_new_impl(self) -> Result<CString, NulError> {
 +                spec_new_impl_bytes(self)
              }
          }
  
 -        Self::_new(SpecIntoVec::into_vec(t))
 -    }
 +        impl SpecNewImpl for &'_ str {
 +            fn spec_new_impl(self) -> Result<CString, NulError> {
 +                spec_new_impl_bytes(self.as_bytes())
 +            }
 +        }
  
 -    fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
 -        match memchr::memchr(0, &bytes) {
 -            Some(i) => Err(NulError(i, bytes)),
 -            None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
 +        impl SpecNewImpl for &'_ mut [u8] {
 +            fn spec_new_impl(self) -> Result<CString, NulError> {
 +                spec_new_impl_bytes(self)
 +            }
          }
 +
 +        t.spec_new_impl()
      }
  
      /// Creates a C-compatible string by consuming a byte vector,
@@@ -871,6 -848,8 +871,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()
  
  #[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) }
  
  #[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 {
@@@ -973,8 -956,7 +979,8 @@@ impl<'a> From<&'a CString> for Cow<'a, 
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<CString> for Arc<CStr> {
 -    /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> without copying or allocating.
 +    /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> by moving the [`CString`]
 +    /// data into a new [`Arc`] buffer.
      #[inline]
      fn from(s: CString) -> Arc<CStr> {
          let arc: Arc<[u8]> = Arc::from(s.into_inner());
  
  #[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());
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<CString> for Rc<CStr> {
 -    /// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> without copying or allocating.
 +    /// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> by moving the [`CString`]
 +    /// data into a new [`Arc`] buffer.
      #[inline]
      fn from(s: CString) -> Rc<CStr> {
          let rc: Rc<[u8]> = Rc::from(s.into_inner());
  
  #[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());
@@@ -1077,7 -1062,7 +1087,7 @@@ impl fmt::Display for NulError 
  impl From<NulError> for io::Error {
      /// Converts a [`NulError`] into a [`io::Error`].
      fn from(_: NulError) -> io::Error {
 -        io::Error::new_const(io::ErrorKind::InvalidInput, &"data provided contains a nul byte")
 +        io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
      }
  }
  
@@@ -1252,16 -1237,15 +1262,16 @@@ impl CStr 
      /// assert!(cstr.is_err());
      /// ```
      #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
 -    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> {
 +    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
          let nul_pos = memchr::memchr(0, bytes);
 -        if let Some(nul_pos) = nul_pos {
 -            if nul_pos + 1 != bytes.len() {
 -                return Err(FromBytesWithNulError::interior_nul(nul_pos));
 +        match nul_pos {
 +            Some(nul_pos) if nul_pos + 1 == bytes.len() => {
 +                // SAFETY: We know there is only one nul byte, at the end
 +                // of the byte slice.
 +                Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
              }
 -            Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) })
 -        } else {
 -            Err(FromBytesWithNulError::not_nul_terminated())
 +            Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
 +            None => Err(FromBytesWithNulError::not_nul_terminated()),
          }
      }
  
      #[inline]
      #[must_use]
      #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
 -    #[rustc_const_unstable(feature = "const_cstr_unchecked", issue = "90343")]
 +    #[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")]
      pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
          // SAFETY: Casting to CStr is safe because its internal representation
          // is a [u8] too (safe only inside std).
@@@ -1530,6 -1514,7 +1540,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()
      }
index 81f72e34d93889fdd1a4216abaa35af97a09e6e5,7bb2ff6770ec5d894e90adedfafa5bf291a60dd2..9b5e5d6c0cc4b1d377896ba1ba8d7dc444a2bfe3
@@@ -3,7 -3,6 +3,7 @@@ mod tests
  
  use crate::borrow::{Borrow, Cow};
  use crate::cmp;
 +use crate::collections::TryReserveError;
  use crate::fmt;
  use crate::hash::{Hash, Hasher};
  use crate::iter::{Extend, FromIterator};
@@@ -266,43 -265,6 +266,43 @@@ impl OsString 
          self.inner.reserve(additional)
      }
  
 +    /// Tries to reserve capacity for at least `additional` more length units
 +    /// in the given `OsString`. The string may reserve more space to avoid
 +    /// frequent reallocations. After calling `try_reserve`, capacity will be
 +    /// greater than or equal to `self.len() + additional`. Does nothing if
 +    /// capacity is already sufficient.
 +    ///
 +    /// # Errors
 +    ///
 +    /// If the capacity overflows, or the allocator reports a failure, then an error
 +    /// is returned.
 +    ///
 +    /// # Examples
 +    ///
 +    /// ```
 +    /// #![feature(try_reserve_2)]
 +    /// use std::ffi::{OsStr, OsString};
 +    /// use std::collections::TryReserveError;
 +    ///
 +    /// fn process_data(data: &str) -> Result<OsString, TryReserveError> {
 +    ///     let mut s = OsString::new();
 +    ///
 +    ///     // Pre-reserve the memory, exiting if we can't
 +    ///     s.try_reserve(OsStr::new(data).len())?;
 +    ///
 +    ///     // Now we know this can't OOM in the middle of our complex work
 +    ///     s.push(data);
 +    ///
 +    ///     Ok(s)
 +    /// }
 +    /// # process_data("123").expect("why is the test harness OOMing on 3 bytes?");
 +    /// ```
 +    #[unstable(feature = "try_reserve_2", issue = "91789")]
 +    #[inline]
 +    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
 +        self.inner.try_reserve(additional)
 +    }
 +
      /// Reserves the minimum capacity for exactly `additional` more capacity to
      /// be inserted in the given `OsString`. Does nothing if the capacity is
      /// already sufficient.
          self.inner.reserve_exact(additional)
      }
  
 +    /// Tries to reserve the minimum capacity for exactly `additional`
 +    /// more length units in the given `OsString`. After calling
 +    /// `try_reserve_exact`, capacity will be greater than or equal to
 +    /// `self.len() + additional` if it returns `Ok(())`.
 +    /// Does nothing if the capacity is already sufficient.
 +    ///
 +    /// Note that the allocator may give the `OsString` more space than it
 +    /// requests. Therefore, capacity can not be relied upon to be precisely
 +    /// minimal. Prefer [`try_reserve`] if future insertions are expected.
 +    ///
 +    /// [`try_reserve`]: OsString::try_reserve
 +    ///
 +    /// # Errors
 +    ///
 +    /// If the capacity overflows, or the allocator reports a failure, then an error
 +    /// is returned.
 +    ///
 +    /// # Examples
 +    ///
 +    /// ```
 +    /// #![feature(try_reserve_2)]
 +    /// use std::ffi::{OsStr, OsString};
 +    /// use std::collections::TryReserveError;
 +    ///
 +    /// fn process_data(data: &str) -> Result<OsString, TryReserveError> {
 +    ///     let mut s = OsString::new();
 +    ///
 +    ///     // Pre-reserve the memory, exiting if we can't
 +    ///     s.try_reserve_exact(OsStr::new(data).len())?;
 +    ///
 +    ///     // Now we know this can't OOM in the middle of our complex work
 +    ///     s.push(data);
 +    ///
 +    ///     Ok(s)
 +    /// }
 +    /// # process_data("123").expect("why is the test harness OOMing on 3 bytes?");
 +    /// ```
 +    #[unstable(feature = "try_reserve_2", issue = "91789")]
 +    #[inline]
 +    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
 +        self.inner.try_reserve_exact(additional)
 +    }
 +
      /// Shrinks the capacity of the `OsString` to match its length.
      ///
      /// # Examples
@@@ -452,6 -371,8 +452,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()
      }
@@@ -942,6 -863,7 +944,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;
  
  #[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 {
@@@ -989,8 -913,7 +994,8 @@@ impl Clone for Box<OsStr> 
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<OsString> for Arc<OsStr> {
 -    /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> without copying or allocating.
 +    /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> by moving the [`OsString`]
 +    /// data into a new [`Arc`] buffer.
      #[inline]
      fn from(s: OsString) -> Arc<OsStr> {
          let arc = s.inner.into_arc();
  
  #[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();
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<OsString> for Rc<OsStr> {
 -    /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> without copying or allocating.
 +    /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> by moving the [`OsString`]
 +    /// data into a new [`Rc`] buffer.
      #[inline]
      fn from(s: OsString) -> Rc<OsStr> {
          let rc = s.inner.into_rc();
  
  #[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();
  
  #[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)
  
  #[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)
  
  #[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())
  
  #[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()
diff --combined library/std/src/path.rs
index 3f7f0f888476a3654f4c715167d8de7a24c9142c,a4d0119c2a06351939fca6d039826b32cd07aae7..adb8b30ec08930b0c7c8827e4f580e67c2576dee
@@@ -72,7 -72,6 +72,7 @@@ mod tests
  
  use crate::borrow::{Borrow, Cow};
  use crate::cmp;
 +use crate::collections::TryReserveError;
  use crate::error::Error;
  use crate::fmt;
  use crate::fs;
@@@ -85,7 -84,7 +85,7 @@@ use crate::str::FromStr
  use crate::sync::Arc;
  
  use crate::ffi::{OsStr, OsString};
 -
 +use crate::sys;
  use crate::sys::path::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR};
  
  ////////////////////////////////////////////////////////////////////////////////
@@@ -1513,15 -1512,6 +1513,15 @@@ impl PathBuf 
          self.inner.reserve(additional)
      }
  
 +    /// Invokes [`try_reserve`] on the underlying instance of [`OsString`].
 +    ///
 +    /// [`try_reserve`]: OsString::try_reserve
 +    #[unstable(feature = "try_reserve_2", issue = "91789")]
 +    #[inline]
 +    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
 +        self.inner.try_reserve(additional)
 +    }
 +
      /// Invokes [`reserve_exact`] on the underlying instance of [`OsString`].
      ///
      /// [`reserve_exact`]: OsString::reserve_exact
          self.inner.reserve_exact(additional)
      }
  
 +    /// Invokes [`try_reserve_exact`] on the underlying instance of [`OsString`].
 +    ///
 +    /// [`try_reserve_exact`]: OsString::try_reserve_exact
 +    #[unstable(feature = "try_reserve_2", issue = "91789")]
 +    #[inline]
 +    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
 +        self.inner.try_reserve_exact(additional)
 +    }
 +
      /// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`].
      ///
      /// [`shrink_to_fit`]: OsString::shrink_to_fit
@@@ -1600,7 -1581,7 +1600,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]
  
  #[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.
@@@ -1631,7 -1612,7 +1631,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]
@@@ -1785,8 -1766,7 +1785,8 @@@ impl<'a> From<Cow<'a, Path>> for PathBu
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<PathBuf> for Arc<Path> {
 -    /// Converts a [`PathBuf`] into an [`Arc`] by moving the [`PathBuf`] data into a new [`Arc`] buffer.
 +    /// Converts a [`PathBuf`] into an <code>[Arc]<[Path]></code> by moving the [`PathBuf`] data
 +    /// into a new [`Arc`] buffer.
      #[inline]
      fn from(s: PathBuf) -> Arc<Path> {
          let arc: Arc<OsStr> = Arc::from(s.into_os_string());
@@@ -1806,8 -1786,7 +1806,8 @@@ impl From<&Path> for Arc<Path> 
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<PathBuf> for Rc<Path> {
 -    /// Converts a [`PathBuf`] into an [`Rc`] by moving the [`PathBuf`] data into a new `Rc` buffer.
 +    /// Converts a [`PathBuf`] into an <code>[Rc]<[Path]></code> by moving the [`PathBuf`] data into
 +    /// a new [`Rc`] buffer.
      #[inline]
      fn from(s: PathBuf) -> Rc<Path> {
          let rc: Rc<OsStr> = Rc::from(s.into_os_string());
  
  #[stable(feature = "shared_from_slice2", since = "1.24.0")]
  impl From<&Path> for Rc<Path> {
 -    /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new `Rc` buffer.
 +    /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer.
      #[inline]
      fn from(s: &Path) -> Rc<Path> {
          let rc: Rc<OsStr> = Rc::from(s.as_os_str());
@@@ -2730,7 -2709,7 +2730,7 @@@ impl Path 
      /// This function will traverse symbolic links to query information about the
      /// destination file. In case of broken symbolic links this will return `Ok(false)`.
      ///
 -    /// As opposed to the `exists()` method, this one doesn't silently ignore errors
 +    /// As opposed to the [`exists()`] method, this one doesn't silently ignore errors
      /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
      /// denied on some of the parent directories.)
      ///
      /// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
      /// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
      /// ```
 +    ///
 +    /// [`exists()`]: Self::exists
      // FIXME: stabilization should modify documentation of `exists()` to recommend this method
      // instead.
      #[unstable(feature = "path_try_exists", issue = "83186")]
      /// use std::os::unix::fs::symlink;
      ///
      /// let link_path = Path::new("link");
 -    /// symlink("/origin_does_not_exists/", link_path).unwrap();
 +    /// symlink("/origin_does_not_exist/", link_path).unwrap();
      /// assert_eq!(link_path.is_symlink(), true);
      /// assert_eq!(link_path.exists(), false);
      /// ```
      /// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call
      /// [`fs::Metadata::is_symlink`] if it was [`Ok`].
      #[must_use]
 -    #[stable(feature = "is_symlink", since = "1.57.0")]
 +    #[stable(feature = "is_symlink", since = "1.58.0")]
      pub fn is_symlink(&self) -> bool {
          fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
      }
@@@ -2922,12 -2899,12 +2922,12 @@@ impl cmp::PartialEq for Path 
  impl Hash for Path {
      fn hash<H: Hasher>(&self, h: &mut H) {
          let bytes = self.as_u8_slice();
 -        let prefix_len = match parse_prefix(&self.inner) {
 +        let (prefix_len, verbatim) = match parse_prefix(&self.inner) {
              Some(prefix) => {
                  prefix.hash(h);
 -                prefix.len()
 +                (prefix.len(), prefix.is_verbatim())
              }
 -            None => 0,
 +            None => (0, false),
          };
          let bytes = &bytes[prefix_len..];
  
          let mut bytes_hashed = 0;
  
          for i in 0..bytes.len() {
 -            if is_sep_byte(bytes[i]) {
 +            let is_sep = if verbatim { is_verbatim_sep(bytes[i]) } else { is_sep_byte(bytes[i]) };
 +            if is_sep {
                  if i > component_start {
                      let to_hash = &bytes[component_start..i];
                      h.write(to_hash);
                  }
  
                  // skip over separator and optionally a following CurDir item
 -                // since components() would normalize these away
 -                component_start = i + match bytes[i..] {
 -                    [_, b'.', b'/', ..] | [_, b'.'] => 2,
 -                    _ => 1,
 -                };
 +                // since components() would normalize these away.
 +                component_start = i + 1;
 +
 +                let tail = &bytes[component_start..];
 +
 +                if !verbatim {
 +                    component_start += match tail {
 +                        [b'.'] => 1,
 +                        [b'.', sep @ _, ..] if is_sep_byte(*sep) => 1,
 +                        _ => 0,
 +                    };
 +                }
              }
          }
  
@@@ -3172,79 -3141,3 +3172,79 @@@ impl Error for StripPrefixError 
          "prefix not found"
      }
  }
 +
 +/// Makes the path absolute without accessing the filesystem.
 +///
 +/// If the path is relative, the current directory is used as the base directory.
 +/// All intermediate components will be resolved according to platforms-specific
 +/// rules but unlike [`canonicalize`][crate::fs::canonicalize] this does not
 +/// resolve symlinks and may succeed even if the path does not exist.
 +///
 +/// If the `path` is empty or getting the
 +/// [current directory][crate::env::current_dir] fails then an error will be
 +/// returned.
 +///
 +/// # Examples
 +///
 +/// ## Posix paths
 +///
 +/// ```
 +/// #![feature(absolute_path)]
 +/// # #[cfg(unix)]
 +/// fn main() -> std::io::Result<()> {
 +///   use std::path::{self, Path};
 +///
 +///   // Relative to absolute
 +///   let absolute = path::absolute("foo/./bar")?;
 +///   assert!(absolute.ends_with("foo/bar"));
 +///
 +///   // Absolute to absolute
 +///   let absolute = path::absolute("/foo//test/.././bar.rs")?;
 +///   assert_eq!(absolute, Path::new("/foo/test/../bar.rs"));
 +///   Ok(())
 +/// }
 +/// # #[cfg(not(unix))]
 +/// # fn main() {}
 +/// ```
 +///
 +/// The path is resolved using [POSIX semantics][posix-semantics] except that
 +/// it stops short of resolving symlinks. This means it will keep `..`
 +/// components and trailing slashes.
 +///
 +/// ## Windows paths
 +///
 +/// ```
 +/// #![feature(absolute_path)]
 +/// # #[cfg(windows)]
 +/// fn main() -> std::io::Result<()> {
 +///   use std::path::{self, Path};
 +///
 +///   // Relative to absolute
 +///   let absolute = path::absolute("foo/./bar")?;
 +///   assert!(absolute.ends_with(r"foo\bar"));
 +///
 +///   // Absolute to absolute
 +///   let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?;
 +///
 +///   assert_eq!(absolute, Path::new(r"C:\foo\bar.rs"));
 +///   Ok(())
 +/// }
 +/// # #[cfg(not(windows))]
 +/// # fn main() {}
 +/// ```
 +///
 +/// For verbatim paths this will simply return the path as given. For other
 +/// paths this is currently equivalent to calling [`GetFullPathNameW`][windows-path]
 +/// This may change in the future.
 +///
 +/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
 +/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
 +#[unstable(feature = "absolute_path", issue = "92750")]
 +pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 +    let path = path.as_ref();
 +    if path.as_os_str().is_empty() {
 +        Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
 +    } else {
 +        sys::path::absolute(path)
 +    }
 +}
index 1f04890539604e98d04e4cf8b60f0ae68a65f38d,ae39997de62127e69b7f55692a98f8fa49c5882b..e3fff155e47224b6728fa5c355d4de98ca9acbe1
@@@ -110,7 -110,7 +110,7 @@@ use crate::convert::Infallible
  use crate::ffi::OsStr;
  use crate::fmt;
  use crate::fs;
 -use crate::io::{self, Initializer, IoSlice, IoSliceMut};
 +use crate::io::{self, IoSlice, IoSliceMut};
  use crate::num::NonZeroI32;
  use crate::path::Path;
  use crate::str;
@@@ -362,6 -362,12 +362,6 @@@ impl Read for ChildStdout 
      fn is_read_vectored(&self) -> bool {
          self.inner.is_read_vectored()
      }
 -
 -    #[inline]
 -    unsafe fn initializer(&self) -> Initializer {
 -        // SAFETY: Read is guaranteed to work on uninitialized memory
 -        unsafe { Initializer::nop() }
 -    }
  }
  
  impl AsInner<AnonPipe> for ChildStdout {
@@@ -423,6 -429,12 +423,6 @@@ impl Read for ChildStderr 
      fn is_read_vectored(&self) -> bool {
          self.inner.is_read_vectored()
      }
 -
 -    #[inline]
 -    unsafe fn initializer(&self) -> Initializer {
 -        // SAFETY: Read is guaranteed to work on uninitialized memory
 -        unsafe { Initializer::nop() }
 -    }
  }
  
  impl AsInner<AnonPipe> for ChildStderr {
@@@ -1277,7 -1289,7 +1277,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
      ///
  
  #[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
      ///
  
  #[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
      ///
  
  #[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
      ///
@@@ -1600,6 -1612,7 +1600,6 @@@ impl ExitStatusError 
      /// ```
      /// #![feature(exit_status_error)]
      /// # if cfg!(unix) {
 -    /// use std::convert::TryFrom;
      /// use std::num::NonZeroI32;
      /// use std::process::Command;
      ///
@@@ -1676,29 -1689,6 +1676,29 @@@ impl ExitCode 
      pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
  }
  
 +impl ExitCode {
 +    // This should not be stabilized when stabilizing ExitCode, we don't know that i32 will serve
 +    // all usecases, for example windows seems to use u32, unix uses the 8-15th bits of an i32, we
 +    // likely want to isolate users anything that could restrict the platform specific
 +    // representation of an ExitCode
 +    //
 +    // More info: https://internals.rust-lang.org/t/mini-pre-rfc-redesigning-process-exitstatus/5426
 +    /// Convert an ExitCode into an i32
 +    #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
 +    #[inline]
 +    pub fn to_i32(self) -> i32 {
 +        self.0.as_i32()
 +    }
 +}
 +
 +#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
 +impl From<u8> for ExitCode {
 +    /// Construct an exit code from an arbitrary u8 value.
 +    fn from(code: u8) -> Self {
 +        ExitCode(imp::ExitCode::from(code))
 +    }
 +}
 +
  impl Child {
      /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
      /// error is returned.
@@@ -2039,20 -2029,20 +2039,20 @@@ pub fn id() -> u32 
  pub trait Termination {
      /// Is called to get the representation of the value as status code.
      /// This status code is returned to the operating system.
 -    fn report(self) -> i32;
 +    fn report(self) -> ExitCode;
  }
  
  #[unstable(feature = "termination_trait_lib", issue = "43301")]
  impl Termination for () {
      #[inline]
 -    fn report(self) -> i32 {
 +    fn report(self) -> ExitCode {
          ExitCode::SUCCESS.report()
      }
  }
  
  #[unstable(feature = "termination_trait_lib", issue = "43301")]
  impl<E: fmt::Debug> Termination for Result<(), E> {
 -    fn report(self) -> i32 {
 +    fn report(self) -> ExitCode {
          match self {
              Ok(()) => ().report(),
              Err(err) => Err::<!, _>(err).report(),
  
  #[unstable(feature = "termination_trait_lib", issue = "43301")]
  impl Termination for ! {
 -    fn report(self) -> i32 {
 +    fn report(self) -> ExitCode {
          self
      }
  }
  
  #[unstable(feature = "termination_trait_lib", issue = "43301")]
  impl<E: fmt::Debug> Termination for Result<!, E> {
 -    fn report(self) -> i32 {
 +    fn report(self) -> ExitCode {
          let Err(err) = self;
          eprintln!("Error: {:?}", err);
          ExitCode::FAILURE.report()
  
  #[unstable(feature = "termination_trait_lib", issue = "43301")]
  impl<E: fmt::Debug> Termination for Result<Infallible, E> {
 -    fn report(self) -> i32 {
 +    fn report(self) -> ExitCode {
          let Err(err) = self;
          Err::<!, _>(err).report()
      }
  #[unstable(feature = "termination_trait_lib", issue = "43301")]
  impl Termination for ExitCode {
      #[inline]
 -    fn report(self) -> i32 {
 -        self.0.as_i32()
 +    fn report(self) -> ExitCode {
 +        self
      }
  }