@@ -346,28 +346,6 @@ impl<T> Rc<T> {
346346 )
347347 }
348348
349- /// Constructs a new `Rc<T>`.
350- ///
351- /// # Examples
352- ///
353- /// ```
354- /// #![feature(allocator_api, new_uninit)]
355- /// use std::rc::Rc;
356- ///
357- /// let five = Rc::new(5);
358- /// ```
359- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
360- pub fn try_new ( value : T ) -> Result < Rc < T > , AllocError > {
361- // There is an implicit weak pointer owned by all the strong
362- // pointers, which ensures that the weak destructor never frees
363- // the allocation while the strong destructor is running, even
364- // if the weak pointer is stored inside the strong one.
365- Ok ( Self :: from_inner (
366- Box :: leak ( Box :: try_new ( RcBox { strong : Cell :: new ( 1 ) , weak : Cell :: new ( 1 ) , value } ) ?)
367- . into ( ) ,
368- ) )
369- }
370-
371349 /// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
372350 /// to upgrade the weak reference before this function returns will result
373351 /// in a `None` value. However, the weak reference may be cloned freely and
@@ -475,6 +453,95 @@ impl<T> Rc<T> {
475453 }
476454 }
477455
456+ /// Constructs a new `Rc<T>`, returning an error if the allocation fails
457+ ///
458+ /// # Examples
459+ ///
460+ /// ```
461+ /// #![feature(allocator_api)]
462+ /// use std::rc::Rc;
463+ ///
464+ /// let five = Rc::try_new(5);
465+ /// # Ok::<(), std::alloc::AllocError>(())
466+ /// ```
467+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
468+ pub fn try_new ( value : T ) -> Result < Rc < T > , AllocError > {
469+ // There is an implicit weak pointer owned by all the strong
470+ // pointers, which ensures that the weak destructor never frees
471+ // the allocation while the strong destructor is running, even
472+ // if the weak pointer is stored inside the strong one.
473+ Ok ( Self :: from_inner (
474+ Box :: leak ( Box :: try_new ( RcBox { strong : Cell :: new ( 1 ) , weak : Cell :: new ( 1 ) , value } ) ?)
475+ . into ( ) ,
476+ ) )
477+ }
478+
479+ /// Constructs a new `Rc` with uninitialized contents, returning an error if the allocation fails
480+ ///
481+ /// # Examples
482+ ///
483+ /// ```
484+ /// #![feature(allocator_api, new_uninit)]
485+ /// #![feature(get_mut_unchecked)]
486+ ///
487+ /// use std::rc::Rc;
488+ ///
489+ /// let mut five = Rc::<u32>::try_new_uninit()?;
490+ ///
491+ /// let five = unsafe {
492+ /// // Deferred initialization:
493+ /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
494+ ///
495+ /// five.assume_init()
496+ /// };
497+ ///
498+ /// assert_eq!(*five, 5);
499+ /// # Ok::<(), std::alloc::AllocError>(())
500+ /// ```
501+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
502+ // #[unstable(feature = "new_uninit", issue = "63291")]
503+ pub fn try_new_uninit ( ) -> Result < Rc < mem:: MaybeUninit < T > > , AllocError > {
504+ unsafe {
505+ Ok ( Rc :: from_ptr ( Rc :: try_allocate_for_layout (
506+ Layout :: new :: < T > ( ) ,
507+ |layout| Global . allocate ( layout) ,
508+ |mem| mem as * mut RcBox < mem:: MaybeUninit < T > > ,
509+ ) ?) )
510+ }
511+ }
512+
513+ /// Constructs a new `Rc` with uninitialized contents, with the memory
514+ /// being filled with `0` bytes, returning an error if the allocation fails
515+ ///
516+ /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
517+ /// incorrect usage of this method.
518+ ///
519+ /// # Examples
520+ ///
521+ /// ```
522+ /// #![feature(allocator_api, new_uninit)]
523+ ///
524+ /// use std::rc::Rc;
525+ ///
526+ /// let zero = Rc::<u32>::try_new_zeroed()?;
527+ /// let zero = unsafe { zero.assume_init() };
528+ ///
529+ /// assert_eq!(*zero, 0);
530+ /// # Ok::<(), std::alloc::AllocError>(())
531+ /// ```
532+ ///
533+ /// [zeroed]: mem::MaybeUninit::zeroed
534+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
535+ //#[unstable(feature = "new_uninit", issue = "63291")]
536+ pub fn try_new_zeroed ( ) -> Result < Rc < mem:: MaybeUninit < T > > , AllocError > {
537+ unsafe {
538+ Ok ( Rc :: from_ptr ( Rc :: try_allocate_for_layout (
539+ Layout :: new :: < T > ( ) ,
540+ |layout| Global . allocate_zeroed ( layout) ,
541+ |mem| mem as * mut RcBox < mem:: MaybeUninit < T > > ,
542+ ) ?) )
543+ }
544+ }
478545 /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
479546 /// `value` will be pinned in memory and unable to be moved.
480547 #[ stable( feature = "pin" , since = "1.33.0" ) ]
@@ -1056,6 +1123,38 @@ impl<T: ?Sized> Rc<T> {
10561123 inner
10571124 }
10581125
1126+ /// Allocates an `RcBox<T>` with sufficient space for
1127+ /// a possibly-unsized inner value where the value has the layout provided,
1128+ /// returning an error if allocation fails.
1129+ ///
1130+ /// The function `mem_to_rcbox` is called with the data pointer
1131+ /// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
1132+ unsafe fn try_allocate_for_layout (
1133+ value_layout : Layout ,
1134+ allocate : impl FnOnce ( Layout ) -> Result < NonNull < [ u8 ] > , AllocError > ,
1135+ mem_to_rcbox : impl FnOnce ( * mut u8 ) -> * mut RcBox < T > ,
1136+ ) -> Result < * mut RcBox < T > , AllocError > {
1137+ // Calculate layout using the given value layout.
1138+ // Previously, layout was calculated on the expression
1139+ // `&*(ptr as *const RcBox<T>)`, but this created a misaligned
1140+ // reference (see #54908).
1141+ let layout = Layout :: new :: < RcBox < ( ) > > ( ) . extend ( value_layout) . unwrap ( ) . 0 . pad_to_align ( ) ;
1142+
1143+ // Allocate for the layout.
1144+ let ptr = allocate ( layout) ?;
1145+
1146+ // Initialize the RcBox
1147+ let inner = mem_to_rcbox ( ptr. as_non_null_ptr ( ) . as_ptr ( ) ) ;
1148+ unsafe {
1149+ debug_assert_eq ! ( Layout :: for_value( & * inner) , layout) ;
1150+
1151+ ptr:: write ( & mut ( * inner) . strong , Cell :: new ( 1 ) ) ;
1152+ ptr:: write ( & mut ( * inner) . weak , Cell :: new ( 1 ) ) ;
1153+ }
1154+
1155+ Ok ( inner)
1156+ }
1157+
10591158 /// Allocates an `RcBox<T>` with sufficient space for an unsized inner value
10601159 unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut RcBox < T > {
10611160 // Allocate for the `RcBox<T>` using the given value.
0 commit comments