@@ -346,28 +346,6 @@ impl<T> Rc<T> {
346
346
)
347
347
}
348
348
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
-
371
349
/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
372
350
/// to upgrade the weak reference before this function returns will result
373
351
/// in a `None` value. However, the weak reference may be cloned freely and
@@ -475,6 +453,95 @@ impl<T> Rc<T> {
475
453
}
476
454
}
477
455
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
+ }
478
545
/// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
479
546
/// `value` will be pinned in memory and unable to be moved.
480
547
#[ stable( feature = "pin" , since = "1.33.0" ) ]
@@ -1056,6 +1123,38 @@ impl<T: ?Sized> Rc<T> {
1056
1123
inner
1057
1124
}
1058
1125
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
+
1059
1158
/// Allocates an `RcBox<T>` with sufficient space for an unsized inner value
1060
1159
unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut RcBox < T > {
1061
1160
// Allocate for the `RcBox<T>` using the given value.
0 commit comments