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