Repository: rust-lang/rust
File: library/alloc/src/rc.rs (Rust)

Code before:

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Rc<T> {
    /// Creates a new `Rc<T>`, with the `Default` value for `T`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::rc::Rc;
    ///
    /// let x: Rc<i32> = Default::default();
    /// assert_eq!(*x, 0);
    /// ```
    #[inline]
    fn default() -> Self {
        // First create an uninitialized allocation before creating an instance
        // of `T`. This avoids having `T` on the stack and avoids the need to
        // codegen a call to the destructor for `T` leading to generally better
        // codegen. See #131460 for some more details.
        let mut rc = Rc::new_uninit();

        // SAFETY: this is a freshly allocated `Rc` so it's guaranteed there are
        // no other strong or weak pointers other than `rc` itself.
        unsafe {
            Rc::get_mut_unchecked(&mut rc).write(T::default());
        }

        // SAFETY: this allocation was just initialized above.
        unsafe { rc.assume_init() }
    }
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "more_rc_default_impls", since = "1.80.0")]
impl Default for Rc<str> {
    /// Creates an empty `str` inside an `Rc`.
    ///
    /// This may or may not share an allocation with other Rcs on the same thread.
    #[inline]
    fn default() -> Self {
        let rc = Rc::<[u8]>::default();
        // `[u8]` has the same layout as `str`.
        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) }
    }
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "more_rc_default_impls", since = "1.80.0")]
impl<T> Default for Rc<[T]> {
    /// Creates an empty `[T]` inside an `Rc`.

Review comment (bug):
`Box::default` uses `ptr::write` here to avoid unnecessary stack copies of `T` even in debug mode...

Code after:

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Rc<T> {
    /// Creates a new `Rc<T>`, with the `Default` value for `T`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::rc::Rc;
    ///
    /// let x: Rc<i32> = Default::default();
    /// assert_eq!(*x, 0);
    /// ```
    #[inline]
    fn default() -> Self {
        // First create an uninitialized allocation before creating an instance
        // of `T`. This avoids having `T` on the stack and avoids the need to
        // codegen a call to the destructor for `T` leading to generally better
        // codegen. See #131460 for some more details.
        let mut rc = Rc::new_uninit();

        // SAFETY: this is a freshly allocated `Rc` so it's guaranteed there are
        // no other strong or weak pointers other than `rc` itself.
        unsafe {
            let raw = Rc::get_mut_unchecked(&mut rc);

            // Note that `ptr::write` here is used specifically instead of
            // `MaybeUninit::write` to avoid creating an extra stack copy of `T`
            // in debug mode. See #136043 for more context.
            ptr::write(raw.as_mut_ptr(), T::default());
        }

        // SAFETY: this allocation was just initialized above.
        unsafe { rc.assume_init() }
    }
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "more_rc_default_impls", since = "1.80.0")]
impl Default for Rc<str> {
    /// Creates an empty `str` inside an `Rc`.
    ///
    /// This may or may not share an allocation with other Rcs on the same thread.
    #[inline]
    fn default() -> Self {
        let rc = Rc::<[u8]>::default();
        // `[u8]` has the same layout as `str`.
        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) }
    }
}