rc_box/
lib.rs

1// NB: Last updated for Rust 1.40 parity. All impls are in rustdoc gutter order.
2
3//! Known unique versions of [`Rc`] and [`Arc`].
4//! This allows them to be used for mutable ownership.
5//!
6//! The main reason to use [`RcBox`] or [`ArcBox`] is for types that will be reference counted,
7//! but need some "fixing up" done after being allocated behind the reference counted pointer.
8//! With the standard library types, you would use `get_mut` and have to handle the impossible
9//! case where the value was shared. With the known unique versions, you have [`DerefMut`],
10//! so it's as simple as mutating behind a [`Box`].
11
12#![warn(missing_docs, missing_debug_implementations)]
13#![no_std]
14
15extern crate alloc;
16#[cfg(feature = "std")]
17extern crate std;
18
19#[cfg(feature = "erasable")]
20use erasable::{Erasable, ErasablePtr, ErasedPtr};
21#[cfg(feature = "slice-dst")]
22use slice_dst::{AllocSliceDst, SliceDst, TryAllocSliceDst};
23#[cfg(feature = "std")]
24use std::panic::UnwindSafe;
25use {
26    alloc::{boxed::Box, rc::Rc, string::String, sync::Arc, vec::Vec},
27    core::{
28        any::Any,
29        borrow::{Borrow, BorrowMut},
30        cmp::Ordering,
31        convert::{TryFrom, TryInto},
32        fmt::{self, Debug, Display, Formatter, Pointer},
33        hash::{Hash, Hasher},
34        hint::unreachable_unchecked,
35        iter::{FromIterator, FusedIterator},
36        marker::PhantomData,
37        mem::ManuallyDrop,
38        ops::{Deref, DerefMut},
39        pin::Pin,
40        ptr,
41    },
42};
43
44macro_rules! doc_comment {
45    ($x:expr, $($tt:tt)*) => {
46        #[doc = $x]
47        $($tt)*
48    };
49}
50
51macro_rules! rc_box {
52    ($($(#[$m:meta])* $RcBox:ident = $Rc:ident)*) => {$(
53        $(#[$m])*
54        pub struct $RcBox<T: ?Sized> {
55            raw: ptr::NonNull<T>,
56            marker: PhantomData<$Rc<T>>,
57        }
58
59        unsafe impl<T: ?Sized> Send for $RcBox<T> where Box<T>: Send {}
60        unsafe impl<T: ?Sized> Sync for $RcBox<T> where Box<T>: Sync {}
61
62        impl<T: ?Sized> Drop for $RcBox<T> {
63            fn drop(&mut self) {
64                unsafe { drop($Rc::<T>::from(ptr::read(self))) }
65            }
66        }
67
68        impl<T: ?Sized> From<$RcBox<T>> for $Rc<T> {
69            fn from(v: $RcBox<T>) -> $Rc<T> {
70                unsafe { $Rc::from_raw($RcBox::into_raw(v).as_ptr()) }
71            }
72        }
73
74        impl<T: ?Sized> TryFrom<$Rc<T>> for $RcBox<T> {
75            type Error = $Rc<T>;
76            fn try_from(mut v: $Rc<T>) -> Result<$RcBox<T>, $Rc<T>> {
77                // Could this just be `$Rc::strong_count == 1 && $Rc::weak_count == 0`?
78                // I _think_ `get_mut` has the weaker synchronization requirements?
79                if $Rc::get_mut(&mut v).is_some() {
80                    unsafe { Ok($RcBox::from_raw($Rc::into_raw(v))) }
81                } else {
82                    Err(v)
83                }
84            }
85        }
86
87        impl<T: ?Sized> TryFrom<Pin<$Rc<T>>> for Pin<$RcBox<T>> {
88            type Error = Pin<$Rc<T>>;
89            fn try_from(v: Pin<$Rc<T>>) -> Result<Pin<$RcBox<T>>, Pin<$Rc<T>>> {
90                unsafe {
91                    let v = Pin::into_inner_unchecked(v);
92                    match $RcBox::<T>::try_from(v) {
93                        Ok(this) => Ok(Pin::new_unchecked(this)),
94                        Err(v) => Err(Pin::new_unchecked(v)),
95                    }
96                }
97            }
98        }
99
100        impl<T: ?Sized> $RcBox<T> {
101            unsafe fn from_unchecked<V>(v: V) -> Self
102            where
103                V: TryInto<$RcBox<T>>,
104            {
105                v.try_into().unwrap_or_else(|_| unreachable_unchecked())
106            }
107        }
108
109        // ~~~ $Rc<T> and Box<T> like inherent impls ~~~ //
110
111        impl $RcBox<dyn Any + 'static> {
112            doc_comment! {
113                concat!("Attempt to downcast the box to a concrete type.
114
115# Examples
116
117```rust
118# use rc_box::*; use std::convert::TryInto;
119# use std::rc::Rc; use std::sync::Arc;
120use std::any::Any;
121
122fn print_if_string(value: ", stringify!($RcBox), r#"<dyn Any>) {
123    if let Ok(string) = value.downcast::<String>() {
124        println!("String ({}): {}", string.len(), string);
125    }
126}
127
128let my_string = "Hello World".to_string();
129let my_string: "#, stringify!($Rc), "<dyn Any> = ", stringify!($Rc), "::new(my_string); 
130print_if_string(my_string.try_into().unwrap());
131let my_number: ", stringify!($Rc), "<dyn Any> = ", stringify!($Rc), "::new(0i8);
132print_if_string(my_number.try_into().unwrap());
133```
134
135The unsizing as `", stringify!($Rc), "` is required until
136[DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized. Alternatively,
137activate the `unsize` feature to convert the pointer via an explicit method call."),
138                #[inline]
139                pub fn downcast<T>(self) -> Result<$RcBox<T>, Self>
140                where T: Any,
141                {
142                    if self.is::<T>() {
143                        unsafe {
144                            let raw: *mut dyn Any = Self::into_raw(self).as_ptr();
145                            Ok($RcBox::from_raw(raw as *mut T))
146                        }
147                    } else {
148                        Err(self)
149                    }
150                }
151            }
152        }
153
154        impl $RcBox<dyn Any + 'static + Send> {
155        doc_comment! {
156                concat!("Attempt to downcast the box to a concrete type.
157
158# Examples
159
160```rust
161# use rc_box::*; use std::convert::TryInto;
162# use std::rc::Rc; use std::sync::Arc;
163use std::any::Any;
164
165fn print_if_string(value: ", stringify!($RcBox), r#"<dyn Any + Send>) {
166    if let Ok(string) = value.downcast::<String>() {
167        println!("String ({}): {}", string.len(), string);
168    }
169}
170
171let my_string = "Hello World".to_string();
172let my_string: "#, stringify!($Rc), "<dyn Any + Send> = ", stringify!($Rc), "::new(my_string); 
173print_if_string(my_string.try_into().unwrap());
174let my_number: ", stringify!($Rc), "<dyn Any + Send> = ", stringify!($Rc), "::new(0i8);
175print_if_string(my_number.try_into().unwrap());
176```
177
178The unsizing as `", stringify!($Rc), "` is required until
179[DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized. Alternatively,
180activate the `unsize` feature to convert the pointer via an explicit method call."),
181                #[inline]
182                pub fn downcast<T>(self) -> Result<$RcBox<T>, Self>
183                where T: Any + Send
184                {
185                    if self.is::<T>() {
186                        unsafe {
187                            let raw: *mut (dyn Any + Send) = Self::into_raw(self).as_ptr();
188                            Ok($RcBox::from_raw(raw as *mut T))
189                        }
190                    } else {
191                        Err(self)
192                    }
193                }
194            }
195        }
196
197        impl $RcBox<dyn Any + 'static + Send + Sync> {
198        doc_comment! {
199                concat!("Attempt to downcast the box to a concrete type.
200
201# Examples
202
203```rust
204# use rc_box::*; use std::convert::TryInto;
205# use std::rc::Rc; use std::sync::Arc;
206use std::any::Any;
207
208fn print_if_string(value: ", stringify!($RcBox), r#"<dyn Any + Send + Sync>) {
209    if let Ok(string) = value.downcast::<String>() {
210        println!("String ({}): {}", string.len(), string);
211    }
212}
213
214let my_string = "Hello World".to_string();
215let my_string: "#, stringify!($Rc), "<dyn Any + Send + Sync> = ", stringify!($Rc), "::new(my_string); 
216print_if_string(my_string.try_into().unwrap());
217let my_number: ", stringify!($Rc), "<dyn Any + Send + Sync> = ", stringify!($Rc), "::new(0i8);
218print_if_string(my_number.try_into().unwrap());
219```
220
221The unsizing as `", stringify!($Rc), "` is required until
222[DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized. Alternatively,
223activate the `unsize` feature to convert the pointer via an explicit method call."),
224                #[inline]
225                pub fn downcast<T>(self) -> Result<$RcBox<T>, Self>
226                where T: Any + Send + Sync
227                {
228                    if self.is::<T>() {
229                        unsafe {
230                            let raw: *mut (dyn Any + Send + Sync) = Self::into_raw(self).as_ptr();
231                            Ok($RcBox::from_raw(raw as *mut T))
232                        }
233                    } else {
234                        Err(self)
235                    }
236                }
237            }
238        }
239
240        impl<T: ?Sized> $RcBox<T> {
241            // `downgrade` makes no sense as it would always immediately drop.
242
243            doc_comment! {
244                concat!("Construct an ", stringify!($RcBox), " from a raw pointer.
245
246# Safety
247
248The raw pointer must have previously been acquired by a call to [`",
249stringify!($RcBox), "::into_raw`], or [`", stringify!($Rc), "::into_raw`]
250where the `", stringify!($Rc), "` is known unique."),
251                pub unsafe fn from_raw(ptr: *const T) -> Self {
252                    $RcBox {
253                        // NB: $Rc::from_raw uses `ptr::NonNull::new_unchecked`
254                        raw: ptr::NonNull::new_unchecked(ptr as *mut _),
255                        marker: PhantomData,
256                    }
257                }
258            }
259
260            doc_comment! {
261                concat!("Get a mutable reference into the `", stringify!($RcBox), "`.
262
263This method exists only for API compatibility with `", stringify!($Rc), "`.
264Use `DerefMut` instead."),
265                #[deprecated(note = "Use [`DerefMut`](#impl-DerefMut) instead")]
266                pub fn get_mut(this: &mut Self) -> Option<&mut T> {
267                    Some(&mut **this)
268                }
269            }
270
271            doc_comment! {
272                concat!("Get a mutable reference into the `", stringify!($RcBox), "`.
273
274This method exists only for API compatibility with `", stringify!($Rc), "`.
275Use `DerefMut` instead."),
276                #[deprecated(note = "Use [`DerefMut`](#impl-DerefMut) instead")]
277                pub fn get_mut_unchecked(this: &mut Self) -> &mut T {
278                    &mut **this
279                }
280            }
281
282            doc_comment! {
283                concat!("\
284Returns a raw pointer to the object `T` pointed to by this `", stringify!($RcBox), "`.
285
286Note that this returns a [`ptr::NonNull`], not a raw pointer.
287That makes this function equivalent to `as_raw_non_null`."),
288                pub fn as_raw(this: &Self) -> ptr::NonNull<T> {
289                    this.raw
290                }
291            }
292
293            doc_comment! {
294                concat!("\
295Consume the `", stringify!($RcBox), "`, returning the wrapped pointer.
296
297To avoid a memory leak, the pointer must be converted back to a `",
298stringify!($RcBox), "`, using [`", stringify!($RcBox), "::from_raw`],
299or directly into a `", stringify!($Rc), "`, using [`", stringify!($Rc), "::from_raw`].
300
301Note that this returns a [`ptr::NonNull`], not a raw pointer.
302That makes this function equivalent to `into_raw_non_null`."),
303                pub fn into_raw(this: Self) -> ptr::NonNull<T> {
304                    $RcBox::as_raw(&ManuallyDrop::new(this))
305                }
306            }
307
308            doc_comment! {
309                concat!("Consume and leak the `", stringify!($RcBox), "`."),
310                pub fn leak<'a>(this: Self) -> &'a mut T
311                where
312                    T: 'a,
313                {
314                    unsafe { &mut *$RcBox::into_raw(this).as_ptr() }
315                }
316            }
317
318            doc_comment! {
319                concat!("Create a new ", stringify!($RcBox), "."),
320                pub fn new(data: T) -> Self
321                where
322                    T: Sized,
323                {
324                    unsafe { $RcBox::from_unchecked($Rc::new(data)) }
325                }
326            }
327
328            // `new_uninit`/`new_uninit_slice` are unstable but probably desirable.
329
330            doc_comment! {
331                concat!("\
332Construct a new `Pin<", stringify!($RcBox), "<T>>`. If `T` does not implement [`Unpin`],
333then the data will be pinned in memory and unable to be moved."),
334                pub fn pin(x: T) -> Pin<$RcBox<T>>
335                where
336                    T: Sized,
337                {
338                    unsafe {
339                        Pin::new_unchecked($RcBox::from_unchecked(
340                            Pin::into_inner_unchecked($Rc::pin(x))
341                        ))
342                    }
343                }
344            }
345
346            doc_comment! {
347                concat!("Deconstruct this `", stringify!($RcBox), "`, returning the inner value."),
348                pub fn into_inner(this: Self) -> T
349                where
350                    T: Sized,
351                {
352                    let rc: $Rc<T> = this.into();
353                    $Rc::try_unwrap(rc).unwrap_or_else(|_| unsafe { unreachable_unchecked() })
354                }
355            }
356        }
357
358        // ~~~ Box<T> like impls ~~~ //
359
360        #[cfg(feature = "erasable")]
361        unsafe impl<T: ?Sized> ErasablePtr for $RcBox<T>
362        where
363            T: Erasable
364        {
365            fn erase(this: Self) -> ErasedPtr {
366                T::erase($RcBox::into_raw(this))
367            }
368
369            unsafe fn unerase(this: ErasedPtr) -> Self {
370                $RcBox::from_raw(T::unerase(this).as_ptr())
371            }
372        }
373
374        #[cfg(feature = "slice-dst")]
375        unsafe impl<S: ?Sized + SliceDst> AllocSliceDst<S> for $RcBox<S> {
376            unsafe fn new_slice_dst<I>(len: usize, init: I) -> Self
377            where
378                I: FnOnce(ptr::NonNull<S>),
379            {
380                Self::from_unchecked($Rc::new_slice_dst(len, init))
381            }
382        }
383        #[cfg(feature = "slice-dst")]
384        unsafe impl<S: ?Sized + SliceDst> TryAllocSliceDst<S> for $RcBox<S> {
385            unsafe fn try_new_slice_dst<I, E>(len: usize, init: I) -> Result<Self, E>
386            where
387                I: FnOnce(ptr::NonNull<S>) -> Result<(), E>,
388            {
389                $Rc::try_new_slice_dst(len, init).map(|x| Self::from_unchecked(x))
390            }
391        }
392
393        impl<T: ?Sized> AsMut<T> for $RcBox<T> {
394            fn as_mut(&mut self) -> &mut T {
395                &mut **self
396            }
397        }
398
399        impl<T: ?Sized> AsRef<T> for $RcBox<T> {
400            fn as_ref(&self) -> &T {
401                &**self
402            }
403        }
404
405        impl<T: ?Sized> Borrow<T> for $RcBox<T> {
406            fn borrow(&self) -> &T {
407                &**self
408            }
409        }
410
411        impl<T: ?Sized> BorrowMut<T> for $RcBox<T> {
412            fn borrow_mut(&mut self) -> &mut T {
413                &mut **self
414            }
415        }
416
417        // impl CoerceUnsized
418
419        impl<T: ?Sized> Debug for $RcBox<T>
420        where
421            T: Debug,
422        {
423            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
424                (**self).fmt(f)
425            }
426        }
427
428        impl<T: ?Sized> Deref for $RcBox<T> {
429            type Target = T;
430            fn deref(&self) -> &T {
431                unsafe { self.raw.as_ref() }
432            }
433        }
434
435        impl<T: ?Sized> DerefMut for $RcBox<T> {
436            fn deref_mut(&mut self) -> &mut T {
437                unsafe { self.raw.as_mut() }
438            }
439        }
440
441        // impl DispatchFromDyn
442
443        impl<T: ?Sized> Display for $RcBox<T>
444        where
445            T: Display,
446        {
447            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
448                (**self).fmt(f)
449            }
450        }
451
452        impl<T: ?Sized> DoubleEndedIterator for $RcBox<T>
453        where
454            T: DoubleEndedIterator,
455        {
456            fn next_back(&mut self) -> Option<Self::Item> {
457                (**self).next_back()
458            }
459
460            fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
461                (**self).nth_back(n)
462            }
463        }
464
465        impl<T: ?Sized> Eq for $RcBox<T> where T: Eq {}
466
467        impl<T: ?Sized> ExactSizeIterator for $RcBox<T> where T: ExactSizeIterator {}
468
469        // impl Fn, FnMut, FnOnce
470
471        impl<T> From<&'_ [T]> for $RcBox<[T]>
472        where
473            T: Clone
474        {
475            fn from(v: &[T]) -> Self {
476                unsafe { $RcBox::from_unchecked($Rc::from(v)) }
477            }
478        }
479
480        impl From<&'_ str> for $RcBox<str> {
481            fn from(v: &str) -> Self {
482                unsafe { $RcBox::from_unchecked($Rc::from(v)) }
483            }
484        }
485
486        impl<T: ?Sized> From<Box<T>> for $RcBox<T> {
487            fn from(v: Box<T>) -> Self {
488                unsafe { $RcBox::from_unchecked($Rc::from(v)) }
489            }
490        }
491
492        impl From<String> for $RcBox<str> {
493            fn from(v: String) -> Self {
494                unsafe { $RcBox::from_unchecked($Rc::from(v)) }
495            }
496        }
497
498        impl<T> From<T> for $RcBox<T> {
499            fn from(v: T) -> Self {
500                unsafe { $RcBox::from_unchecked($Rc::from(v)) }
501            }
502        }
503
504        impl<T> From<Vec<T>> for $RcBox<[T]> {
505            fn from(v: Vec<T>) -> Self {
506                unsafe { $RcBox::from_unchecked($Rc::from(v)) }
507            }
508        }
509
510        impl<T> FromIterator<T> for $RcBox<[T]> {
511            fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
512                unsafe { $RcBox::from_unchecked($Rc::from_iter(iter)) }
513            }
514        }
515
516        impl<T: ?Sized> FusedIterator for $RcBox<T> where T: FusedIterator {}
517
518        // Skip Future/Generator; just use Box instead! There's no reason to share it later.
519
520        impl<T: ?Sized> Hash for $RcBox<T>
521        where
522            T: Hash,
523        {
524            fn hash<H: Hasher>(&self, state: &mut H) {
525                (**self).hash(state)
526            }
527        }
528
529        impl<T: ?Sized> Hasher for $RcBox<T>
530        where
531            T: Hasher,
532        {
533            fn finish(&self) -> u64 {
534                (**self).finish()
535            }
536
537            fn write(&mut self, bytes: &[u8]) {
538                (**self).write(bytes)
539            }
540
541            fn write_u8(&mut self, i: u8) {
542                (**self).write_u8(i)
543            }
544
545            fn write_u16(&mut self, i: u16) {
546                (**self).write_u16(i)
547            }
548
549            fn write_u32(&mut self, i: u32) {
550                (**self).write_u32(i)
551            }
552
553            fn write_u64(&mut self, i: u64) {
554                (**self).write_u64(i)
555            }
556
557            fn write_u128(&mut self, i: u128) {
558                (**self).write_u128(i)
559            }
560
561            fn write_usize(&mut self, i: usize) {
562                (**self).write_usize(i)
563            }
564
565            fn write_i8(&mut self, i: i8) {
566                (**self).write_i8(i)
567            }
568
569            fn write_i16(&mut self, i: i16) {
570                (**self).write_i16(i)
571            }
572
573            fn write_i32(&mut self, i: i32) {
574                (**self).write_i32(i)
575            }
576
577            fn write_i64(&mut self, i: i64) {
578                (**self).write_i64(i)
579            }
580
581            fn write_i128(&mut self, i: i128) {
582                (**self).write_i128(i)
583            }
584
585            fn write_isize(&mut self, i: isize) {
586                (**self).write_isize(i)
587            }
588        }
589
590        impl<T: ?Sized> Iterator for $RcBox<T>
591        where
592            T: Iterator
593        {
594            type Item = T::Item;
595
596            fn next(&mut self) -> Option<Self::Item> {
597                (**self).next()
598            }
599
600            fn size_hint(&self) -> (usize, Option<usize>) {
601                (**self).size_hint()
602            }
603
604            fn nth(&mut self, n: usize) -> Option<Self::Item> {
605                (**self).nth(n)
606            }
607        }
608
609        impl<T: ?Sized> Ord for $RcBox<T>
610        where
611            T: Ord,
612        {
613            fn cmp(&self, other: &Self) -> Ordering {
614                (**self).cmp(other)
615            }
616        }
617
618        impl<T: ?Sized, O> PartialEq<O> for $RcBox<T>
619        where
620            O: Deref,
621            T: PartialEq<O::Target>,
622        {
623            fn eq(&self, other: &O) -> bool {
624                (**self).eq(&*other)
625            }
626        }
627
628        impl<T: ?Sized, O> PartialOrd<O> for $RcBox<T>
629        where
630            O: Deref,
631            T: PartialOrd<O::Target>,
632        {
633            fn partial_cmp(&self, other: &O) -> Option<Ordering> {
634                (**self).partial_cmp(other)
635            }
636        }
637
638        impl<T: ?Sized> Pointer for $RcBox<T> {
639            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
640                fmt::Pointer::fmt(&&**self, f)
641            }
642        }
643
644        // impl TryFrom<($Rc)(Box)<[T]>> for $RcBox<[T; N]>
645        // (waiting on const generics)
646
647        impl<T: ?Sized> Unpin for $RcBox<T> {}
648
649        #[cfg(feature = "std")]
650        impl<T: ?Sized> UnwindSafe for $RcBox<T> where Box<T>: UnwindSafe {}
651
652        #[cfg(feature = "unsize")]
653        doc_comment! {
654            concat!("Unsizes a pointer using the `unsize` crate.
655
656# Usage
657
658```
659# use rc_box::*;
660use unsize::{Coercion, CoerceUnsize};
661
662let unique = ", stringify!($RcBox), "::new(|| 42u32);
663let unique:", stringify!($RcBox), r"<dyn Fn() -> u32> =
664    unique.unsize(Coercion::<_, dyn Fn() -> u32>::to_fn());
665
666let value = (*unique)();
667assert_eq!(value, 42);
668```
669
670Another common usage would be to create a `dyn Any`.
671
672fn print_if_string(value: ", stringify!($RcBox), r#"<dyn Any>) {
673    if let Ok(string) = value.downcast::<String>() {
674        println!("String ({}): {}", string.len(), string);
675    }
676}
677
678let my_string = "Hello World".to_string();
679let my_string: "#, stringify!($RcBox), "<dyn Any> = ", stringify!($RcBox), "::new(my_string).unsize(Coercion::to_any());
680print_if_string(my_string);
681let my_number: ", stringify!($RcBox), "<dyn Any> = ", stringify!($RcBox), "::new(0i8).unsize(Coercion::to_any());
682print_if_string(my_number);
683```"),
684            unsafe impl<T, U: ?Sized> unsize::CoerciblePtr<U> for $RcBox<T> {
685                type Pointee = T;
686                type Output = $RcBox<U>;
687                fn as_sized_ptr(&mut self) -> *mut T {
688                    $RcBox::as_raw(self).as_ptr()
689                }
690                unsafe fn replace_ptr(self, new: *mut U) -> $RcBox<U> {
691                    let new = $RcBox::into_raw(self).replace_ptr(new);
692                    $RcBox::from_raw(new.as_ptr() as *const U)
693                }
694            }
695        }
696    )*};
697}
698
699rc_box! {
700    /// Known unique version of [`Arc`].
701    ///
702    /// This type is guaranteed to have the same repr as `Box<T>`.
703    /// (The heap layout is that of `Arc<T>`.)
704    #[repr(transparent)]
705    ArcBox = Arc
706    /// Known unique version of [`Rc`].
707    ///
708    /// This type is guaranteed to have the same repr as `Box<T>`.
709    /// (The heap layout is that of `Rc<T>`.)
710    #[repr(transparent)]
711    RcBox = Rc
712}