Skip to main content

triomphe/
arc.rs

1use alloc::alloc::handle_alloc_error;
2use alloc::boxed::Box;
3use core::alloc::Layout;
4use core::borrow;
5use core::cmp::Ordering;
6use core::convert::From;
7use core::ffi::c_void;
8use core::fmt;
9use core::hash::{Hash, Hasher};
10use core::iter::FromIterator;
11use core::marker::PhantomData;
12use core::mem::{ManuallyDrop, MaybeUninit};
13use core::ops::Deref;
14use core::panic::{RefUnwindSafe, UnwindSafe};
15use core::ptr::{self, addr_of_mut, NonNull};
16use core::sync::atomic;
17use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
18#[cfg(feature = "serde")]
19use serde::{Deserialize, Serialize};
20#[cfg(feature = "stable_deref_trait")]
21use stable_deref_trait::{CloneStableDeref, StableDeref};
22
23use crate::{abort, AllocError, ArcBorrow, HeaderSlice, OffsetArc, UniqueArc};
24
25/// A soft limit on the amount of references that may be made to an `Arc`.
26///
27/// Going above this limit will abort your program (although not
28/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
29const MAX_REFCOUNT: usize = (isize::MAX) as usize;
30
31/// The object allocated by an `Arc<T>`
32#[repr(C)]
33pub(crate) struct ArcInner<T: ?Sized> {
34    pub(crate) count: atomic::AtomicUsize,
35    pub(crate) data: T,
36}
37
38unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
39unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
40
41impl<T: ?Sized> ArcInner<T> {
42    /// Compute the offset of the `data` field within `ArcInner<T>`.
43    ///
44    /// # Safety
45    ///
46    /// - The pointer must be created from `Arc::into_raw` or similar functions
47    /// - The pointee must be initialized (`&*value` must not be UB).
48    ///   That happens automatically if the pointer comes from `Arc` and type was not changed.
49    ///   This is **not** the case, for example, when `Arc` was uninitialized `MaybeUninit<T>`
50    ///   and the pointer was cast to `*const T`.
51    unsafe fn offset_of_data(value: *const T) -> usize {
52        // We can use `Layout::for_value_raw` when it is stable.
53        let value = &*value;
54
55        let layout = Layout::new::<atomic::AtomicUsize>();
56        let (_, offset) = layout.extend(Layout::for_value(value)).unwrap();
57        offset
58    }
59}
60
61/// An atomically reference counted shared pointer
62///
63/// See the documentation for [`Arc`] in the standard library. Unlike the
64/// standard library `Arc`, this `Arc` does not support weak reference counting.
65///
66/// [`Arc`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html
67#[repr(transparent)]
68pub struct Arc<T: ?Sized> {
69    pub(crate) p: ptr::NonNull<ArcInner<T>>,
70    pub(crate) phantom: PhantomData<T>,
71}
72
73unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
74unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
75
76impl<T: ?Sized + RefUnwindSafe> UnwindSafe for Arc<T> {}
77
78impl<T> Arc<T> {
79    /// Construct an `Arc<T>`
80    #[inline]
81    pub fn new(data: T) -> Self {
82        let ptr = Box::into_raw(Box::new(ArcInner {
83            count: atomic::AtomicUsize::new(1),
84            data,
85        }));
86
87        unsafe {
88            Arc {
89                p: ptr::NonNull::new_unchecked(ptr),
90                phantom: PhantomData,
91            }
92        }
93    }
94
95    /// Construct an `Arc<T>`, returning an error if allocation fails.
96    ///
97    /// Unlike [`Arc::new`], this does not abort the process on allocation
98    /// failure; instead it returns [`AllocError`].
99    #[inline]
100    pub fn try_new(data: T) -> Result<Self, AllocError> {
101        // `try_allocate_for_layout` takes the layout of the *value* (`T`) and
102        // internally reconstructs the layout of `ArcInner<T>`, so we pass the
103        // layout of `T` here, not of `ArcInner<T>`. This mirrors the existing
104        // `From<Box<T>>` impl.
105        //
106        // Safety: the closure only changes the type of the pointer.
107        let inner = unsafe {
108            Self::try_allocate_for_layout(Layout::new::<T>(), |mem| mem as *mut ArcInner<T>)?
109        };
110
111        unsafe {
112            // Safety: `inner` is freshly allocated, so the `data` field is
113            // valid for writes and not yet initialized.
114            ptr::write(addr_of_mut!((*inner.as_ptr()).data), data);
115        }
116
117        Ok(Arc {
118            p: inner,
119            phantom: PhantomData,
120        })
121    }
122
123    /// Temporarily converts |self| into a bonafide OffsetArc and exposes it to the
124    /// provided callback. The refcount is not modified.
125    #[inline(always)]
126    pub fn with_raw_offset_arc<F, U>(&self, f: F) -> U
127    where
128        F: FnOnce(&OffsetArc<T>) -> U,
129    {
130        // Synthesize transient Arc, which never touches the refcount of the ArcInner.
131        // Store transient in `ManuallyDrop`, to leave the refcount untouched.
132        let transient = unsafe { ManuallyDrop::new(Arc::into_raw_offset(ptr::read(self))) };
133
134        // Expose the transient Arc to the callback, which may clone it if it wants.
135        f(&transient)
136    }
137
138    /// Returns the inner value, if the [`Arc`] has exactly one strong reference.
139    ///
140    /// Otherwise, an [`Err`] is returned with the same [`Arc`] that was
141    /// passed in.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use triomphe::Arc;
147    ///
148    /// let x = Arc::new(3);
149    /// assert_eq!(Arc::try_unwrap(x), Ok(3));
150    ///
151    /// let x = Arc::new(4);
152    /// let _y = Arc::clone(&x);
153    /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);
154    /// ```
155    pub fn try_unwrap(this: Self) -> Result<T, Self> {
156        Self::try_unique(this).map(UniqueArc::into_inner)
157    }
158
159    /// Converts the `Arc` to `UniqueArc` if the `Arc` has exactly one strong reference.
160    ///
161    /// Otherwise, `None` is returned and the `Arc` is dropped.
162    ///
163    /// If `Arc::into_unique` is called on every clone of this `Arc`, it is guaranteed that exactly one of the calls
164    /// returns a `UniqueArc`. This means in particular that the inner data is not dropped. This can be useful when
165    /// it is desirable to recover the inner value in a way that does not require coordination amongst the various
166    /// copies of `Arc`.
167    ///
168    /// `Arc::try_unique` is conceptually similar to `Arc::into_unique`, but it is meant for different use-cases. If
169    /// used as a direct replacement for `Arc::into_unique`, such as with the expression `Arc::try_unique(this).ok()`,
170    /// then it does not give the same guarantee as described in the previous paragraph.
171    ///
172    /// For more information, see the examples below and read the documentation of `Arc::try_unique`.
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// use triomphe::Arc;
178    ///
179    /// let x = Arc::new(3);
180    /// let y = Arc::clone(&x);
181    ///
182    /// // Two threads calling `Arc::into_inner` on both clones of an `Arc`:
183    /// let x_thread = std::thread::spawn(|| Arc::into_unique(x));
184    /// let y_thread = std::thread::spawn(|| Arc::into_unique(y));
185    ///
186    /// let x_unique = x_thread.join().unwrap();
187    /// let y_unique = y_thread.join().unwrap();
188    ///
189    /// // One of the threads is guaranteed to receive the inner value:
190    /// assert!((x_unique.is_some() && y_unique.is_none()) || (x_unique.is_none() && y_unique.is_some()));
191    /// // The result could also be `(None, None)` if the threads called
192    /// // `Arc::try_unique(x).ok()` and `Arc::try_unique(y).ok()` instead.
193    /// ```
194    pub fn into_unique(this: Self) -> Option<UniqueArc<T>> {
195        // Prevent ourselves from being dropped in avoid clashing with the existing drop logic.
196        let this = ManuallyDrop::new(this);
197
198        // Update the reference count by decrementing by one, and if we are the last holder of this `Arc` (previous
199        // value was one), then we know we now can reconstitute this `Arc` into a `UniqueArc`. Otherwise, there's
200        // nothing else for us to do and we return `None` to signal that we weren't the last holder.
201        //
202        // Unlike `drop_inner`, we use AcqRel ordering on `fetch_sub` (instead of `fetch_sub(Release)` followed by
203        // `load(Acquire)`) to end up with the same outcome, just with a single atomic operation instead. This _is_
204        // strictly stronger (in terms of synchronization) but is not materially different: we're simply ensuring that
205        // any subsequent mutation of the data through `UniqueArc` cannot be ordered _before_ the reference count is
206        // updated, which could allow for other threads to see the data in an inconsistent state, ultimately leading to
207        // a data race.
208        if this.inner().count.fetch_sub(1, AcqRel) != 1 {
209            return None;
210        }
211
212        // Update the reference count _back_ to one, which upholds the reference count invariant of `UniqueArc`.
213        //
214        // Since we know we are the only thread accessing this `Arc` at this point, we have no special ordering needs.
215        this.inner().count.store(1, Relaxed);
216
217        // SAFETY: The reference count is guaranteed to be one at this point.
218        Some(unsafe { UniqueArc::from_arc(ManuallyDrop::into_inner(this)) })
219    }
220}
221
222impl<T> Arc<[T]> {
223    /// Reconstruct the `Arc<[T]>` from a raw pointer obtained from `into_raw()`.
224    ///
225    /// [`Arc::from_raw`] should accept unsized types, but this is not trivial to do correctly
226    /// until the feature [`pointer_bytes_offsets`](https://github.com/rust-lang/rust/issues/96283)
227    /// is stabilized. This is stopgap solution for slices.
228    ///
229    ///  # Safety
230    /// - The given pointer must be a valid pointer to `[T]` that came from [`Arc::into_raw`].
231    /// - After `from_raw_slice`, the pointer must not be accessed.
232    pub unsafe fn from_raw_slice(ptr: *const [T]) -> Self {
233        Arc::from_raw(ptr)
234    }
235}
236
237impl<T: ?Sized> Arc<T> {
238    /// Convert the `Arc<T>` to a raw pointer, suitable for use across FFI
239    ///
240    /// Note: This returns a pointer to the data T, which is offset in the allocation.
241    ///
242    /// It is recommended to use OffsetArc for this.
243    #[inline]
244    pub fn into_raw(this: Self) -> *const T {
245        let this = ManuallyDrop::new(this);
246        this.as_ptr()
247    }
248
249    /// Reconstruct the `Arc<T>` from a raw pointer obtained from into_raw()
250    ///
251    /// Note: This raw pointer will be offset in the allocation and must be preceded
252    /// by the atomic count.
253    ///
254    /// It is recommended to use OffsetArc for this
255    ///
256    ///  # Safety
257    /// - The given pointer must be a valid pointer to `T` that came from [`Arc::into_raw`].
258    /// - After `from_raw`, the pointer must not be accessed.
259    #[inline]
260    pub unsafe fn from_raw(ptr: *const T) -> Self {
261        // To find the corresponding pointer to the `ArcInner` we need
262        // to subtract the offset of the `data` field from the pointer.
263
264        // SAFETY: `ptr` comes from `ArcInner.data`, so it must be initialized.
265        let offset_of_data = ArcInner::<T>::offset_of_data(ptr);
266
267        // SAFETY: `from_raw_inner` expects a pointer to the beginning of the allocation,
268        //   not a pointer to data part.
269        //  `ptr` points to `ArcInner.data`, so subtraction results
270        //   in the beginning of the `ArcInner`, which is the beginning of the allocation.
271        let arc_inner_ptr = ptr.byte_sub(offset_of_data);
272        Arc::from_raw_inner(arc_inner_ptr as *mut ArcInner<T>)
273    }
274
275    /// Converts a `OffsetArc` into an `Arc`. This consumes the `OffsetArc`, so the refcount
276    /// is not modified.
277    #[inline]
278    pub fn from_raw_offset(a: OffsetArc<T>) -> Self {
279        let a = ManuallyDrop::new(a);
280        let ptr = a.ptr.as_ptr();
281        unsafe { Arc::from_raw(ptr) }
282    }
283
284    /// Converts an `Arc` into a `OffsetArc`. This consumes the `Arc`, so the refcount
285    /// is not modified.
286    #[inline]
287    pub fn into_raw_offset(a: Self) -> OffsetArc<T> {
288        unsafe {
289            OffsetArc {
290                ptr: ptr::NonNull::new_unchecked(Arc::into_raw(a) as *mut T),
291                phantom: PhantomData,
292            }
293        }
294    }
295
296    /// Returns the raw pointer.
297    ///
298    /// Same as into_raw except `self` isn't consumed.
299    #[inline]
300    pub fn as_ptr(&self) -> *const T {
301        // SAFETY: This cannot go through a reference to `data`, because this method
302        // is used to implement `into_raw`. To reconstruct the full `Arc` from this
303        // pointer, it needs to maintain its full provenance, and not be reduced to
304        // just the contained `T`.
305        unsafe { ptr::addr_of_mut!((*self.ptr()).data) }
306    }
307
308    /// Produce a pointer to the data that can be converted back
309    /// to an Arc. This is basically an `&Arc<T>`, without the extra indirection.
310    /// It has the benefits of an `&T` but also knows about the underlying refcount
311    /// and can be converted into more `Arc<T>`s if necessary.
312    #[inline]
313    pub fn borrow_arc(&self) -> ArcBorrow<'_, T> {
314        unsafe { ArcBorrow(NonNull::new_unchecked(self.as_ptr() as *mut T), PhantomData) }
315    }
316
317    /// Returns the address on the heap of the Arc itself -- not the T within it -- for memory
318    /// reporting.
319    pub fn heap_ptr(&self) -> *const c_void {
320        self.p.as_ptr() as *const ArcInner<T> as *const c_void
321    }
322
323    /// The reference count of this `Arc`.
324    ///
325    /// The number does not include borrowed pointers,
326    /// or temporary `Arc` pointers created with functions like
327    /// [`ArcBorrow::with_arc`].
328    ///
329    /// The function is called `strong_count` to mirror `std::sync::Arc::strong_count`,
330    /// however `triomphe::Arc` does not support weak references.
331    #[inline]
332    pub fn strong_count(this: &Self) -> usize {
333        this.inner().count.load(Relaxed)
334    }
335
336    #[inline]
337    pub(super) fn into_raw_inner(this: Self) -> *mut ArcInner<T> {
338        let this = ManuallyDrop::new(this);
339        this.ptr()
340    }
341
342    /// Construct an `Arc` from an allocated `ArcInner`.
343    /// # Safety
344    /// The `ptr` must point to a valid instance, allocated by an `Arc`. The reference could will
345    /// not be modified.
346    pub(super) unsafe fn from_raw_inner(ptr: *mut ArcInner<T>) -> Self {
347        Arc {
348            p: ptr::NonNull::new_unchecked(ptr),
349            phantom: PhantomData,
350        }
351    }
352
353    #[inline]
354    pub(super) fn inner(&self) -> &ArcInner<T> {
355        // This unsafety is ok because while this arc is alive we're guaranteed
356        // that the inner pointer is valid. Furthermore, we know that the
357        // `ArcInner` structure itself is `Sync` because the inner data is
358        // `Sync` as well, so we're ok loaning out an immutable pointer to these
359        // contents.
360        unsafe { &*self.ptr() }
361    }
362
363    // Non-inlined part of `drop`. Just invokes the destructor.
364    #[inline(never)]
365    unsafe fn drop_slow(&mut self) {
366        let _ = Box::from_raw(self.ptr());
367    }
368
369    /// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to
370    /// [`ptr::eq`]. This function ignores the metadata of  `dyn Trait` pointers.
371    #[inline]
372    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
373        ptr::addr_eq(this.ptr(), other.ptr())
374    }
375
376    pub(crate) fn ptr(&self) -> *mut ArcInner<T> {
377        self.p.as_ptr()
378    }
379
380    /// Allocates an `ArcInner<T>` with sufficient space for
381    /// a possibly-unsized inner value where the value has the layout provided.
382    ///
383    /// The function `mem_to_arcinner` is called with the data pointer
384    /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
385    ///
386    /// This function initializes the reference count, but the caller is
387    /// responsible for initializing `inner_ptr.data` after `inner_ptr` is
388    /// returned from this function.
389    ///
390    /// ## Safety
391    ///
392    /// `mem_to_arcinner` must return the same pointer, the only things that can change are
393    /// - its type
394    /// - its metadata
395    ///
396    /// `value_layout` must be correct for `T`.
397    pub(super) unsafe fn allocate_for_layout(
398        value_layout: Layout,
399        mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
400    ) -> NonNull<ArcInner<T>> {
401        // Recompute the full layout so that we can preserve the historical
402        // "layout too big" panic and the `handle_alloc_error` abort.
403        //
404        // Safety: same conditions as `try_allocate_for_layout`.
405        let full_layout = Layout::new::<ArcInner<()>>()
406            .extend(value_layout)
407            .expect("layout too big")
408            .0
409            .pad_to_align();
410
411        match unsafe { Self::try_allocate_for_layout(value_layout, mem_to_arcinner) } {
412            Ok(p) => p,
413            // The layout was already validated above, so the only way the
414            // fallible version can fail here is an actual allocation failure.
415            Err(AllocError) => handle_alloc_error(full_layout),
416        }
417    }
418
419    /// Fallible version of [`Arc::allocate_for_layout`].
420    ///
421    /// Returns `Err(AllocError)` on either layout overflow or allocation
422    /// failure, instead of panicking or aborting.
423    ///
424    /// ## Safety
425    ///
426    /// `mem_to_arcinner` must return the same pointer, the only things that can change are
427    /// - its type
428    /// - its metadata
429    ///
430    /// `value_layout` must be correct for `T`.
431    pub(super) unsafe fn try_allocate_for_layout(
432        value_layout: Layout,
433        mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
434    ) -> Result<NonNull<ArcInner<T>>, AllocError> {
435        // Safety
436
437        // 1. Caller ensures that value_layout is the layout of T
438        // 2. ArcInner is repr(C)
439        // 3. Thus, full_layout is layout of ArcInner<T>
440        let full_layout = Layout::new::<ArcInner<()>>()
441            .extend(value_layout)
442            .map_err(|_| AllocError)?
443            .0
444            .pad_to_align();
445
446        unsafe {
447            // ArcInner never has a zero size
448            let ptr = alloc::alloc::alloc(full_layout);
449            if ptr.is_null() {
450                Err(AllocError)
451            } else {
452                // Form the ArcInner pointer by adding type/metadata
453                // mem_to_arcinner keeps the same pointer (caller safety condition)
454                let inner_ptr = mem_to_arcinner(ptr);
455                // Initialize the reference count
456                ptr::write(
457                    addr_of_mut!((*inner_ptr).count),
458                    atomic::AtomicUsize::new(1),
459                );
460                // Pointer stays non-null
461                Ok(NonNull::new_unchecked(inner_ptr))
462            }
463        }
464    }
465}
466
467impl<H, T> Arc<HeaderSlice<H, [T]>> {
468    /// Allocates the arc inner for a slice DST type.
469    ///
470    /// The `len` argument provides the length of the tail. This function initializes the
471    /// reference count, but the caller is responsible for initializing the data inside
472    /// `inner_ptr.data` where `inner_ptr` is the pointer returned by this function.
473    pub(super) fn allocate_for_header_and_slice(
474        len: usize,
475    ) -> NonNull<ArcInner<HeaderSlice<H, [T]>>> {
476        // Recompute the full `ArcInner` layout so that we can preserve the
477        // historical "Requested size too big" / "layout too big" panics and
478        // pass the actually-attempted layout to `handle_alloc_error`.
479        let value_layout = Layout::array::<T>(len)
480            .and_then(|tail_layout| {
481                let header_layout = Layout::new::<H>();
482                header_layout.extend(tail_layout)
483            })
484            .expect("Requested size too big")
485            .0
486            .pad_to_align();
487        let full_layout = Layout::new::<ArcInner<()>>()
488            .extend(value_layout)
489            .expect("layout too big")
490            .0
491            .pad_to_align();
492
493        match Self::try_allocate_for_header_and_slice(len) {
494            Ok(p) => p,
495            // The layout was already validated above, so the only way the
496            // fallible version can fail here is an actual allocation failure.
497            Err(AllocError) => handle_alloc_error(full_layout),
498        }
499    }
500
501    /// Fallible version of [`Arc::allocate_for_header_and_slice`].
502    ///
503    /// Returns `Err(AllocError)` on either layout overflow or allocation
504    /// failure, instead of panicking or aborting.
505    #[allow(clippy::type_complexity)]
506    pub(super) fn try_allocate_for_header_and_slice(
507        len: usize,
508    ) -> Result<NonNull<ArcInner<HeaderSlice<H, [T]>>>, AllocError> {
509        let layout = Layout::array::<T>(len)
510            .and_then(|tail_layout| {
511                let header_layout = Layout::new::<H>();
512                header_layout.extend(tail_layout)
513            })
514            .map_err(|_| AllocError)?
515            .0
516            .pad_to_align();
517
518        unsafe {
519            // Safety:
520            // - the provided closure does not change the pointer (except for meta & type)
521            // - the provided layout is valid for `HeaderSlice<H, [T]>`
522            Arc::try_allocate_for_layout(layout, |mem| {
523                // Synthesize the fat pointer. We do this by claiming we have a direct
524                // pointer to a [T], and then changing the type of the borrow. The key
525                // point here is that the length portion of the fat pointer applies
526                // only to the number of elements in the dynamically-sized portion of
527                // the type, so the value will be the same whether it points to a [T]
528                // or something else with a [T] as its last member.
529                let fake_slice = ptr::slice_from_raw_parts_mut(mem as *mut T, len);
530                fake_slice as *mut ArcInner<HeaderSlice<H, [T]>>
531            })
532        }
533    }
534}
535
536impl<T> Arc<MaybeUninit<T>> {
537    /// Create an Arc contains an `MaybeUninit<T>`.
538    pub fn new_uninit() -> Self {
539        Arc::new(MaybeUninit::<T>::uninit())
540    }
541
542    /// Fallible version of [`Arc::new_uninit`].
543    ///
544    /// Returns `Err(AllocError)` instead of aborting on allocation failure.
545    pub fn try_new_uninit() -> Result<Self, AllocError> {
546        Arc::try_new(MaybeUninit::<T>::uninit())
547    }
548
549    /// Calls `MaybeUninit::write` on the value contained.
550    ///
551    /// ## Panics
552    ///
553    /// If the `Arc` is not unique.
554    #[deprecated(
555        since = "0.1.7",
556        note = "this function previously was UB and now panics for non-unique `Arc`s. Use `UniqueArc::write` instead."
557    )]
558    #[track_caller]
559    pub fn write(&mut self, val: T) -> &mut T {
560        UniqueArc::write(must_be_unique(self), val)
561    }
562
563    /// Obtain a mutable pointer to the stored `MaybeUninit<T>`.
564    #[inline]
565    pub fn as_mut_ptr(&mut self) -> *mut MaybeUninit<T> {
566        unsafe { core::ptr::addr_of_mut!((*self.ptr()).data) }
567    }
568
569    /// # Safety
570    ///
571    /// Must initialize all fields before calling this function.
572    #[inline]
573    pub unsafe fn assume_init(self) -> Arc<T> {
574        Arc::from_raw_inner(ManuallyDrop::new(self).ptr().cast())
575    }
576}
577
578impl<T> Arc<[MaybeUninit<T>]> {
579    /// Create an Arc contains an array `[MaybeUninit<T>]` of `len`.
580    pub fn new_uninit_slice(len: usize) -> Self {
581        UniqueArc::new_uninit_slice(len).shareable()
582    }
583
584    /// Fallible version of [`Arc::new_uninit_slice`].
585    ///
586    /// Returns `Err(AllocError)` instead of aborting on allocation failure.
587    pub fn try_new_uninit_slice(len: usize) -> Result<Self, AllocError> {
588        Ok(UniqueArc::try_new_uninit_slice(len)?.shareable())
589    }
590
591    /// Obtain a mutable slice to the stored `[MaybeUninit<T>]`.
592    #[deprecated(
593        since = "0.1.8",
594        note = "this function previously was UB and now panics for non-unique `Arc`s. Use `UniqueArc` or `get_mut` instead."
595    )]
596    #[track_caller]
597    pub fn as_mut_slice(&mut self) -> &mut [MaybeUninit<T>] {
598        must_be_unique(self)
599    }
600
601    /// # Safety
602    ///
603    /// Must initialize all fields before calling this function.
604    #[inline]
605    pub unsafe fn assume_init(self) -> Arc<[T]> {
606        Arc::from_raw_inner(ManuallyDrop::new(self).ptr() as _)
607    }
608}
609
610impl<T: ?Sized> Clone for Arc<T> {
611    #[inline]
612    fn clone(&self) -> Self {
613        // Using a relaxed ordering is alright here, as knowledge of the
614        // original reference prevents other threads from erroneously deleting
615        // the object.
616        //
617        // As explained in the [Boost documentation][1], Increasing the
618        // reference counter can always be done with memory_order_relaxed: New
619        // references to an object can only be formed from an existing
620        // reference, and passing an existing reference from one thread to
621        // another must already provide any required synchronization.
622        //
623        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
624        let old_size = self.inner().count.fetch_add(1, Relaxed);
625
626        // However we need to guard against massive refcounts in case someone
627        // is `mem::forget`ing Arcs. If we don't do this the count can overflow
628        // and users will use-after free. We racily saturate to `isize::MAX` on
629        // the assumption that there aren't ~2 billion threads incrementing
630        // the reference count at once. This branch will never be taken in
631        // any realistic program.
632        //
633        // We abort because such a program is incredibly degenerate, and we
634        // don't care to support it.
635        if old_size > MAX_REFCOUNT {
636            abort();
637        }
638
639        unsafe {
640            Arc {
641                p: ptr::NonNull::new_unchecked(self.ptr()),
642                phantom: PhantomData,
643            }
644        }
645    }
646}
647
648impl<T: ?Sized> Deref for Arc<T> {
649    type Target = T;
650
651    #[inline]
652    fn deref(&self) -> &T {
653        &self.inner().data
654    }
655}
656
657impl<T: Clone> Arc<T> {
658    /// Makes a mutable reference to the `Arc`, cloning if necessary
659    ///
660    /// This is functionally equivalent to [`Arc::make_mut`][mm] from the standard library.
661    ///
662    /// If this `Arc` is uniquely owned, `make_mut()` will provide a mutable
663    /// reference to the contents. If not, `make_mut()` will create a _new_ `Arc`
664    /// with a copy of the contents, update `this` to point to it, and provide
665    /// a mutable reference to its contents.
666    ///
667    /// This is useful for implementing copy-on-write schemes where you wish to
668    /// avoid copying things if your `Arc` is not shared.
669    ///
670    /// [mm]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.make_mut
671    #[inline]
672    pub fn make_mut(this: &mut Self) -> &mut T {
673        if !this.is_unique() {
674            // Another pointer exists; clone
675            *this = Arc::new(T::clone(this));
676        }
677
678        unsafe {
679            // This unsafety is ok because we're guaranteed that the pointer
680            // returned is the *only* pointer that will ever be returned to T. Our
681            // reference count is guaranteed to be 1 at this point, and we required
682            // the Arc itself to be `mut`, so we're returning the only possible
683            // reference to the inner data.
684            &mut (*this.ptr()).data
685        }
686    }
687
688    /// Makes a `UniqueArc` from an `Arc`, cloning if necessary.
689    ///
690    /// If this `Arc` is uniquely owned, `make_unique()` will provide a `UniqueArc`
691    /// containing `this`. If not, `make_unique()` will create a _new_ `Arc`
692    /// with a copy of the contents, update `this` to point to it, and provide
693    /// a `UniqueArc` to it.
694    ///
695    /// This is useful for implementing copy-on-write schemes where you wish to
696    /// avoid copying things if your `Arc` is not shared.
697    #[inline]
698    pub fn make_unique(this: &mut Self) -> &mut UniqueArc<T> {
699        if !this.is_unique() {
700            // Another pointer exists; clone
701            *this = Arc::new(T::clone(this));
702        }
703
704        unsafe {
705            // Safety: this is either unique or just created (which is also unique)
706            UniqueArc::from_arc_ref(this)
707        }
708    }
709
710    /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the clone.
711    ///
712    /// Assuming `arc_t` is of type `Arc<T>`, this function is functionally equivalent to `(*arc_t).clone()`, but will avoid cloning the inner value where possible.
713    pub fn unwrap_or_clone(this: Arc<T>) -> T {
714        Self::try_unwrap(this).unwrap_or_else(|this| T::clone(&this))
715    }
716}
717
718impl<T: ?Sized> Arc<T> {
719    /// Provides mutable access to the contents _if_ the `Arc` is uniquely owned.
720    #[inline]
721    pub fn get_mut(this: &mut Self) -> Option<&mut T> {
722        if this.is_unique() {
723            unsafe {
724                // See make_mut() for documentation of the threadsafety here.
725                Some(&mut (*this.ptr()).data)
726            }
727        } else {
728            None
729        }
730    }
731
732    /// Provides unique access to the arc _if_ the `Arc` is uniquely owned.
733    pub fn get_unique(this: &mut Self) -> Option<&mut UniqueArc<T>> {
734        Self::try_as_unique(this).ok()
735    }
736
737    /// Whether or not the `Arc` is uniquely owned (is the refcount 1?).
738    pub fn is_unique(&self) -> bool {
739        // See the extensive discussion in [1] for why this needs to be Acquire.
740        //
741        // [1] https://github.com/servo/servo/issues/21186
742        Self::count(self) == 1
743    }
744
745    /// Gets the number of [`Arc`] pointers to this allocation
746    pub fn count(this: &Self) -> usize {
747        this.inner().count.load(Acquire)
748    }
749
750    /// Returns a [`UniqueArc`] if the [`Arc`] has exactly one strong reference.
751    ///
752    /// Otherwise, an [`Err`] is returned with the same [`Arc`] that was
753    /// passed in.
754    ///
755    /// # Examples
756    ///
757    /// ```
758    /// use triomphe::{Arc, UniqueArc};
759    ///
760    /// let x = Arc::new(3);
761    /// assert_eq!(UniqueArc::into_inner(Arc::try_unique(x).unwrap()), 3);
762    ///
763    /// let x = Arc::new(4);
764    /// let _y = Arc::clone(&x);
765    /// assert_eq!(
766    ///     *Arc::try_unique(x).map(UniqueArc::into_inner).unwrap_err(),
767    ///     4,
768    /// );
769    /// ```
770    pub fn try_unique(this: Self) -> Result<UniqueArc<T>, Self> {
771        if this.is_unique() {
772            // Safety: The current arc is unique and making a `UniqueArc`
773            //         from it is sound
774            unsafe { Ok(UniqueArc::from_arc(this)) }
775        } else {
776            Err(this)
777        }
778    }
779
780    pub(crate) fn try_as_unique(this: &mut Self) -> Result<&mut UniqueArc<T>, &mut Self> {
781        if this.is_unique() {
782            // Safety: The current arc is unique and making a `UniqueArc`
783            //         from it is sound
784            unsafe { Ok(UniqueArc::from_arc_ref(this)) }
785        } else {
786            Err(this)
787        }
788    }
789
790    fn drop_inner(&mut self) {
791        // Because `fetch_sub` is already atomic, we do not need to synchronize
792        // with other threads unless we are going to delete the object.
793        if self.inner().count.fetch_sub(1, Release) != 1 {
794            return;
795        }
796
797        // This fence is needed to prevent reordering of use of the data and
798        // deletion of the data. Because it is marked `Release`, the decreasing
799        // of the reference count synchronizes with this `Acquire` fence. This
800        // means that use of the data happens before decreasing the reference
801        // count, which happens before this fence, which happens before the
802        // deletion of the data.
803        //
804        // As explained in the [Boost documentation][1],
805        //
806        // > It is important to enforce any possible access to the object in one
807        // > thread (through an existing reference) to *happen before* deleting
808        // > the object in a different thread. This is achieved by a "release"
809        // > operation after dropping a reference (any access to the object
810        // > through this reference must obviously happened before), and an
811        // > "acquire" operation before deleting the object.
812        //
813        // In particular, while the contents of an Arc are usually immutable, it's
814        // possible to have interior writes to something like a Mutex<T>. Since a
815        // Mutex is not acquired when it is deleted, we can't rely on its
816        // synchronization logic to make writes in thread A visible to a destructor
817        // running in thread B.
818        //
819        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
820        atomic::fence(Acquire);
821
822        unsafe {
823            self.drop_slow();
824        }
825    }
826}
827
828#[cfg(not(feature = "unstable_dropck_eyepatch"))]
829impl<T: ?Sized> Drop for Arc<T> {
830    #[inline]
831    fn drop(&mut self) {
832        self.drop_inner();
833    }
834}
835
836// SAFETY: We do not access the inner `T`, so we are fine to drop Arc with an already dropped T.
837#[cfg(feature = "unstable_dropck_eyepatch")]
838unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
839    #[inline]
840    fn drop(&mut self) {
841        self.drop_inner();
842    }
843}
844
845impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
846    fn eq(&self, other: &Arc<T>) -> bool {
847        // TODO: pointer equality is incorrect if `T` is not `Eq`.
848        Self::ptr_eq(self, other) || *(*self) == *(*other)
849    }
850
851    #[allow(clippy::partialeq_ne_impl)]
852    fn ne(&self, other: &Arc<T>) -> bool {
853        !Self::ptr_eq(self, other) && *(*self) != *(*other)
854    }
855}
856
857impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
858    fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
859        (**self).partial_cmp(&**other)
860    }
861
862    fn lt(&self, other: &Arc<T>) -> bool {
863        *(*self) < *(*other)
864    }
865
866    fn le(&self, other: &Arc<T>) -> bool {
867        *(*self) <= *(*other)
868    }
869
870    fn gt(&self, other: &Arc<T>) -> bool {
871        *(*self) > *(*other)
872    }
873
874    fn ge(&self, other: &Arc<T>) -> bool {
875        *(*self) >= *(*other)
876    }
877}
878
879impl<T: ?Sized + Ord> Ord for Arc<T> {
880    fn cmp(&self, other: &Arc<T>) -> Ordering {
881        (**self).cmp(&**other)
882    }
883}
884
885impl<T: ?Sized + Eq> Eq for Arc<T> {}
886
887impl<T: ?Sized + fmt::Display> fmt::Display for Arc<T> {
888    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
889        fmt::Display::fmt(&**self, f)
890    }
891}
892
893impl<T: ?Sized + fmt::Debug> fmt::Debug for Arc<T> {
894    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
895        fmt::Debug::fmt(&**self, f)
896    }
897}
898
899impl<T: ?Sized> fmt::Pointer for Arc<T> {
900    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
901        fmt::Pointer::fmt(&self.ptr(), f)
902    }
903}
904
905impl<T: Default> Default for Arc<T> {
906    #[inline]
907    fn default() -> Arc<T> {
908        Arc::new(Default::default())
909    }
910}
911
912impl<T: ?Sized + Hash> Hash for Arc<T> {
913    fn hash<H: Hasher>(&self, state: &mut H) {
914        (**self).hash(state)
915    }
916}
917
918impl<T> From<T> for Arc<T> {
919    #[inline]
920    fn from(t: T) -> Self {
921        Arc::new(t)
922    }
923}
924
925impl<A> FromIterator<A> for Arc<[A]> {
926    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
927        UniqueArc::from_iter(iter).shareable()
928    }
929}
930
931impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
932    #[inline]
933    fn borrow(&self) -> &T {
934        self
935    }
936}
937
938impl<T: ?Sized> AsRef<T> for Arc<T> {
939    #[inline]
940    fn as_ref(&self) -> &T {
941        self
942    }
943}
944
945#[cfg(feature = "stable_deref_trait")]
946unsafe impl<T: ?Sized> StableDeref for Arc<T> {}
947#[cfg(feature = "stable_deref_trait")]
948unsafe impl<T: ?Sized> CloneStableDeref for Arc<T> {}
949
950#[cfg(feature = "serde")]
951impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc<T> {
952    fn deserialize<D>(deserializer: D) -> Result<Arc<T>, D::Error>
953    where
954        D: ::serde::de::Deserializer<'de>,
955    {
956        T::deserialize(deserializer).map(Arc::new)
957    }
958}
959
960#[cfg(feature = "serde")]
961impl<T: Serialize> Serialize for Arc<T> {
962    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
963    where
964        S: ::serde::ser::Serializer,
965    {
966        (**self).serialize(serializer)
967    }
968}
969
970// Safety:
971// This implementation must guarantee that it is sound to call replace_ptr with an unsized variant
972// of the pointer retuned in `as_sized_ptr`. The basic property of Unsize coercion is that safety
973// variants and layout is unaffected. The Arc does not rely on any other property of T. This makes
974// any unsized ArcInner valid for being shared with the sized variant.
975// This does _not_ mean that any T can be unsized into an U, but rather than if such unsizing is
976// possible then it can be propagated into the Arc<T>.
977#[cfg(feature = "unsize")]
978unsafe impl<T, U: ?Sized> unsize::CoerciblePtr<U> for Arc<T> {
979    type Pointee = T;
980    type Output = Arc<U>;
981
982    fn as_sized_ptr(&mut self) -> *mut T {
983        // Returns a pointer to the complete inner. The unsizing itself won't care about the
984        // pointer value and promises not to offset it.
985        self.p.as_ptr() as *mut T
986    }
987
988    unsafe fn replace_ptr(self, new: *mut U) -> Arc<U> {
989        // Fix the provenance by ensuring that of `self` is used.
990        let inner = ManuallyDrop::new(self);
991        let p = inner.p.as_ptr() as *mut T;
992        // Safety: This points to an ArcInner of the previous self and holds shared ownership since
993        // the old pointer never decremented the reference count. The caller upholds that `new` is
994        // an unsized version of the previous ArcInner. This assumes that unsizing to the fat
995        // pointer tag of an `ArcInner<U>` and `U` is isomorphic under a direct pointer cast since
996        // in reality we unsized *mut T to *mut U at the address of the ArcInner. This is the case
997        // for all currently envisioned unsized types where the tag of T and ArcInner<T> are simply
998        // the same.
999        Arc::from_raw_inner(p.replace_ptr(new) as *mut ArcInner<U>)
1000    }
1001}
1002
1003#[track_caller]
1004fn must_be_unique<T: ?Sized>(arc: &mut Arc<T>) -> &mut UniqueArc<T> {
1005    match Arc::try_as_unique(arc) {
1006        Ok(unique) => unique,
1007        Err(this) => panic!("`Arc` must be unique in order for this operation to be safe, there are currently {} copies", Arc::count(this)),
1008    }
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013    use crate::arc::Arc;
1014    use alloc::borrow::ToOwned;
1015    use alloc::string::String;
1016    use alloc::vec::Vec;
1017    use core::iter::FromIterator;
1018    use core::mem::MaybeUninit;
1019    #[cfg(feature = "unsize")]
1020    use unsize::{CoerceUnsize, Coercion};
1021
1022    #[test]
1023    fn try_new() {
1024        let x = Arc::try_new(100usize).unwrap();
1025        assert_eq!(*x, 100);
1026    }
1027
1028    #[test]
1029    fn try_new_uninit() {
1030        let mut arc: Arc<MaybeUninit<u32>> = Arc::try_new_uninit().unwrap();
1031        let arc = unsafe {
1032            arc.as_mut_ptr().write(MaybeUninit::new(999));
1033            arc.assume_init()
1034        };
1035        assert_eq!(*arc, 999);
1036    }
1037
1038    #[test]
1039    fn try_new_uninit_slice() {
1040        let mut arc: Arc<[MaybeUninit<u32>]> = Arc::try_new_uninit_slice(5).unwrap();
1041        for (uninit, index) in Arc::get_mut(&mut arc).unwrap().iter_mut().zip(0..5) {
1042            uninit.write(index);
1043        }
1044        let arc = unsafe { arc.assume_init() };
1045        assert_eq!(*arc, [0, 1, 2, 3, 4]);
1046    }
1047
1048    #[test]
1049    fn try_unwrap() {
1050        let x = Arc::new(100usize);
1051        let y = x.clone();
1052
1053        // The count should be two so `try_unwrap()` should fail
1054        assert_eq!(Arc::count(&x), 2);
1055        assert!(Arc::try_unwrap(x).is_err());
1056
1057        // Since `x` has now been dropped, the count should be 1
1058        // and `try_unwrap()` should succeed
1059        assert_eq!(Arc::count(&y), 1);
1060        assert_eq!(Arc::try_unwrap(y), Ok(100));
1061    }
1062
1063    #[test]
1064    #[cfg(feature = "unsize")]
1065    fn coerce_to_slice() {
1066        let x = Arc::new([0u8; 4]);
1067        let y: Arc<[u8]> = x.clone().unsize(Coercion::to_slice());
1068        assert_eq!((*x).as_ptr(), (*y).as_ptr());
1069    }
1070
1071    #[test]
1072    #[cfg(feature = "unsize")]
1073    fn coerce_to_dyn() {
1074        let x: Arc<_> = Arc::new(|| 42u32);
1075        let x: Arc<_> = x.unsize(Coercion::<_, dyn Fn() -> u32>::to_fn());
1076        assert_eq!((*x)(), 42);
1077    }
1078
1079    #[test]
1080    #[allow(deprecated)]
1081    fn maybeuninit() {
1082        let mut arc: Arc<MaybeUninit<_>> = Arc::new_uninit();
1083        arc.write(999);
1084
1085        let arc = unsafe { arc.assume_init() };
1086        assert_eq!(*arc, 999);
1087    }
1088
1089    #[test]
1090    #[allow(deprecated)]
1091    #[should_panic = "`Arc` must be unique in order for this operation to be safe"]
1092    fn maybeuninit_ub_to_proceed() {
1093        let mut uninit = Arc::new_uninit();
1094        let clone = uninit.clone();
1095
1096        let x: &MaybeUninit<String> = &clone;
1097
1098        // This write invalidates `x` reference
1099        uninit.write(String::from("nonononono"));
1100
1101        // Read invalidated reference to trigger UB
1102        let _read = &*x;
1103    }
1104
1105    #[test]
1106    #[allow(deprecated)]
1107    #[should_panic = "`Arc` must be unique in order for this operation to be safe"]
1108    fn maybeuninit_slice_ub_to_proceed() {
1109        let mut uninit = Arc::new_uninit_slice(13);
1110        let clone = uninit.clone();
1111
1112        let x: &[MaybeUninit<String>] = &clone;
1113
1114        // This write invalidates `x` reference
1115        uninit.as_mut_slice()[0].write(String::from("nonononono"));
1116
1117        // Read invalidated reference to trigger UB
1118        let _read = &*x;
1119    }
1120
1121    #[test]
1122    fn maybeuninit_array() {
1123        let mut arc: Arc<[MaybeUninit<_>]> = Arc::new_uninit_slice(5);
1124        assert!(arc.is_unique());
1125        #[allow(deprecated)]
1126        for (uninit, index) in arc.as_mut_slice().iter_mut().zip(0..5) {
1127            let ptr = uninit.as_mut_ptr();
1128            unsafe { core::ptr::write(ptr, index) };
1129        }
1130
1131        let arc = unsafe { arc.assume_init() };
1132        assert!(arc.is_unique());
1133        // Using clone to that the layout generated in new_uninit_slice is compatible
1134        // with ArcInner.
1135        let arcs = [
1136            arc.clone(),
1137            arc.clone(),
1138            arc.clone(),
1139            arc.clone(),
1140            arc.clone(),
1141        ];
1142        assert_eq!(6, Arc::count(&arc));
1143        // If the layout is not compatible, then the data might be corrupted.
1144        assert_eq!(*arc, [0, 1, 2, 3, 4]);
1145
1146        // Drop the arcs and check the count and the content to
1147        // make sure it isn't corrupted.
1148        drop(arcs);
1149        assert!(arc.is_unique());
1150        assert_eq!(*arc, [0, 1, 2, 3, 4]);
1151    }
1152
1153    #[test]
1154    fn roundtrip() {
1155        let arc: Arc<usize> = Arc::new(0usize);
1156        let ptr = Arc::into_raw(arc);
1157        unsafe {
1158            let _arc = Arc::from_raw(ptr);
1159        }
1160    }
1161
1162    #[test]
1163    fn from_iterator_exact_size() {
1164        let arc = Arc::from_iter(Vec::from_iter(["ololo".to_owned(), "trololo".to_owned()]));
1165        assert_eq!(1, Arc::count(&arc));
1166        assert_eq!(["ololo".to_owned(), "trololo".to_owned()], *arc);
1167    }
1168
1169    #[test]
1170    fn from_iterator_unknown_size() {
1171        let arc = Arc::from_iter(
1172            Vec::from_iter(["ololo".to_owned(), "trololo".to_owned()])
1173                .into_iter()
1174                // Filter is opaque to iterators, so the resulting iterator
1175                // will report lower bound of 0.
1176                .filter(|_| true),
1177        );
1178        assert_eq!(1, Arc::count(&arc));
1179        assert_eq!(["ololo".to_owned(), "trololo".to_owned()], *arc);
1180    }
1181
1182    #[test]
1183    fn roundtrip_slice() {
1184        let arc = Arc::from(Vec::from_iter([17, 19]));
1185        let ptr = Arc::into_raw(arc);
1186        let arc = unsafe { Arc::from_raw_slice(ptr) };
1187        assert_eq!([17, 19], *arc);
1188        assert_eq!(1, Arc::count(&arc));
1189    }
1190
1191    #[test]
1192    fn arc_eq_and_cmp() {
1193        [
1194            [("*", &b"AB"[..]), ("*", &b"ab"[..])],
1195            [("*", &b"AB"[..]), ("*", &b"a"[..])],
1196            [("*", &b"A"[..]), ("*", &b"ab"[..])],
1197            [("A", &b"*"[..]), ("a", &b"*"[..])],
1198            [("a", &b"*"[..]), ("A", &b"*"[..])],
1199            [("AB", &b"*"[..]), ("a", &b"*"[..])],
1200            [("A", &b"*"[..]), ("ab", &b"*"[..])],
1201        ]
1202        .iter()
1203        .for_each(|[lt @ (lh, ls), rt @ (rh, rs)]| {
1204            let l = Arc::from_header_and_slice(lh, ls);
1205            let r = Arc::from_header_and_slice(rh, rs);
1206
1207            assert_eq!(l, l);
1208            assert_eq!(r, r);
1209
1210            assert_ne!(l, r);
1211            assert_ne!(r, l);
1212
1213            assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}");
1214            assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}");
1215
1216            assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}");
1217            assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}");
1218
1219            assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}");
1220            assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}");
1221
1222            assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}");
1223            assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}");
1224
1225            assert_eq!(l < r, lt < rt, "{lt:?} < {rt:?}");
1226            assert_eq!(r > l, rt > lt, "{rt:?} > {lt:?}");
1227        })
1228    }
1229
1230    #[test]
1231    fn arc_eq_and_partial_cmp() {
1232        [
1233            [(0.0, &[0.0, 0.0][..]), (1.0, &[0.0, 0.0][..])],
1234            [(1.0, &[0.0, 0.0][..]), (0.0, &[0.0, 0.0][..])],
1235            [(0.0, &[0.0][..]), (0.0, &[0.0, 0.0][..])],
1236            [(0.0, &[0.0, 0.0][..]), (0.0, &[0.0][..])],
1237            [(0.0, &[1.0, 2.0][..]), (0.0, &[10.0, 20.0][..])],
1238        ]
1239        .iter()
1240        .for_each(|[lt @ (lh, ls), rt @ (rh, rs)]| {
1241            let l = Arc::from_header_and_slice(lh, ls);
1242            let r = Arc::from_header_and_slice(rh, rs);
1243
1244            assert_eq!(l, l);
1245            assert_eq!(r, r);
1246
1247            assert_ne!(l, r);
1248            assert_ne!(r, l);
1249
1250            assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}");
1251            assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}");
1252
1253            assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}");
1254            assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}");
1255
1256            assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}");
1257            assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}");
1258
1259            assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}");
1260            assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}");
1261
1262            assert_eq!(l < r, lt < rt, "{lt:?} < {rt:?}");
1263            assert_eq!(r > l, rt > lt, "{rt:?} > {lt:?}");
1264        })
1265    }
1266
1267    #[test]
1268    fn test_strong_count() {
1269        let arc = Arc::new(17);
1270        assert_eq!(1, Arc::strong_count(&arc));
1271        let arc2 = arc.clone();
1272        assert_eq!(2, Arc::strong_count(&arc));
1273        drop(arc);
1274        assert_eq!(1, Arc::strong_count(&arc2));
1275    }
1276
1277    #[test]
1278    fn test_partial_eq_bug() {
1279        let float = f32::NAN;
1280        assert_ne!(float, float);
1281        let arc = Arc::new(f32::NAN);
1282        // TODO: this is a bug.
1283        assert_eq!(arc, arc);
1284    }
1285
1286    #[test]
1287    fn test_into_raw_from_raw_dst() {
1288        trait AnInteger {
1289            fn get_me_an_integer(&self) -> u64;
1290        }
1291
1292        impl AnInteger for u32 {
1293            fn get_me_an_integer(&self) -> u64 {
1294                *self as u64
1295            }
1296        }
1297
1298        let arc = Arc::<u32>::new(19);
1299        let data = Arc::into_raw(arc);
1300        let data: *const dyn AnInteger = data as *const _;
1301        let arc: Arc<dyn AnInteger> = unsafe { Arc::from_raw(data) };
1302        assert_eq!(19, arc.get_me_an_integer());
1303    }
1304
1305    #[test]
1306    fn into_unique() {
1307        let arc = Arc::new(42);
1308        assert_eq!(1, Arc::count(&arc));
1309
1310        let arc2 = Arc::clone(&arc);
1311
1312        assert_eq!(2, Arc::count(&arc));
1313
1314        let arc2_unique = Arc::into_unique(arc2);
1315        assert!(arc2_unique.is_none());
1316        assert_eq!(1, Arc::count(&arc));
1317
1318        let arc_unique = Arc::into_unique(arc).unwrap();
1319        assert_eq!(42, *arc_unique);
1320    }
1321
1322    #[cfg(feature = "std")]
1323    #[test]
1324    fn into_unique_data_race_no_sleep() {
1325        // Exists to be exercised by Miri to check for data races.
1326        let a = Arc::new(0);
1327        let b = a.clone();
1328        std::thread::spawn(move || {
1329            let _value = *b;
1330        });
1331        std::thread::spawn(move || {
1332            *Arc::into_unique(a).unwrap() += 1;
1333        });
1334    }
1335
1336    #[cfg(feature = "std")]
1337    #[test]
1338    fn into_unique_data_race_sleep() {
1339        // Exists to be exercised by Miri to check for data races.
1340        let a = Arc::new(0);
1341        let b = a.clone();
1342        let t1 = std::thread::spawn(move || {
1343            let _value = *b;
1344        });
1345        let t2 = std::thread::spawn(move || {
1346            std::thread::sleep(std::time::Duration::from_millis(100));
1347            if let Some(mut u) = Arc::into_unique(a) {
1348                *u += 1
1349            }
1350        });
1351        t1.join().unwrap();
1352        t2.join().unwrap();
1353    }
1354
1355    #[test]
1356    fn test_as_mut_ptr_sound() {
1357        // See https://github.com/Manishearth/triomphe/issues/134
1358        //
1359        // This tests that obtaining a mutable pointer from a non-unique `Arc` is sound
1360        // and does not trigger UB in Miri (e.g. via intermediate `&mut` retagging).
1361        //
1362        // DANGER: While obtaining the `*mut` pointer is sound, writing to it or
1363        // dereferencing it while other shared references (like `shared` below)
1364        // are active is still UB. The caller must ensure proper synchronization
1365        // and uniqueness before mutating through the pointer.
1366        let mut arc1: Arc<MaybeUninit<u64>> = Arc::new_uninit();
1367        let arc2 = arc1.clone();
1368        let shared: &MaybeUninit<u64> = &*arc2;
1369
1370        let _ptr: *mut MaybeUninit<u64> = arc1.as_mut_ptr();
1371
1372        let _copy: MaybeUninit<u64> = *shared;
1373    }
1374
1375    #[allow(dead_code)]
1376    const fn is_partial_ord<T: ?Sized + PartialOrd>() {}
1377
1378    #[allow(dead_code)]
1379    const fn is_ord<T: ?Sized + Ord>() {}
1380
1381    // compile-time check that PartialOrd/Ord is correctly derived
1382    const _: () = is_partial_ord::<Arc<f64>>();
1383    const _: () = is_ord::<Arc<u64>>();
1384}