Skip to content

Commit

Permalink
Rollup merge of rust-lang#93109 - JakobDegen:arc-docs, r=m-ou-se
Browse files Browse the repository at this point in the history
Improve `Arc` and `Rc` documentation

This makes two changes (I can split the PR if necessary, but the changes are pretty small):
 1. A bunch of trait implementations claimed to be zero cost; however, they use the `Arc<T>: From<Box<T>>` impl which is definitely not free, especially for large dynamically sized `T`.
 2.  The code in deferred initialization examples unnecessarily used excessive amounts of `unsafe`. This has been reduced.
  • Loading branch information
matthiaskrgr authored Jan 21, 2022
2 parents ab19d4a + 4de7618 commit 9474c74
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 65 deletions.
50 changes: 21 additions & 29 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,12 +451,10 @@ impl<T> Rc<T> {
///
/// let mut five = Rc::<u32>::new_uninit();
///
/// let five = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
/// // Deferred initialization:
/// Rc::get_mut(&mut five).unwrap().write(5);
///
/// five.assume_init()
/// };
/// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5)
/// ```
Expand Down Expand Up @@ -543,12 +541,10 @@ impl<T> Rc<T> {
///
/// let mut five = Rc::<u32>::try_new_uninit()?;
///
/// let five = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
/// // Deferred initialization:
/// Rc::get_mut(&mut five).unwrap().write(5);
///
/// five.assume_init()
/// };
/// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5);
/// # Ok::<(), std::alloc::AllocError>(())
Expand Down Expand Up @@ -660,14 +656,13 @@ impl<T> Rc<[T]> {
///
/// let mut values = Rc::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
/// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
/// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
/// // Deferred initialization:
/// let data = Rc::get_mut(&mut values).unwrap();
/// data[0].write(1);
/// data[1].write(2);
/// data[2].write(3);
///
/// values.assume_init()
/// };
/// let values = unsafe { values.assume_init() };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
Expand Down Expand Up @@ -738,12 +733,10 @@ impl<T> Rc<mem::MaybeUninit<T>> {
///
/// let mut five = Rc::<u32>::new_uninit();
///
/// let five = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
/// // Deferred initialization:
/// Rc::get_mut(&mut five).unwrap().write(5);
///
/// five.assume_init()
/// };
/// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5)
/// ```
Expand Down Expand Up @@ -777,14 +770,13 @@ impl<T> Rc<[mem::MaybeUninit<T>]> {
///
/// let mut values = Rc::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
/// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
/// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
/// // Deferred initialization:
/// let data = Rc::get_mut(&mut values).unwrap();
/// data[0].write(1);
/// data[1].write(2);
/// data[2].write(3);
///
/// values.assume_init()
/// };
/// let values = unsafe { values.assume_init() };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
Expand Down
50 changes: 21 additions & 29 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,12 +437,10 @@ impl<T> Arc<T> {
///
/// let mut five = Arc::<u32>::new_uninit();
///
/// let five = unsafe {
/// // Deferred initialization:
/// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
/// // Deferred initialization:
/// Arc::get_mut(&mut five).unwrap().write(5);
///
/// five.assume_init()
/// };
/// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5)
/// ```
Expand Down Expand Up @@ -545,12 +543,10 @@ impl<T> Arc<T> {
///
/// let mut five = Arc::<u32>::try_new_uninit()?;
///
/// let five = unsafe {
/// // Deferred initialization:
/// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
/// // Deferred initialization:
/// Arc::get_mut(&mut five).unwrap().write(5);
///
/// five.assume_init()
/// };
/// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5);
/// # Ok::<(), std::alloc::AllocError>(())
Expand Down Expand Up @@ -652,14 +648,13 @@ impl<T> Arc<[T]> {
///
/// let mut values = Arc::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
/// // Deferred initialization:
/// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
/// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
/// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
/// // Deferred initialization:
/// let data = Arc::get_mut(&mut values).unwrap();
/// data[0].write(1);
/// data[1].write(2);
/// data[2].write(3);
///
/// values.assume_init()
/// };
/// let values = unsafe { values.assume_init() };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
Expand Down Expand Up @@ -730,12 +725,10 @@ impl<T> Arc<mem::MaybeUninit<T>> {
///
/// let mut five = Arc::<u32>::new_uninit();
///
/// let five = unsafe {
/// // Deferred initialization:
/// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
/// // Deferred initialization:
/// Arc::get_mut(&mut five).unwrap().write(5);
///
/// five.assume_init()
/// };
/// let five = unsafe { five.assume_init() };
///
/// assert_eq!(*five, 5)
/// ```
Expand Down Expand Up @@ -770,14 +763,13 @@ impl<T> Arc<[mem::MaybeUninit<T>]> {
///
/// let mut values = Arc::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
/// // Deferred initialization:
/// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
/// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
/// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
/// // Deferred initialization:
/// let data = Arc::get_mut(&mut values).unwrap();
/// data[0].write(1);
/// data[1].write(2);
/// data[2].write(3);
///
/// values.assume_init()
/// };
/// let values = unsafe { values.assume_init() };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
Expand Down
6 changes: 4 additions & 2 deletions library/std/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,8 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> {

#[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());
Expand All @@ -992,7 +993,8 @@ impl From<&CStr> for Arc<CStr> {

#[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());
Expand Down
6 changes: 4 additions & 2 deletions library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,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();
Expand All @@ -1008,7 +1009,8 @@ impl From<&OsStr> for Arc<OsStr> {

#[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();
Expand Down
8 changes: 5 additions & 3 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,8 @@ impl<'a> From<Cow<'a, Path>> for PathBuf {

#[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());
Expand All @@ -1786,7 +1787,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());
Expand All @@ -1796,7 +1798,7 @@ impl From<PathBuf> for Rc<Path> {

#[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());
Expand Down

0 comments on commit 9474c74

Please sign in to comment.