@@ -327,6 +327,37 @@ impl<T> Rc<T> {
327327 } ) )
328328 }
329329
330+ /// Constructs a new `Rc` with uninitialized contents.
331+ ///
332+ /// # Examples
333+ ///
334+ /// ```
335+ /// #![feature(new_uninit)]
336+ /// #![feature(get_mut_unchecked)]
337+ ///
338+ /// use std::rc::Rc;
339+ ///
340+ /// let mut five = Rc::<u32>::new_uninit();
341+ ///
342+ /// let five = unsafe {
343+ /// // Deferred initialization:
344+ /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
345+ ///
346+ /// five.assume_init()
347+ /// };
348+ ///
349+ /// assert_eq!(*five, 5)
350+ /// ```
351+ #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
352+ pub fn new_uninit ( ) -> Rc < mem:: MaybeUninit < T > > {
353+ unsafe {
354+ Rc :: from_ptr ( Rc :: allocate_for_layout (
355+ Layout :: new :: < T > ( ) ,
356+ |mem| mem as * mut RcBox < mem:: MaybeUninit < T > > ,
357+ ) )
358+ }
359+ }
360+
330361 /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
331362 /// `value` will be pinned in memory and unable to be moved.
332363 #[ stable( feature = "pin" , since = "1.33.0" ) ]
@@ -377,6 +408,118 @@ impl<T> Rc<T> {
377408 }
378409}
379410
411+ impl < T > Rc < [ T ] > {
412+ /// Constructs a new reference-counted slice with uninitialized contents.
413+ ///
414+ /// # Examples
415+ ///
416+ /// ```
417+ /// #![feature(new_uninit)]
418+ /// #![feature(get_mut_unchecked)]
419+ ///
420+ /// use std::rc::Rc;
421+ ///
422+ /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
423+ ///
424+ /// let values = unsafe {
425+ /// // Deferred initialization:
426+ /// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
427+ /// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
428+ /// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
429+ ///
430+ /// values.assume_init()
431+ /// };
432+ ///
433+ /// assert_eq!(*values, [1, 2, 3])
434+ /// ```
435+ #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
436+ pub fn new_uninit_slice ( len : usize ) -> Rc < [ mem:: MaybeUninit < T > ] > {
437+ unsafe {
438+ Rc :: from_ptr ( Rc :: allocate_for_slice ( len) )
439+ }
440+ }
441+ }
442+
443+ impl < T > Rc < mem:: MaybeUninit < T > > {
444+ /// Converts to `Rc<T>`.
445+ ///
446+ /// # Safety
447+ ///
448+ /// As with [`MaybeUninit::assume_init`],
449+ /// it is up to the caller to guarantee that the value
450+ /// really is in an initialized state.
451+ /// Calling this when the content is not yet fully initialized
452+ /// causes immediate undefined behavior.
453+ ///
454+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
455+ ///
456+ /// # Examples
457+ ///
458+ /// ```
459+ /// #![feature(new_uninit)]
460+ /// #![feature(get_mut_unchecked)]
461+ ///
462+ /// use std::rc::Rc;
463+ ///
464+ /// let mut five = Rc::<u32>::new_uninit();
465+ ///
466+ /// let five = unsafe {
467+ /// // Deferred initialization:
468+ /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
469+ ///
470+ /// five.assume_init()
471+ /// };
472+ ///
473+ /// assert_eq!(*five, 5)
474+ /// ```
475+ #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
476+ #[ inline]
477+ pub unsafe fn assume_init ( self ) -> Rc < T > {
478+ Rc :: from_inner ( mem:: ManuallyDrop :: new ( self ) . ptr . cast ( ) )
479+ }
480+ }
481+
482+ impl < T > Rc < [ mem:: MaybeUninit < T > ] > {
483+ /// Converts to `Rc<[T]>`.
484+ ///
485+ /// # Safety
486+ ///
487+ /// As with [`MaybeUninit::assume_init`],
488+ /// it is up to the caller to guarantee that the value
489+ /// really is in an initialized state.
490+ /// Calling this when the content is not yet fully initialized
491+ /// causes immediate undefined behavior.
492+ ///
493+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
494+ ///
495+ /// # Examples
496+ ///
497+ /// ```
498+ /// #![feature(new_uninit)]
499+ /// #![feature(get_mut_unchecked)]
500+ ///
501+ /// use std::rc::Rc;
502+ ///
503+ /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
504+ ///
505+ /// let values = unsafe {
506+ /// // Deferred initialization:
507+ /// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
508+ /// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
509+ /// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
510+ ///
511+ /// values.assume_init()
512+ /// };
513+ ///
514+ /// assert_eq!(*values, [1, 2, 3])
515+ /// ```
516+ #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
517+ #[ inline]
518+ pub unsafe fn assume_init ( self ) -> Rc < [ T ] > {
519+ Rc :: from_ptr ( mem:: ManuallyDrop :: new ( self ) . ptr . as_ptr ( ) as _ )
520+ }
521+ }
522+
380523impl < T : ?Sized > Rc < T > {
381524 /// Consumes the `Rc`, returning the wrapped pointer.
382525 ///
@@ -560,13 +703,46 @@ impl<T: ?Sized> Rc<T> {
560703 pub fn get_mut ( this : & mut Self ) -> Option < & mut T > {
561704 if Rc :: is_unique ( this) {
562705 unsafe {
563- Some ( & mut this . ptr . as_mut ( ) . value )
706+ Some ( Rc :: get_mut_unchecked ( this ) )
564707 }
565708 } else {
566709 None
567710 }
568711 }
569712
713+ /// Returns a mutable reference to the inner value,
714+ /// without any check.
715+ ///
716+ /// See also [`get_mut`], which is safe and does appropriate checks.
717+ ///
718+ /// [`get_mut`]: struct.Rc.html#method.get_mut
719+ ///
720+ /// # Safety
721+ ///
722+ /// Any other `Rc` or [`Weak`] pointers to the same value must not be dereferenced
723+ /// for the duration of the returned borrow.
724+ /// This is trivially the case if no such pointers exist,
725+ /// for example immediately after `Rc::new`.
726+ ///
727+ /// # Examples
728+ ///
729+ /// ```
730+ /// #![feature(get_mut_unchecked)]
731+ ///
732+ /// use std::rc::Rc;
733+ ///
734+ /// let mut x = Rc::new(String::new());
735+ /// unsafe {
736+ /// Rc::get_mut_unchecked(&mut x).push_str("foo")
737+ /// }
738+ /// assert_eq!(*x, "foo");
739+ /// ```
740+ #[ inline]
741+ #[ unstable( feature = "get_mut_unchecked" , issue = "63292" ) ]
742+ pub unsafe fn get_mut_unchecked ( this : & mut Self ) -> & mut T {
743+ & mut this. ptr . as_mut ( ) . value
744+ }
745+
570746 #[ inline]
571747 #[ stable( feature = "ptr_eq" , since = "1.17.0" ) ]
572748 /// Returns `true` if the two `Rc`s point to the same value (not
@@ -704,11 +880,11 @@ impl Rc<dyn Any> {
704880
705881impl < T : ?Sized > Rc < T > {
706882 /// Allocates an `RcBox<T>` with sufficient space for
707- /// an unsized value where the value has the layout provided.
883+ /// a possibly- unsized value where the value has the layout provided.
708884 ///
709885 /// The function `mem_to_rcbox` is called with the data pointer
710886 /// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
711- unsafe fn allocate_for_unsized (
887+ unsafe fn allocate_for_layout (
712888 value_layout : Layout ,
713889 mem_to_rcbox : impl FnOnce ( * mut u8 ) -> * mut RcBox < T >
714890 ) -> * mut RcBox < T > {
@@ -737,7 +913,7 @@ impl<T: ?Sized> Rc<T> {
737913 /// Allocates an `RcBox<T>` with sufficient space for an unsized value
738914 unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut RcBox < T > {
739915 // Allocate for the `RcBox<T>` using the given value.
740- Self :: allocate_for_unsized (
916+ Self :: allocate_for_layout (
741917 Layout :: for_value ( & * ptr) ,
742918 |mem| set_data_ptr ( ptr as * mut T , mem) as * mut RcBox < T > ,
743919 )
@@ -768,7 +944,7 @@ impl<T: ?Sized> Rc<T> {
768944impl < T > Rc < [ T ] > {
769945 /// Allocates an `RcBox<[T]>` with the given length.
770946 unsafe fn allocate_for_slice ( len : usize ) -> * mut RcBox < [ T ] > {
771- Self :: allocate_for_unsized (
947+ Self :: allocate_for_layout (
772948 Layout :: array :: < T > ( len) . unwrap ( ) ,
773949 |mem| ptr:: slice_from_raw_parts_mut ( mem as * mut T , len) as * mut RcBox < [ T ] > ,
774950 )
0 commit comments