@@ -327,6 +327,37 @@ impl<T> Rc<T> {
327
327
} ) )
328
328
}
329
329
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
+
330
361
/// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
331
362
/// `value` will be pinned in memory and unable to be moved.
332
363
#[ stable( feature = "pin" , since = "1.33.0" ) ]
@@ -377,6 +408,118 @@ impl<T> Rc<T> {
377
408
}
378
409
}
379
410
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
+
380
523
impl < T : ?Sized > Rc < T > {
381
524
/// Consumes the `Rc`, returning the wrapped pointer.
382
525
///
@@ -560,13 +703,46 @@ impl<T: ?Sized> Rc<T> {
560
703
pub fn get_mut ( this : & mut Self ) -> Option < & mut T > {
561
704
if Rc :: is_unique ( this) {
562
705
unsafe {
563
- Some ( & mut this . ptr . as_mut ( ) . value )
706
+ Some ( Rc :: get_mut_unchecked ( this ) )
564
707
}
565
708
} else {
566
709
None
567
710
}
568
711
}
569
712
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
+
570
746
#[ inline]
571
747
#[ stable( feature = "ptr_eq" , since = "1.17.0" ) ]
572
748
/// Returns `true` if the two `Rc`s point to the same value (not
@@ -704,11 +880,11 @@ impl Rc<dyn Any> {
704
880
705
881
impl < T : ?Sized > Rc < T > {
706
882
/// 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.
708
884
///
709
885
/// The function `mem_to_rcbox` is called with the data pointer
710
886
/// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
711
- unsafe fn allocate_for_unsized (
887
+ unsafe fn allocate_for_layout (
712
888
value_layout : Layout ,
713
889
mem_to_rcbox : impl FnOnce ( * mut u8 ) -> * mut RcBox < T >
714
890
) -> * mut RcBox < T > {
@@ -737,7 +913,7 @@ impl<T: ?Sized> Rc<T> {
737
913
/// Allocates an `RcBox<T>` with sufficient space for an unsized value
738
914
unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut RcBox < T > {
739
915
// Allocate for the `RcBox<T>` using the given value.
740
- Self :: allocate_for_unsized (
916
+ Self :: allocate_for_layout (
741
917
Layout :: for_value ( & * ptr) ,
742
918
|mem| set_data_ptr ( ptr as * mut T , mem) as * mut RcBox < T > ,
743
919
)
@@ -768,7 +944,7 @@ impl<T: ?Sized> Rc<T> {
768
944
impl < T > Rc < [ T ] > {
769
945
/// Allocates an `RcBox<[T]>` with the given length.
770
946
unsafe fn allocate_for_slice ( len : usize ) -> * mut RcBox < [ T ] > {
771
- Self :: allocate_for_unsized (
947
+ Self :: allocate_for_layout (
772
948
Layout :: array :: < T > ( len) . unwrap ( ) ,
773
949
|mem| ptr:: slice_from_raw_parts_mut ( mem as * mut T , len) as * mut RcBox < [ T ] > ,
774
950
)
0 commit comments