diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 98a11f8e1df08..a5256db57eaa7 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -944,8 +944,7 @@ pub(crate) enum RedefiningRuntimeSymbolsDiag<'tcx> { "invalid definition of the runtime `{$symbol_name}` symbol used by the standard library" )] #[note( - "expected `{$expected_fn_sig}` (for the current target) - found `{$found_fn_sig}`" + "expected `{$expected_fn_sig}` (for the current target)\n{\" \"}found `{$found_fn_sig}`" )] #[help( "either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = \"{$symbol_name}\")]`, or `#[link_name = \"{$symbol_name}\"]`" @@ -955,8 +954,7 @@ pub(crate) enum RedefiningRuntimeSymbolsDiag<'tcx> { "suspicious definition of the runtime `{$symbol_name}` symbol used by the standard library" )] #[note( - "expected `{$expected_fn_sig}` (for the current target) - found `{$found_fn_sig}`" + "expected `{$expected_fn_sig}` (for the current target)\n{\" \"}found `{$found_fn_sig}`" )] #[help( "either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = \"{$symbol_name}\")]`, or `#[link_name = \"{$symbol_name}\"]`" diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index 8eff9a4fa9e8a..404404bbc1cd0 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs @@ -173,6 +173,9 @@ fn verify_message_formatting(attr_span: Span, msg_span: Span, message: &str) { if line.is_empty() { continue; } + if line.trim().starts_with("{") && line.contains(&"found ") { + continue; + } let indent = line.chars().take_while(|c| *c == ' ').count(); if indent < start { span_err( diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index de6830a514656..b1aa1a9a4f525 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -230,12 +230,25 @@ // from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. #![feature(intra_doc_pointers)] +#[cfg(not(no_rc))] +#[stable(feature = "rust1", since = "1.0.0")] +pub use rcs::rc; + // Module with internal macros used by other modules (needs to be included before other modules). #[macro_use] mod macros; mod raw_vec; +/// Implementations of reference-counted pointers. +#[cfg(not(no_rc))] +mod rcs { + pub mod rc; + + #[cfg(all(not(no_sync), target_has_atomic = "ptr"))] + pub(crate) mod arc; +} + // Heaps provided for low-level allocation strategies pub mod alloc; @@ -256,8 +269,6 @@ pub mod intrinsics; #[unstable(feature = "alloc_io", issue = "154046")] pub mod io; pub mod panicking; -#[cfg(not(no_rc))] -pub mod rc; pub mod slice; pub mod str; pub mod string; diff --git a/library/alloc/src/rcs/arc.rs b/library/alloc/src/rcs/arc.rs new file mode 100644 index 0000000000000..e61ea5193eccb --- /dev/null +++ b/library/alloc/src/rcs/arc.rs @@ -0,0 +1,5204 @@ +use core::any::Any; +use core::cell::CloneFromCell; +#[cfg(not(no_global_oom_handling))] +use core::clone::TrivialClone; +use core::clone::{CloneToUninit, Share, UseCloned}; +use core::cmp::Ordering; +use core::hash::{Hash, Hasher}; +use core::intrinsics::abort; +#[cfg(not(no_global_oom_handling))] +use core::iter; +use core::marker::{PhantomData, Unsize}; +use core::mem::{self, Alignment, ManuallyDrop}; +use core::num::NonZeroUsize; +use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; +#[cfg(not(no_global_oom_handling))] +use core::ops::{Residual, Try}; +use core::panic::{RefUnwindSafe, UnwindSafe}; +use core::pin::{Pin, PinSafePointer}; +use core::ptr::{self, NonNull}; +#[cfg(not(no_global_oom_handling))] +use core::slice::from_raw_parts_mut; +use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; +use core::sync::atomic::{self, Atomic}; +use core::{borrow, fmt, hint}; + +use crate::alloc::{AllocError, Allocator, AllocatorClone, Global, Layout, StaticAllocator}; +#[cfg(not(no_global_oom_handling))] +use crate::alloc::{AllocatorNightly, handle_alloc_error}; +use crate::borrow::{Cow, ToOwned}; +use crate::boxed::Box; +use crate::rc::is_dangling; +#[cfg(not(no_global_oom_handling))] +use crate::string::String; +#[cfg(not(no_global_oom_handling))] +use crate::vec::Vec; + +/// A soft limit on the amount of references that may be made to an `Arc`. +/// +/// Going above this limit will abort your program (although not +/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references. +/// Trying to go above it might call a `panic` (if not actually going above it). +/// +/// This is a global invariant, and also applies when using a compare-exchange loop. +/// +/// See comment in `Arc::clone`. +const MAX_REFCOUNT: usize = (isize::MAX) as usize; + +#[cold] +#[cfg_attr(not(panic = "immediate-abort"), inline(never))] +#[cfg_attr(panic = "immediate-abort", inline)] +#[track_caller] +fn panic_arc_overflow() -> ! { + panic!("Arc counter overflow"); +} + +#[cfg(not(sanitize = "thread"))] +macro_rules! acquire { + ($x:expr) => { + atomic::fence(Acquire) + }; +} + +// ThreadSanitizer does not support memory fences. To avoid false positive +// reports in Arc / Weak implementation use atomic loads for synchronization +// instead. +#[cfg(sanitize = "thread")] +macro_rules! acquire { + ($x:expr) => { + $x.load(Acquire) + }; +} + +/// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically +/// Reference Counted'. +/// +/// The type `Arc` provides shared ownership of a value of type `T`, +/// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces +/// a new `Arc` instance, which points to the same allocation on the heap as the +/// source `Arc`, while increasing a reference count. When the last `Arc` +/// pointer to a given allocation is destroyed, the value stored in that allocation (often +/// referred to as "inner value") is also dropped. +/// +/// Shared references in Rust disallow mutation by default, and `Arc` is no +/// exception: you cannot generally obtain a mutable reference to something +/// inside an `Arc`. If you do need to mutate through an `Arc`, you have several options: +/// +/// 1. Use interior mutability with synchronization primitives like [`Mutex`][mutex], +/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. +/// +/// 2. Use clone-on-write semantics with [`Arc::make_mut`] which provides efficient mutation +/// without requiring interior mutability. This approach clones the data only when +/// needed (when there are multiple references) and can be more efficient when mutations +/// are infrequent. +/// +/// 3. Use [`Arc::get_mut`] when you know your `Arc` is not shared (has a reference count of 1), +/// which provides direct mutable access to the inner value without any cloning. +/// +/// ``` +/// use std::sync::Arc; +/// +/// let mut data = Arc::new(vec![1, 2, 3]); +/// +/// // This will clone the vector only if there are other references to it +/// Arc::make_mut(&mut data).push(4); +/// +/// assert_eq!(*data, vec![1, 2, 3, 4]); +/// ``` +/// +/// **Note**: This type is only available on platforms that support atomic +/// loads and stores of pointers, which includes all platforms that support +/// the `std` crate but not all those which only support [`alloc`](crate). +/// This may be detected at compile time using `#[cfg(target_has_atomic = "ptr")]`. +/// +/// ## Thread Safety +/// +/// Unlike [`Rc`], `Arc` uses atomic operations for its reference +/// counting. This means that it is thread-safe. The disadvantage is that +/// atomic operations are more expensive than ordinary memory accesses. If you +/// are not sharing reference-counted allocations between threads, consider using +/// [`Rc`] for lower overhead. [`Rc`] is a safe default, because the +/// compiler will catch any attempt to send an [`Rc`] between threads. +/// However, a library might choose `Arc` in order to give library consumers +/// more flexibility. +/// +/// `Arc` will implement [`Send`] and [`Sync`] as long as the `T` implements +/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an +/// `Arc` to make it thread-safe? This may be a bit counter-intuitive at +/// first: after all, isn't the point of `Arc` thread safety? The key is +/// this: `Arc` makes it thread safe to have multiple ownership of the same +/// data, but it doesn't add thread safety to its data. Consider +/// Arc<[RefCell\]>. [`RefCell`] isn't [`Sync`], and if `Arc` was always +/// [`Send`], Arc<[RefCell\]> would be as well. But then we'd have a problem: +/// [`RefCell`] is not thread safe; it keeps track of the borrowing count using +/// non-atomic operations. +/// +/// In the end, this means that you may need to pair `Arc` with some sort of +/// [`std::sync`] type, usually [`Mutex`][mutex]. +/// +/// ## Breaking cycles with `Weak` +/// +/// The [`downgrade`][downgrade] method can be used to create a non-owning +/// [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d +/// to an `Arc`, but this will return [`None`] if the value stored in the allocation has +/// already been dropped. In other words, `Weak` pointers do not keep the value +/// inside the allocation alive; however, they *do* keep the allocation +/// (the backing store for the value) alive. +/// +/// A cycle between `Arc` pointers will never be deallocated. For this reason, +/// [`Weak`] is used to break cycles. For example, a tree could have +/// strong `Arc` pointers from parent nodes to children, and [`Weak`] +/// pointers from children back to their parents. +/// +/// # Cloning references +/// +/// Creating a new reference from an existing reference-counted pointer is done using the +/// `Clone` trait implemented for [`Arc`][Arc] and [`Weak`][Weak]. +/// +/// ``` +/// use std::sync::Arc; +/// let foo = Arc::new(vec![1.0, 2.0, 3.0]); +/// // The two syntaxes below are equivalent. +/// let a = foo.clone(); +/// let b = Arc::clone(&foo); +/// // a, b, and foo are all Arcs that point to the same memory location +/// ``` +/// +/// ## `Deref` behavior +/// +/// `Arc` automatically dereferences to `T` (via the [`Deref`] trait), +/// so you can call `T`'s methods on a value of type `Arc`. To avoid name +/// clashes with `T`'s methods, the methods of `Arc` itself are associated +/// functions, called using [fully qualified syntax]: +/// +/// ``` +/// use std::sync::Arc; +/// +/// let my_arc = Arc::new(()); +/// let my_weak = Arc::downgrade(&my_arc); +/// ``` +/// +/// `Arc`'s implementations of traits like `Clone` may also be called using +/// fully qualified syntax. Some people prefer to use fully qualified syntax, +/// while others prefer using method-call syntax. +/// +/// ``` +/// use std::sync::Arc; +/// +/// let arc = Arc::new(()); +/// // Method-call syntax +/// let arc2 = arc.clone(); +/// // Fully qualified syntax +/// let arc3 = Arc::clone(&arc); +/// ``` +/// +/// [`Weak`][Weak] does not auto-dereference to `T`, because the inner value may have +/// already been dropped. +/// +/// [`Rc`]: crate::rc::Rc +/// [clone]: Clone::clone +/// [mutex]: ../../std/sync/struct.Mutex.html +/// [rwlock]: ../../std/sync/struct.RwLock.html +/// [atomic]: core::sync::atomic +/// [downgrade]: Arc::downgrade +/// [upgrade]: Weak::upgrade +/// [RefCell\]: core::cell::RefCell +/// [`RefCell`]: core::cell::RefCell +/// [`std::sync`]: ../../std/sync/index.html +/// [`Arc::clone(&from)`]: Arc::clone +/// [fully qualified syntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name +/// +/// # Examples +/// +/// Sharing some immutable data between threads: +/// +/// ``` +/// use std::sync::Arc; +/// use std::thread; +/// +/// let five = Arc::new(5); +/// +/// for _ in 0..10 { +/// let five = Arc::clone(&five); +/// +/// thread::spawn(move || { +/// println!("{five:?}"); +/// }); +/// } +/// ``` +/// +/// Sharing a mutable [`AtomicUsize`]: +/// +/// [`AtomicUsize`]: core::sync::atomic::AtomicUsize "sync::atomic::AtomicUsize" +/// +/// ``` +/// use std::sync::Arc; +/// use std::sync::atomic::{AtomicUsize, Ordering}; +/// use std::thread; +/// +/// let val = Arc::new(AtomicUsize::new(5)); +/// +/// for _ in 0..10 { +/// let val = Arc::clone(&val); +/// +/// thread::spawn(move || { +/// let v = val.fetch_add(1, Ordering::Relaxed); +/// println!("{v:?}"); +/// }); +/// } +/// ``` +/// +/// See the [`rc` documentation][rc_examples] for more examples of reference +/// counting in general. +/// +/// [rc_examples]: crate::rc#examples +#[doc(search_unbox)] +#[rustc_diagnostic_item = "Arc"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_insignificant_dtor] +#[diagnostic::on_move( + message = "the type `{Self}` does not implement `Copy`", + label = "this move could be avoided by cloning the original `{Self}`, which is inexpensive", + note = "consider using `Arc::clone`" +)] +pub struct Arc< + T: ?Sized, + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: Allocator = Global, +> { + ptr: NonNull>, + phantom: PhantomData>, + alloc: A, +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Send for Arc {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for Arc {} + +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl UnwindSafe + for Arc +{ +} + +#[unstable(feature = "coerce_unsized", issue = "18598")] +impl, U: ?Sized, A: Allocator> CoerceUnsized> for Arc {} + +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl, U: ?Sized> DispatchFromDyn> for Arc {} + +// SAFETY: `Arc::clone` doesn't access any `Cell`s which could contain the `Arc` being cloned. +#[unstable(feature = "cell_get_cloned", issue = "145329")] +unsafe impl CloneFromCell for Arc {} + +impl Arc { + unsafe fn from_inner(ptr: NonNull>) -> Self { + // SAFETY: Upheld by caller. + unsafe { Self::from_inner_in(ptr, Global) } + } + + unsafe fn from_ptr(ptr: *mut ArcInner) -> Self { + // SAFETY: Upheld by caller. + unsafe { Self::from_ptr_in(ptr, Global) } + } +} + +impl Arc { + #[inline] + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + let this = mem::ManuallyDrop::new(this); + // SAFETY: Pointer is valid for reads. + (this.ptr, unsafe { ptr::read(&this.alloc) }) + } + + #[inline] + unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { + Self { ptr, phantom: PhantomData, alloc } + } + + #[inline] + unsafe fn from_ptr_in(ptr: *mut ArcInner, alloc: A) -> Self { + // SAFETY: Upheld by caller. + unsafe { Self::from_inner_in(NonNull::new_unchecked(ptr), alloc) } + } +} + +/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the +/// managed allocation. +/// +/// The allocation is accessed by calling [`upgrade`] on the `Weak` +/// pointer, which returns an [Option]<[Arc]\>. +/// +/// Since a `Weak` reference does not count towards ownership, it will not +/// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no +/// guarantees about the value still being present. Thus it may return [`None`] +/// when [`upgrade`]d. Note however that a `Weak` reference *does* prevent the allocation +/// itself (the backing store) from being deallocated. +/// +/// A `Weak` pointer is useful for keeping a temporary reference to the allocation +/// managed by [`Arc`] without preventing its inner value from being dropped. It is also used to +/// prevent circular references between [`Arc`] pointers, since mutual owning references +/// would never allow either [`Arc`] to be dropped. For example, a tree could +/// have strong [`Arc`] pointers from parent nodes to children, and `Weak` +/// pointers from children back to their parents. +/// +/// The typical way to obtain a `Weak` pointer is to call [`Arc::downgrade`]. +/// +/// [`upgrade`]: Weak::upgrade +#[stable(feature = "arc_weak", since = "1.4.0")] +#[rustc_diagnostic_item = "ArcWeak"] +pub struct Weak< + T: ?Sized, + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: Allocator = Global, +> { + // This is a `NonNull` to allow optimizing the size of this type in enums, + // but it is not necessarily a valid pointer. + // `Weak::new` sets this to `usize::MAX` so that it doesn’t need + // to allocate space on the heap. That's not a value a real pointer + // will ever have because ArcInner has alignment at least 2. + ptr: NonNull>, + alloc: A, +} + +#[stable(feature = "arc_weak", since = "1.4.0")] +unsafe impl Send for Weak {} +#[stable(feature = "arc_weak", since = "1.4.0")] +unsafe impl Sync for Weak {} + +#[unstable(feature = "coerce_unsized", issue = "18598")] +impl, U: ?Sized, A: Allocator> CoerceUnsized> for Weak {} +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl, U: ?Sized> DispatchFromDyn> for Weak {} + +// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned. +#[unstable(feature = "cell_get_cloned", issue = "145329")] +unsafe impl CloneFromCell for Weak {} + +#[stable(feature = "arc_weak", since = "1.4.0")] +impl fmt::Debug for Weak { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "(Weak)") + } +} + +// This is repr(C) to future-proof against possible field-reordering, which +// would interfere with otherwise safe [into|from]_raw() of transmutable +// inner types. +// Unlike RcInner, repr(align(2)) is not strictly required because atomic types +// have the alignment same as its size, but we use it for consistency and clarity. +#[repr(C, align(2))] +struct ArcInner { + strong: Atomic, + + // the value usize::MAX acts as a sentinel for temporarily "locking" the + // weak count, preventing `Arc::downgrade` from racing to create new + // `Weak` references. `Arc::is_unique` (which backs `Arc::get_mut`) + // needs to observe both the strong and weak counts as indicating + // uniqueness in one logical atomic step; since they live in separate + // atomic words, it locks the weak count while reading the strong + // count to keep the two reads consistent. + weak: Atomic, + + data: T, +} + +/// Calculate layout for `ArcInner` using the inner value's layout +fn arcinner_layout_for_value_layout(layout: Layout) -> Layout { + // Calculate layout using the given value layout. + // Previously, layout was calculated on the expression + // `&*(ptr as *const ArcInner)`, but this created a misaligned + // reference (see #54908). + Layout::new::>() + .extend(layout) + .unwrap_or_else(|_| panic!("capacity overflow")) + .0 + .pad_to_align() +} + +unsafe impl Send for ArcInner {} +unsafe impl Sync for ArcInner {} + +impl Arc { + /// Constructs a new `Arc`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new(data: T) -> Arc { + // Start the weak pointer count as 1 which is the weak pointer that's + // held by all the strong pointers (kinda), see std/rc.rs for more info + let x: Box<_> = Box::new(ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data, + }); + // SAFETY: Pointer is valid. + unsafe { Self::from_inner(Box::into_non_null(x)) } + } + + /// Constructs a new `Arc` while giving you a `Weak` to the allocation, + /// to allow you to construct a `T` which holds a weak pointer to itself. + /// + /// Generally, a structure circularly referencing itself, either directly or + /// indirectly, should not hold a strong reference to itself to prevent a memory leak. + /// Using this function, you get access to the weak pointer during the + /// initialization of `T`, before the `Arc` is created, such that you can + /// clone and store it inside the `T`. + /// + /// `new_cyclic` first allocates the managed allocation for the `Arc`, + /// then calls your closure, giving it a `Weak` to this allocation, + /// and only afterwards completes the construction of the `Arc` by placing + /// the `T` returned from your closure into the allocation. + /// + /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic` + /// returns, calling [`upgrade`] on the weak reference inside your closure will + /// fail and result in a `None` value. + /// + /// # Panics + /// + /// If `data_fn` panics, the panic is propagated to the caller, and the + /// temporary [`Weak`] is dropped normally. + /// + /// # Example + /// + /// ``` + /// # #![allow(dead_code)] + /// use std::sync::{Arc, Weak}; + /// + /// struct Gadget { + /// me: Weak, + /// } + /// + /// impl Gadget { + /// /// Constructs a reference counted Gadget. + /// fn new() -> Arc { + /// // `me` is a `Weak` pointing at the new allocation of the + /// // `Arc` we're constructing. + /// Arc::new_cyclic(|me| { + /// // Create the actual struct here. + /// Gadget { me: me.clone() } + /// }) + /// } + /// + /// /// Returns a reference counted pointer to Self. + /// fn me(&self) -> Arc { + /// self.me.upgrade().unwrap() + /// } + /// } + /// ``` + /// [`upgrade`]: Weak::upgrade + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "arc_new_cyclic", since = "1.60.0")] + pub fn new_cyclic(data_fn: F) -> Arc + where + F: FnOnce(&Weak) -> T, + { + Self::new_cyclic_in(data_fn, Global) + } + + /// Constructs a new `Arc` with uninitialized contents. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut five = Arc::::new_uninit(); + /// + /// // Deferred initialization: + /// Arc::get_mut(&mut five).unwrap().write(5); + /// + /// let five = unsafe { five.assume_init() }; + /// + /// assert_eq!(*five, 5) + /// ``` + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "new_uninit", since = "1.82.0")] + #[must_use] + pub fn new_uninit() -> Arc> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::from_ptr(Arc::allocate_for_layout( + Layout::new::(), + |layout| Global.allocate(layout), + <*mut u8>::cast, + )) + } + } + + /// Constructs a new `Arc` with uninitialized contents, with the memory + /// being filled with `0` bytes. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let zero = Arc::::new_zeroed(); + /// let zero = unsafe { zero.assume_init() }; + /// + /// assert_eq!(*zero, 0) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] + #[must_use] + pub fn new_zeroed() -> Arc> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::from_ptr(Arc::allocate_for_layout( + Layout::new::(), + |layout| Global.allocate_zeroed(layout), + <*mut u8>::cast, + )) + } + } + + /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then + /// `data` will be pinned in memory and unable to be moved. + #[cfg(not(no_global_oom_handling))] + #[stable(feature = "pin", since = "1.33.0")] + #[must_use] + pub fn pin(data: T) -> Pin> { + // SAFETY: We own and create the pinned pointer. + unsafe { Pin::new_unchecked(Arc::new(data)) } + } + + /// Constructs a new `Pin>`, return an error if allocation fails. + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn try_pin(data: T) -> Result>, AllocError> { + // SAFETY: We own and create the pinned pointer. + unsafe { Ok(Pin::new_unchecked(Arc::try_new(data)?)) } + } + + /// Constructs a new `Arc`, returning an error if allocation fails. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// use std::sync::Arc; + /// + /// let five = Arc::try_new(5)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn try_new(data: T) -> Result, AllocError> { + // Start the weak pointer count as 1 which is the weak pointer that's + // held by all the strong pointers (kinda), see std/rc.rs for more info + let x: Box<_> = Box::try_new(ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data, + })?; + // SAFETY: Pointer is valid. + unsafe { Ok(Self::from_inner(Box::into_non_null(x))) } + } + + /// Constructs a new `Arc` with uninitialized contents, returning an error + /// if allocation fails. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// + /// let mut five = Arc::::try_new_uninit()?; + /// + /// // Deferred initialization: + /// Arc::get_mut(&mut five).unwrap().write(5); + /// + /// let five = unsafe { five.assume_init() }; + /// + /// assert_eq!(*five, 5); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn try_new_uninit() -> Result>, AllocError> { + // ignore-tidy-undocumented-unsafe + unsafe { + Ok(Arc::from_ptr(Arc::try_allocate_for_layout( + Layout::new::(), + |layout| Global.allocate(layout), + <*mut u8>::cast, + )?)) + } + } + + /// Constructs a new `Arc` with uninitialized contents, with the memory + /// being filled with `0` bytes, returning an error if allocation fails. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature( allocator_ext)] + /// + /// use std::sync::Arc; + /// + /// let zero = Arc::::try_new_zeroed()?; + /// let zero = unsafe { zero.assume_init() }; + /// + /// assert_eq!(*zero, 0); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn try_new_zeroed() -> Result>, AllocError> { + // ignore-tidy-undocumented-unsafe + unsafe { + Ok(Arc::from_ptr(Arc::try_allocate_for_layout( + Layout::new::(), + |layout| Global.allocate_zeroed(layout), + <*mut u8>::cast, + )?)) + } + } +} + +impl Arc { + /// Constructs a new `Arc` in the provided allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let five = Arc::new_in(5, System); + /// ``` + #[inline] + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn new_in(data: T, alloc: A) -> Arc { + // Start the weak pointer count as 1 which is the weak pointer that's + // held by all the strong pointers (kinda), see std/rc.rs for more info + let x = Box::new_in( + ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data, + }, + alloc, + ); + let (ptr, alloc) = Box::into_non_null_with_allocator(x); + // SAFETY: Pointer is valid. + unsafe { Self::from_inner_in(ptr, alloc) } + } + + /// Constructs a new `Arc` with uninitialized contents in the provided allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_mut_unchecked)] + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let mut five = Arc::::new_uninit_in(System); + /// + /// let five = unsafe { + /// // Deferred initialization: + /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// + /// five.assume_init() + /// }; + /// + /// assert_eq!(*five, 5) + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn new_uninit_in(alloc: A) -> Arc, A> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::from_ptr_in( + Arc::allocate_for_layout( + Layout::new::(), + |layout| alloc.allocate(layout), + <*mut u8>::cast, + ), + alloc, + ) + } + } + + /// Constructs a new `Arc` with uninitialized contents, with the memory + /// being filled with `0` bytes, in the provided allocator. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let zero = Arc::::new_zeroed_in(System); + /// let zero = unsafe { zero.assume_init() }; + /// + /// assert_eq!(*zero, 0) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn new_zeroed_in(alloc: A) -> Arc, A> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::from_ptr_in( + Arc::allocate_for_layout( + Layout::new::(), + |layout| alloc.allocate_zeroed(layout), + <*mut u8>::cast, + ), + alloc, + ) + } + } + + /// Constructs a new `Arc` in the given allocator while giving you a `Weak` to the allocation, + /// to allow you to construct a `T` which holds a weak pointer to itself. + /// + /// Generally, a structure circularly referencing itself, either directly or + /// indirectly, should not hold a strong reference to itself to prevent a memory leak. + /// Using this function, you get access to the weak pointer during the + /// initialization of `T`, before the `Arc` is created, such that you can + /// clone and store it inside the `T`. + /// + /// `new_cyclic_in` first allocates the managed allocation for the `Arc`, + /// then calls your closure, giving it a `Weak` to this allocation, + /// and only afterwards completes the construction of the `Arc` by placing + /// the `T` returned from your closure into the allocation. + /// + /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic_in` + /// returns, calling [`upgrade`] on the weak reference inside your closure will + /// fail and result in a `None` value. + /// + /// # Panics + /// + /// If `data_fn` panics, the panic is propagated to the caller, and the + /// temporary [`Weak`] is dropped normally. + /// + /// # Example + /// + /// See [`new_cyclic`] + /// + /// [`new_cyclic`]: Arc::new_cyclic + /// [`upgrade`]: Weak::upgrade + #[cfg(not(no_global_oom_handling))] + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn new_cyclic_in(data_fn: F, alloc: A) -> Arc + where + F: FnOnce(&Weak) -> T, + { + // Construct the inner in the "uninitialized" state with a single + // weak reference. + let (uninit_ptr, alloc) = Box::into_non_null_with_allocator(Box::new_in( + ArcInner { + strong: atomic::AtomicUsize::new(0), + weak: atomic::AtomicUsize::new(1), + data: mem::MaybeUninit::::uninit(), + }, + alloc, + )); + let init_ptr: NonNull> = uninit_ptr.cast(); + + let weak = Weak { ptr: init_ptr, alloc }; + + // It's important we don't give up ownership of the weak pointer, or + // else the memory might be freed by the time `data_fn` returns. If + // we really wanted to pass ownership, we could create an additional + // weak pointer for ourselves, but this would result in additional + // updates to the weak reference count which might not be necessary + // otherwise. + let data = data_fn(&weak); + + // Now we can properly initialize the inner value and turn our weak + // reference into a strong reference. + let inner = init_ptr.as_ptr(); + // ignore-tidy-undocumented-unsafe + unsafe { + ptr::write(&raw mut (*inner).data, data); + + // The above write to the data field must be visible to any threads which + // observe a non-zero strong count. Therefore we need at least "Release" ordering + // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`. + // + // "Acquire" ordering is not required. When considering the possible behaviors + // of `data_fn` we only need to look at what it could do with a reference to a + // non-upgradeable `Weak`: + // - It can *clone* the `Weak`, increasing the weak reference count. + // - It can drop those clones, decreasing the weak reference count (but never to zero). + // + // These side effects do not impact us in any way, and no other side effects are + // possible with safe code alone. + let prev_value = (*inner).strong.fetch_add(1, Release); + debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); + + // Strong references should collectively own a shared weak reference, + // so don't run the destructor for our old weak reference. + // Calling into_raw_with_allocator has the double effect of giving us back the allocator, + // and forgetting the weak reference. + let alloc = weak.into_raw_with_allocator().1; + + Arc::from_inner_in(init_ptr, alloc) + } + } + + /// Constructs a new `Pin>` in the provided allocator. If `T` does not implement `Unpin`, + /// then `data` will be pinned in memory and unable to be moved. + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn pin_in(data: T, alloc: A) -> Pin> + where + A: StaticAllocator, + { + // SAFETY: We own and create the pinned pointer. + unsafe { Pin::new_unchecked(Arc::new_in(data, alloc)) } + } + + /// Constructs a new `Pin>` in the provided allocator, return an error if allocation + /// fails. + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn try_pin_in(data: T, alloc: A) -> Result>, AllocError> + where + A: StaticAllocator, + { + // SAFETY: We own and create the pinned pointer. + unsafe { Ok(Pin::new_unchecked(Arc::try_new_in(data, alloc)?)) } + } + + /// Constructs a new `Arc` in the provided allocator, returning an error if allocation fails. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let five = Arc::try_new_in(5, System)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn try_new_in(data: T, alloc: A) -> Result, AllocError> { + // Start the weak pointer count as 1 which is the weak pointer that's + // held by all the strong pointers (kinda), see std/rc.rs for more info + let x = Box::try_new_in( + ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data, + }, + alloc, + )?; + let (ptr, alloc) = Box::into_non_null_with_allocator(x); + // SAFETY: Pointer is valid since we created it. + Ok(unsafe { Self::from_inner_in(ptr, alloc) }) + } + + /// Constructs a new `Arc` with uninitialized contents, in the provided allocator, returning an + /// error if allocation fails. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// #![feature(get_mut_unchecked)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let mut five = Arc::::try_new_uninit_in(System)?; + /// + /// let five = unsafe { + /// // Deferred initialization: + /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// + /// five.assume_init() + /// }; + /// + /// assert_eq!(*five, 5); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> { + // ignore-tidy-undocumented-unsafe + unsafe { + Ok(Arc::from_ptr_in( + Arc::try_allocate_for_layout( + Layout::new::(), + |layout| alloc.allocate(layout), + <*mut u8>::cast, + )?, + alloc, + )) + } + } + + /// Constructs a new `Arc` with uninitialized contents, with the memory + /// being filled with `0` bytes, in the provided allocator, returning an error if allocation + /// fails. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let zero = Arc::::try_new_zeroed_in(System)?; + /// let zero = unsafe { zero.assume_init() }; + /// + /// assert_eq!(*zero, 0); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> { + // ignore-tidy-undocumented-unsafe + unsafe { + Ok(Arc::from_ptr_in( + Arc::try_allocate_for_layout( + Layout::new::(), + |layout| alloc.allocate_zeroed(layout), + <*mut u8>::cast, + )?, + alloc, + )) + } + } + /// Returns the inner value, if the `Arc` has exactly one strong reference. + /// + /// Otherwise, an [`Err`] is returned with the same `Arc` that was + /// passed in. + /// + /// This will succeed even if there are outstanding weak references. + /// + /// It is strongly recommended to use [`Arc::into_inner`] instead if you don't + /// keep the `Arc` in the [`Err`] case. + /// Immediately dropping the [`Err`]-value, as the expression + /// `Arc::try_unwrap(this).ok()` does, can cause the strong count to + /// drop to zero and the inner value of the `Arc` to be dropped. + /// For instance, if two threads execute such an expression in parallel, + /// there is a race condition without the possibility of unsafety: + /// The threads could first both check whether they own the last instance + /// in `Arc::try_unwrap`, determine that they both do not, and then both + /// discard and drop their instance in the call to [`ok`][`Result::ok`]. + /// In this scenario, the value inside the `Arc` is safely destroyed + /// by exactly one of the threads, but neither thread will ever be able + /// to use the value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x = Arc::new(3); + /// assert_eq!(Arc::try_unwrap(x), Ok(3)); + /// + /// let x = Arc::new(4); + /// let _y = Arc::clone(&x); + /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4); + /// ``` + #[inline] + #[stable(feature = "arc_unique", since = "1.4.0")] + pub fn try_unwrap(this: Self) -> Result { + if this.inner().strong.compare_exchange(1, 0, Relaxed, Relaxed).is_err() { + return Err(this); + } + + acquire!(this.inner().strong); + + let this = ManuallyDrop::new(this); + // SAFETY: Pointer is valid for reads, contains initialised memory, + // and not dropped multiple times (we return it). + let elem: T = unsafe { ptr::read(&this.ptr.as_ref().data) }; + // SAFETY: As above, but we explicitly drop the allocator only once + // upon creating and dropping a weak pointer. + let alloc: A = unsafe { ptr::read(&this.alloc) }; // copy the allocator + + // Make a weak pointer to clean up the implicit strong-weak reference + let _weak = Weak { ptr: this.ptr, alloc }; + + Ok(elem) + } + + /// Returns the inner value, if the `Arc` has exactly one strong reference. + /// + /// Otherwise, [`None`] is returned and the `Arc` is dropped. + /// + /// This will succeed even if there are outstanding weak references. + /// + /// If `Arc::into_inner` is called on every clone of this `Arc`, + /// it is guaranteed that exactly one of the calls returns the inner value. + /// This means in particular that the inner value is not dropped. + /// + /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it + /// is meant for different use-cases. If used as a direct replacement + /// for `Arc::into_inner` anyway, such as with the expression + /// [Arc::try_unwrap]\(this).[ok][Result::ok](), then it does + /// **not** give the same guarantee as described in the previous paragraph. + /// For more information, see the examples below and read the documentation + /// of [`Arc::try_unwrap`]. + /// + /// # Examples + /// + /// Minimal example demonstrating the guarantee that `Arc::into_inner` gives. + /// ``` + /// use std::sync::Arc; + /// + /// let x = Arc::new(3); + /// let y = Arc::clone(&x); + /// + /// // Two threads calling `Arc::into_inner` on both clones of an `Arc`: + /// let x_thread = std::thread::spawn(|| Arc::into_inner(x)); + /// let y_thread = std::thread::spawn(|| Arc::into_inner(y)); + /// + /// let x_inner_value = x_thread.join().unwrap(); + /// let y_inner_value = y_thread.join().unwrap(); + /// + /// // One of the threads is guaranteed to receive the inner value: + /// assert!(matches!( + /// (x_inner_value, y_inner_value), + /// (None, Some(3)) | (Some(3), None) + /// )); + /// // The result could also be `(None, None)` if the threads called + /// // `Arc::try_unwrap(x).ok()` and `Arc::try_unwrap(y).ok()` instead. + /// ``` + /// + /// A more practical example demonstrating the need for `Arc::into_inner`: + /// ``` + /// use std::sync::Arc; + /// + /// // Definition of a simple singly linked list using `Arc`: + /// #[derive(Clone)] + /// struct LinkedList(Option>>); + /// struct Node(T, Option>>); + /// + /// // Dropping a long `LinkedList` relying on the destructor of `Arc` + /// // can cause a stack overflow. To prevent this, we can provide a + /// // manual `Drop` implementation that does the destruction in a loop: + /// impl Drop for LinkedList { + /// fn drop(&mut self) { + /// let mut link = self.0.take(); + /// while let Some(arc_node) = link.take() { + /// if let Some(Node(_value, next)) = Arc::into_inner(arc_node) { + /// link = next; + /// } + /// } + /// } + /// } + /// + /// // Implementation of `new` and `push` omitted + /// impl LinkedList { + /// /* ... */ + /// # fn new() -> Self { + /// # LinkedList(None) + /// # } + /// # fn push(&mut self, x: T) { + /// # self.0 = Some(Arc::new(Node(x, self.0.take()))); + /// # } + /// } + /// + /// // The following code could have still caused a stack overflow + /// // despite the manual `Drop` impl if that `Drop` impl had used + /// // `Arc::try_unwrap(arc).ok()` instead of `Arc::into_inner(arc)`. + /// + /// // Create a long list and clone it + /// let mut x = LinkedList::new(); + /// let size = 100000; + /// # let size = if cfg!(miri) { 100 } else { size }; + /// for i in 0..size { + /// x.push(i); // Adds i to the front of x + /// } + /// let y = x.clone(); + /// + /// // Drop the clones in parallel + /// let x_thread = std::thread::spawn(|| drop(x)); + /// let y_thread = std::thread::spawn(|| drop(y)); + /// x_thread.join().unwrap(); + /// y_thread.join().unwrap(); + /// ``` + #[inline] + #[stable(feature = "arc_into_inner", since = "1.70.0")] + pub fn into_inner(this: Self) -> Option { + // Make sure that the ordinary `Drop` implementation isn’t called as well + let mut this = mem::ManuallyDrop::new(this); + + // Following the implementation of `drop` and `drop_slow` + if this.inner().strong.fetch_sub(1, Release) != 1 { + return None; + } + + acquire!(this.inner().strong); + + // SAFETY: This mirrors the line + // + // unsafe { ptr::drop_in_place(Self::get_mut_unchecked(self)) }; + // + // in `drop_slow`. Instead of dropping the value behind the pointer, + // it is read and eventually returned; `ptr::read` has the same + // safety conditions as `ptr::drop_in_place`. + let inner = unsafe { ptr::read(Self::get_mut_unchecked(&mut this)) }; + // SAFETY: Pointer is valid for reads. + let alloc = unsafe { ptr::read(&this.alloc) }; + + drop(Weak { ptr: this.ptr, alloc }); + + Some(inner) + } + + /// Maps the value in an `Arc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `Arc`, and the result is returned, also in + /// an `Arc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Arc::map(a, f)` instead of `r.map(a)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let r = Arc::new(7); + /// let new = Arc::map(r, |i| i + 7); + /// assert_eq!(*new, 14); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] + pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Arc { + if size_of::() == size_of::() + && align_of::() == align_of::() + && Arc::is_unique(&this) + { + // ignore-tidy-undocumented-unsafe + unsafe { + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + let value = ptr.read(); + let mut allocation = Arc::from_raw_in(ptr.cast::>(), alloc); + + Arc::get_mut_unchecked(&mut allocation).write(f(&value)); + allocation.assume_init() + } + } else { + let output = f(&*this); + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + // ignore-tidy-undocumented-unsafe + unsafe { Arc::decrement_strong_count_in(ptr, &alloc) } + + Arc::new_in(output, alloc) + } + } + + /// Attempts to map the value in an `Arc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `Arc`, and if the operation succeeds, the + /// result is returned, also in an `Arc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Arc::try_map(a, f)` instead of `a.try_map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// + /// use std::sync::Arc; + /// + /// let b = Arc::new(7); + /// let new = Arc::try_map(b, |&i| u32::try_from(i)).unwrap(); + /// assert_eq!(*new, 7); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn try_map( + this: Self, + f: impl FnOnce(&T) -> R, + ) -> >>::TryType + where + R: Try, + R::Residual: Residual>, + { + if size_of::() == size_of::() + && align_of::() == align_of::() + && Arc::is_unique(&this) + { + // ignore-tidy-undocumented-unsafe + unsafe { + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + let value = ptr.read(); + let mut allocation = + Arc::from_raw_in(ptr.cast::>(), alloc); + + Arc::get_mut_unchecked(&mut allocation).write(f(&value)?); + try { allocation.assume_init() } + } + } else { + let output = f(&*this)?; + let (ptr, alloc) = Arc::into_raw_with_allocator(this); + // ignore-tidy-undocumented-unsafe + unsafe { Arc::decrement_strong_count_in(ptr, &alloc) } + + try { Arc::new_in(output, alloc) } + } + } +} + +impl Arc<[T]> { + /// Constructs a new atomically reference-counted slice with uninitialized contents. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut values = Arc::<[u32]>::new_uninit_slice(3); + /// + /// // Deferred initialization: + /// let data = Arc::get_mut(&mut values).unwrap(); + /// data[0].write(1); + /// data[1].write(2); + /// data[2].write(3); + /// + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [1, 2, 3]) + /// ``` + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "new_uninit", since = "1.82.0")] + #[must_use] + pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit]> { + // ignore-tidy-undocumented-unsafe + unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) } + } + + /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being + /// filled with `0` bytes. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and + /// incorrect usage of this method. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let values = Arc::<[u32]>::new_zeroed_slice(3); + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] + #[must_use] + pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::from_ptr(Arc::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| Global.allocate_zeroed(layout), + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[mem::MaybeUninit]>, + )) + } + } +} + +impl Arc<[T], A> { + /// Constructs a new atomically reference-counted slice with uninitialized contents in the + /// provided allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_mut_unchecked)] + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let mut values = Arc::<[u32], _>::new_uninit_slice_in(3, System); + /// + /// let values = unsafe { + /// // Deferred initialization: + /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1); + /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2); + /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3); + /// + /// values.assume_init() + /// }; + /// + /// assert_eq!(*values, [1, 2, 3]) + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn new_uninit_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { + // ignore-tidy-undocumented-unsafe + unsafe { Arc::from_ptr_in(Arc::allocate_for_slice_in(len, &alloc), alloc) } + } + + /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being + /// filled with `0` bytes, in the provided allocator. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and + /// incorrect usage of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let values = Arc::<[u32], _>::new_zeroed_slice_in(3, System); + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::from_ptr_in( + Arc::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| alloc.allocate_zeroed(layout), + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[mem::MaybeUninit]>, + ), + alloc, + ) + } + } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// # Errors + /// + /// Returns the original `Arc<[T]>` in the `Err` variant if `self.len()` does not equal `N`. + /// + /// # Examples + /// + /// ``` + /// #![feature(alloc_slice_into_array)] + /// use std::sync::Arc; + /// + /// let arc_slice: Arc<[i32]> = Arc::new([1, 2, 3]); + /// + /// let arc_array: Arc<[i32; 3]> = arc_slice.into_array().unwrap(); + /// ``` + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] + #[inline] + pub fn into_array(self) -> Result, Self> { + if self.len() == N { + let (ptr, alloc) = Self::into_raw_with_allocator(self); + let ptr = ptr as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Arc::from_raw_in(ptr, alloc) }; + Ok(me) + } else { + Err(self) + } + } +} + +impl Arc, A> { + /// Converts to `Arc`. + /// + /// # Safety + /// + /// As with [`MaybeUninit::assume_init`], + /// it is up to the caller to guarantee that the inner value + /// really is in an initialized state. + /// Calling this when the content is not yet fully initialized + /// causes immediate undefined behavior. + /// + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut five = Arc::::new_uninit(); + /// + /// // Deferred initialization: + /// Arc::get_mut(&mut five).unwrap().write(5); + /// + /// let five = unsafe { five.assume_init() }; + /// + /// assert_eq!(*five, 5) + /// ``` + #[stable(feature = "new_uninit", since = "1.82.0")] + #[must_use = "`self` will be dropped if the result is not used"] + #[inline] + pub unsafe fn assume_init(self) -> Arc { + let (ptr, alloc) = Arc::into_inner_with_allocator(self); + // ignore-tidy-undocumented-unsafe + unsafe { Arc::from_inner_in(ptr.cast(), alloc) } + } +} + +impl Arc { + /// Constructs a new `Arc` with a clone of `value`. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// use std::sync::Arc; + /// + /// let hello: Arc = Arc::clone_from_ref("hello"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + pub fn clone_from_ref(value: &T) -> Arc { + Arc::clone_from_ref_in(value, Global) + } + + /// Constructs a new `Arc` with a clone of `value`, returning an error if allocation fails + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// use std::sync::Arc; + /// + /// let hello: Arc = Arc::try_clone_from_ref("hello")?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn try_clone_from_ref(value: &T) -> Result, AllocError> { + Arc::try_clone_from_ref_in(value, Global) + } +} + +impl Arc { + /// Constructs a new `Arc` with a clone of `value` in the provided allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_ext)] + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let hello: Arc = Arc::clone_from_ref_in("hello", System); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn clone_from_ref_in(value: &T, alloc: A) -> Arc { + // `in_progress` drops the allocation if we panic before finishing initializing it. + let mut in_progress: UniqueArcUninit = UniqueArcUninit::new(value, alloc); + + // Initialize with clone of value. + // ignore-tidy-undocumented-unsafe + unsafe { + // Clone. If the clone panics, `in_progress` will be dropped and clean up. + value.clone_to_uninit(in_progress.data_ptr().cast()); + // Cast type of pointer, now that it is initialized. + in_progress.into_arc() + } + } + + /// Constructs a new `Arc` with a clone of `value` in the provided allocator, returning an error if allocation fails + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_ext)] + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let hello: Arc = Arc::try_clone_from_ref_in("hello", System)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn try_clone_from_ref_in(value: &T, alloc: A) -> Result, AllocError> { + // `in_progress` drops the allocation if we panic before finishing initializing it. + let mut in_progress: UniqueArcUninit = UniqueArcUninit::try_new(value, alloc)?; + + // Initialize with clone of value. + // ignore-tidy-undocumented-unsafe + let initialized_clone = unsafe { + // Clone. If the clone panics, `in_progress` will be dropped and clean up. + value.clone_to_uninit(in_progress.data_ptr().cast()); + // Cast type of pointer, now that it is initialized. + in_progress.into_arc() + }; + + Ok(initialized_clone) + } +} + +impl Arc<[mem::MaybeUninit], A> { + /// Converts to `Arc<[T]>`. + /// + /// # Safety + /// + /// As with [`MaybeUninit::assume_init`], + /// it is up to the caller to guarantee that the inner value + /// really is in an initialized state. + /// Calling this when the content is not yet fully initialized + /// causes immediate undefined behavior. + /// + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut values = Arc::<[u32]>::new_uninit_slice(3); + /// + /// // Deferred initialization: + /// let data = Arc::get_mut(&mut values).unwrap(); + /// data[0].write(1); + /// data[1].write(2); + /// data[2].write(3); + /// + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [1, 2, 3]) + /// ``` + #[stable(feature = "new_uninit", since = "1.82.0")] + #[must_use = "`self` will be dropped if the result is not used"] + #[inline] + pub unsafe fn assume_init(self) -> Arc<[T], A> { + let (ptr, alloc) = Arc::into_inner_with_allocator(self); + // SAFETY: Upheld by caller. + unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) } + } +} + +impl Arc { + /// Constructs an `Arc` from a raw pointer. + /// + /// The raw pointer must have been previously returned by a call to + /// [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator]. + /// + /// # Safety + /// + /// * Creating a `Arc` from a pointer other than one returned from + /// [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator] + /// is undefined behavior. + /// * If `U` is sized, it must have the same size and alignment as `T`. This + /// is trivially true if `U` is `T`. + /// * If `U` is unsized, its data pointer must have the same size and + /// alignment as `T`. This is trivially true if `Arc` was constructed + /// through `Arc` and then converted to `Arc` through an [unsized + /// coercion]. + /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. + /// * The raw pointer must point to a block of memory allocated by the global allocator. + /// * The user of `from_raw` has to make sure a specific value of `T` is only + /// dropped once. + /// + /// This function is unsafe because improper use may lead to memory unsafety, + /// even if the returned `Arc` is never accessed. + /// + /// [into_raw]: Arc::into_raw + /// [into_raw_with_allocator]: Arc::into_raw_with_allocator + /// [transmute]: core::mem::transmute + /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x = Arc::new("hello".to_owned()); + /// let x_ptr = Arc::into_raw(x); + /// + /// unsafe { + /// // Convert back to an `Arc` to prevent leak. + /// let x = Arc::from_raw(x_ptr); + /// assert_eq!(&*x, "hello"); + /// + /// // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe. + /// } + /// + /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! + /// ``` + /// + /// Convert a slice back into its original array: + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x: Arc<[u32]> = Arc::new([1, 2, 3]); + /// let x_ptr: *const [u32] = Arc::into_raw(x); + /// + /// unsafe { + /// let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>()); + /// assert_eq!(&*x, &[1, 2, 3]); + /// } + /// ``` + #[inline] + #[stable(feature = "rc_raw", since = "1.17.0")] + pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Upheld by caller. + unsafe { Arc::from_raw_in(ptr, Global) } + } + + /// Consumes the `Arc`, returning the wrapped pointer. + /// + /// To avoid a memory leak the pointer must be converted back to an `Arc` using + /// [`Arc::from_raw`]. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x = Arc::new("hello".to_owned()); + /// let x_ptr = Arc::into_raw(x); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); + /// # // Prevent leaks for Miri. + /// # drop(unsafe { Arc::from_raw(x_ptr) }); + /// ``` + #[must_use = "losing the pointer will leak memory"] + #[stable(feature = "rc_raw", since = "1.17.0")] + #[rustc_never_returns_null_ptr] + pub fn into_raw(this: Self) -> *const T { + let this = ManuallyDrop::new(this); + Self::as_ptr(&*this) + } + + /// Increments the strong reference count on the `Arc` associated with the + /// provided pointer by one. + /// + /// # Safety + /// + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) for the duration of this method, and `ptr` must point to a block of memory + /// allocated by the global allocator. + /// + /// [from_raw_in]: Arc::from_raw_in + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// unsafe { + /// let ptr = Arc::into_raw(five); + /// Arc::increment_strong_count(ptr); + /// + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` between threads. + /// let five = Arc::from_raw(ptr); + /// assert_eq!(2, Arc::strong_count(&five)); + /// # // Prevent leaks for Miri. + /// # Arc::decrement_strong_count(ptr); + /// } + /// ``` + #[inline] + #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] + pub unsafe fn increment_strong_count(ptr: *const T) { + // SAFETY: Upheld by caller. + unsafe { Arc::increment_strong_count_in(ptr, Global) } + } + + /// Decrements the strong reference count on the `Arc` associated with the + /// provided pointer by one. + /// + /// # Safety + /// + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) when invoking this method, and `ptr` must point to a block of memory + /// allocated by the global allocator. This method can be used to release the final + /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been + /// released. + /// + /// [from_raw_in]: Arc::from_raw_in + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// unsafe { + /// let ptr = Arc::into_raw(five); + /// Arc::increment_strong_count(ptr); + /// + /// // Those assertions are deterministic because we haven't shared + /// // the `Arc` between threads. + /// let five = Arc::from_raw(ptr); + /// assert_eq!(2, Arc::strong_count(&five)); + /// Arc::decrement_strong_count(ptr); + /// assert_eq!(1, Arc::strong_count(&five)); + /// } + /// ``` + #[inline] + #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] + pub unsafe fn decrement_strong_count(ptr: *const T) { + // SAFETY: Upheld by caller. + unsafe { Arc::decrement_strong_count_in(ptr, Global) } + } + + /// Gets the number of strong (`Arc`) pointers to the allocation behind the given raw + /// pointer. + /// + /// This method does not consume or drop the `Arc` behind this pointer. + /// + /// # Safety + /// + /// The pointer must point to (and have valid metadata for) the value inside a live `Arc` + /// allocation, such as a pointer returned by [`Arc::into_raw`], + /// [`Arc::into_raw_with_allocator`], or [`Arc::as_ptr`]. + /// `T` must have the same alignment as that value. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) for the duration of this method. + /// + /// Using this method correctly also requires extra care: another thread can change the + /// strong count at any time, including between calling this method and acting on the + /// result. + /// + /// # Examples + /// + /// ``` + /// #![feature(arc_raw_get_strong)] + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let _also_five = Arc::clone(&five); + /// let ptr = Arc::into_raw(five); + /// + /// unsafe { + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` between threads. + /// assert_eq!(2, Arc::strong_count_from_raw(ptr)); + /// + /// // Convert back to an `Arc` to avoid leaking memory. + /// let five = Arc::from_raw(ptr); + /// assert_eq!(2, Arc::strong_count(&five)); + /// } + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "arc_raw_get_strong", issue = "157021")] + pub unsafe fn strong_count_from_raw(ptr: *const T) -> usize { + // SAFETY: Upheld by caller. + let offset = unsafe { data_offset(ptr) }; + // Reverse the offset to find the original ArcInner. + // SAFETY: Caller ensures this pointer was to an `Arc` allocation, + // so offsetting must be inbounds. + let arc_ptr = unsafe { ptr.byte_sub(offset) as *mut ArcInner }; + // SAFETY: Per the above, an `ArcInner` is stored here. + unsafe { (*arc_ptr).strong.load(Relaxed) } + } +} + +impl Arc { + /// Returns a reference to the underlying allocator. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Arc::allocator(&a)` instead of `a.allocator()`. This + /// is so that there is no conflict with a method on the inner type. + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn allocator(this: &Self) -> &A { + &this.alloc + } + + /// Consumes the `Arc`, returning the wrapped pointer and allocator. + /// + /// To avoid a memory leak the pointer must be converted back to an `Arc` using + /// [`Arc::from_raw_in`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let x = Arc::new_in("hello".to_owned(), System); + /// let (ptr, alloc) = Arc::into_raw_with_allocator(x); + /// assert_eq!(unsafe { &*ptr }, "hello"); + /// let x = unsafe { Arc::from_raw_in(ptr, alloc) }; + /// assert_eq!(&*x, "hello"); + /// ``` + #[must_use = "losing the pointer will leak memory"] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn into_raw_with_allocator(this: Self) -> (*const T, A) { + let this = mem::ManuallyDrop::new(this); + let ptr = Self::as_ptr(&this); + // SAFETY: `this` is ManuallyDrop so the allocator will not be double-dropped + let alloc = unsafe { ptr::read(&this.alloc) }; + (ptr, alloc) + } + + /// Provides a raw pointer to the data. + /// + /// The counts are not affected in any way and the `Arc` is not consumed. The pointer is valid for + /// as long as there are strong counts in the `Arc`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x = Arc::new("hello".to_owned()); + /// let y = Arc::clone(&x); + /// let x_ptr = Arc::as_ptr(&x); + /// assert_eq!(x_ptr, Arc::as_ptr(&y)); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); + /// ``` + #[must_use] + #[stable(feature = "rc_as_ptr", since = "1.45.0")] + #[rustc_never_returns_null_ptr] + pub fn as_ptr(this: &Self) -> *const T { + let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); + + // SAFETY: This cannot go through Deref::deref or ArcInnerPtr::inner because + // this is required to retain raw/mut provenance such that e.g. `get_mut` can + // write through the pointer after the Arc is recovered through `from_raw`. + unsafe { &raw mut (*ptr).data } + } + + /// Constructs an `Arc` from a raw pointer. + /// + /// The raw pointer must have been previously returned by a call to [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator]. + /// + /// # Safety + /// + /// * Creating a `Arc` from a pointer other than one returned from + /// [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator] + /// is undefined behavior. + /// * If `U` is sized, it must have the same size and alignment as `T`. This + /// is trivially true if `U` is `T`. + /// * If `U` is unsized, its data pointer must have the same size and + /// alignment as `T`. This is trivially true if `Arc` was constructed + /// through `Arc` and then converted to `Arc` through an [unsized + /// coercion]. + /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. + /// * The raw pointer must point to a block of memory allocated by `alloc` + /// * The user of `from_raw` has to make sure a specific value of `T` is only + /// dropped once. + /// + /// This function is unsafe because improper use may lead to memory unsafety, + /// even if the returned `Arc` is never accessed. + /// + /// [into_raw]: Arc::into_raw + /// [into_raw_with_allocator]: Arc::into_raw_with_allocator + /// [transmute]: core::mem::transmute + /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let x = Arc::new_in("hello".to_owned(), System); + /// let (x_ptr, alloc) = Arc::into_raw_with_allocator(x); + /// + /// unsafe { + /// // Convert back to an `Arc` to prevent leak. + /// let x = Arc::from_raw_in(x_ptr, System); + /// assert_eq!(&*x, "hello"); + /// + /// // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe. + /// } + /// + /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! + /// ``` + /// + /// Convert a slice back into its original array: + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let x: Arc<[u32], _> = Arc::new_in([1, 2, 3], System); + /// let x_ptr: *const [u32] = Arc::into_raw_with_allocator(x).0; + /// + /// unsafe { + /// let x: Arc<[u32; 3], _> = Arc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System); + /// assert_eq!(&*x, &[1, 2, 3]); + /// } + /// ``` + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { + // SAFETY: Upheld by caller. + unsafe { + let offset = data_offset(ptr); + + // Reverse the offset to find the original ArcInner. + let arc_ptr = ptr.byte_sub(offset) as *mut ArcInner; + + Self::from_ptr_in(arc_ptr, alloc) + } + } + + /// Creates a new [`Weak`] pointer to this allocation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// let weak_five = Arc::downgrade(&five); + /// ``` + #[must_use = "this returns a new `Weak` pointer, \ + without modifying the original `Arc`"] + #[stable(feature = "arc_weak", since = "1.4.0")] + pub fn downgrade(this: &Self) -> Weak + where + A: AllocatorClone, + { + // This Relaxed is OK because we're checking the value in the CAS + // below. + let mut cur = this.inner().weak.load(Relaxed); + + loop { + // check if the weak counter is currently "locked"; if so, spin. + if cur == usize::MAX { + hint::spin_loop(); + cur = this.inner().weak.load(Relaxed); + continue; + } + + // We can't allow the refcount to increase much past `MAX_REFCOUNT`. + if cur > MAX_REFCOUNT { + panic_arc_overflow(); + } + // NOTE: this code currently ignores the possibility of overflow + // into usize::MAX; in general both Rc and Arc need to be adjusted + // to deal with overflow. + + // Unlike with Clone(), we need this to be an Acquire read to + // synchronize with the write coming from `is_unique`, so that the + // events prior to that write happen before this read. + match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) { + Ok(_) => { + // Make sure we do not create a dangling Weak + debug_assert!(!is_dangling(this.ptr.as_ptr())); + return Weak { ptr: this.ptr, alloc: this.alloc.clone() }; + } + Err(old) => cur = old, + } + } + } + + /// Gets the number of [`Weak`] pointers to this allocation. + /// + /// # Safety + /// + /// This method by itself is safe, but using it correctly requires extra care. + /// Another thread can change the weak count at any time, + /// including potentially between calling this method and acting on the result. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let _weak_five = Arc::downgrade(&five); + /// + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` or `Weak` between threads. + /// assert_eq!(1, Arc::weak_count(&five)); + /// ``` + #[inline] + #[must_use] + #[stable(feature = "arc_counts", since = "1.15.0")] + pub fn weak_count(this: &Self) -> usize { + let cnt = this.inner().weak.load(Relaxed); + // If the weak count is currently locked, the value of the + // count was 0 just before taking the lock. + if cnt == usize::MAX { 0 } else { cnt - 1 } + } + + /// Gets the number of strong (`Arc`) pointers to this allocation. + /// + /// # Safety + /// + /// This method by itself is safe, but using it correctly requires extra care. + /// Another thread can change the strong count at any time, + /// including potentially between calling this method and acting on the result. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let _also_five = Arc::clone(&five); + /// + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` between threads. + /// assert_eq!(2, Arc::strong_count(&five)); + /// ``` + #[inline] + #[must_use] + #[stable(feature = "arc_counts", since = "1.15.0")] + pub fn strong_count(this: &Self) -> usize { + this.inner().strong.load(Relaxed) + } + + /// Increments the strong reference count on the `Arc` associated with the + /// provided pointer by one. + /// + /// # Safety + /// + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) for the duration of this method, and `ptr` must point to a block of memory + /// allocated by `alloc`. + /// + /// [from_raw_in]: Arc::from_raw_in + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let five = Arc::new_in(5, System); + /// + /// unsafe { + /// let (ptr, _alloc) = Arc::into_raw_with_allocator(five); + /// Arc::increment_strong_count_in(ptr, System); + /// + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` between threads. + /// let five = Arc::from_raw_in(ptr, System); + /// assert_eq!(2, Arc::strong_count(&five)); + /// # // Prevent leaks for Miri. + /// # Arc::decrement_strong_count_in(ptr, System); + /// } + /// ``` + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub unsafe fn increment_strong_count_in(ptr: *const T, alloc: A) + where + A: AllocatorClone, + { + // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop + // SAFETY: Upheld by caller. + let arc = unsafe { mem::ManuallyDrop::new(Arc::from_raw_in(ptr, alloc)) }; + // Now increase refcount, but don't drop new refcount either + let _arc_clone: mem::ManuallyDrop<_> = arc.clone(); + } + + /// Decrements the strong reference count on the `Arc` associated with the + /// provided pointer by one. + /// + /// # Safety + /// + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) when invoking this method, and `ptr` must point to a block of memory + /// allocated by `alloc`. This method can be used to release the final + /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been + /// released. + /// + /// [from_raw_in]: Arc::from_raw_in + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let five = Arc::new_in(5, System); + /// + /// unsafe { + /// let (ptr, _alloc) = Arc::into_raw_with_allocator(five); + /// Arc::increment_strong_count_in(ptr, System); + /// + /// // Those assertions are deterministic because we haven't shared + /// // the `Arc` between threads. + /// let five = Arc::from_raw_in(ptr, System); + /// assert_eq!(2, Arc::strong_count(&five)); + /// Arc::decrement_strong_count_in(ptr, System); + /// assert_eq!(1, Arc::strong_count(&five)); + /// } + /// ``` + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A) { + // SAFETY: Upheld by caller. + unsafe { drop(Arc::from_raw_in(ptr, alloc)) }; + } + + #[inline] + fn inner(&self) -> &ArcInner { + // SAFETY: While this arc is alive we're guaranteed + // that the inner pointer is valid. Furthermore, we know that the + // `ArcInner` structure itself is `Sync` if the inner data is + // `Sync` as well, so we're ok loaning out an immutable pointer to these + // contents. + unsafe { self.ptr.as_ref() } + } + + // Non-inlined part of `drop`. + #[inline(never)] + unsafe fn drop_slow(&mut self) { + // Drop the weak ref collectively held by all strong references when this + // variable goes out of scope. This ensures that the memory is deallocated + // even if the destructor of `T` panics. + // Take a reference to `self.alloc` instead of cloning because 1. it'll last long + // enough, and 2. you should be able to drop `Arc`s with unclonable allocators + let _weak = Weak { ptr: self.ptr, alloc: &self.alloc }; + + // Destroy the data at this time, even though we must not free the box + // allocation itself (there might still be weak pointers lying around). + // We cannot use `get_mut_unchecked` here, because `self.alloc` is borrowed. + // ignore-tidy-undocumented-unsafe + unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; + } + + /// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to + /// [`ptr::eq`]. This function ignores the metadata of `dyn Trait` pointers. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let same_five = Arc::clone(&five); + /// let other_five = Arc::new(5); + /// + /// assert!(Arc::ptr_eq(&five, &same_five)); + /// assert!(!Arc::ptr_eq(&five, &other_five)); + /// ``` + /// + /// [`ptr::eq`]: core::ptr::eq "ptr::eq" + #[inline] + #[must_use] + #[stable(feature = "ptr_eq", since = "1.17.0")] + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr()) + } +} + +impl Arc { + /// Allocates an `ArcInner` with sufficient space for + /// a possibly-unsized inner value where the value has the layout provided. + /// + /// The function `mem_to_arcinner` is called with the data pointer + /// and must return back a (potentially fat)-pointer for the `ArcInner`. + #[cfg(not(no_global_oom_handling))] + unsafe fn allocate_for_layout( + value_layout: Layout, + allocate: impl FnOnce(Layout) -> Result, AllocError>, + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, + ) -> *mut ArcInner { + let layout = arcinner_layout_for_value_layout(value_layout); + + let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + + // ignore-tidy-undocumented-unsafe + unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) } + } + + /// Allocates an `ArcInner` with sufficient space for + /// a possibly-unsized inner value where the value has the layout provided, + /// returning an error if allocation fails. + /// + /// The function `mem_to_arcinner` is called with the data pointer + /// and must return back a (potentially fat)-pointer for the `ArcInner`. + unsafe fn try_allocate_for_layout( + value_layout: Layout, + allocate: impl FnOnce(Layout) -> Result, AllocError>, + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, + ) -> Result<*mut ArcInner, AllocError> { + let layout = arcinner_layout_for_value_layout(value_layout); + + let ptr = allocate(layout)?; + + // ignore-tidy-undocumented-unsafe + let inner = unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) }; + + Ok(inner) + } + + unsafe fn initialize_arcinner( + ptr: NonNull<[u8]>, + layout: Layout, + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, + ) -> *mut ArcInner { + let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr()); + // SAFETY: Upheld by caller. + debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); + + // ignore-tidy-undocumented-unsafe + unsafe { + (&raw mut (*inner).strong).write(atomic::AtomicUsize::new(1)); + (&raw mut (*inner).weak).write(atomic::AtomicUsize::new(1)); + } + + inner + } +} + +impl Arc { + /// Allocates an `ArcInner` with sufficient space for an unsized inner value. + #[inline] + #[cfg(not(no_global_oom_handling))] + unsafe fn allocate_for_ptr_in(ptr: *const T, alloc: &A) -> *mut ArcInner { + // Allocate for the `ArcInner` using the given value. + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::allocate_for_layout( + Layout::for_value_raw(ptr), + |layout| alloc.allocate(layout), + |mem| mem.with_metadata_of(ptr as *const ArcInner), + ) + } + } + + #[cfg(not(no_global_oom_handling))] + fn from_box_in(src: Box) -> Arc { + // ignore-tidy-undocumented-unsafe + unsafe { + let value_size = size_of_val(&*src); + let ptr = Self::allocate_for_ptr_in(&*src, Box::allocator(&src)); + + // Copy value as bytes + ptr::copy_nonoverlapping( + (&raw const *src) as *const u8, + (&raw mut (*ptr).data) as *mut u8, + value_size, + ); + + // Free the allocation without dropping its contents + let (bptr, alloc) = Box::into_raw_with_allocator(src); + let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop, &alloc); + drop(src); + + Self::from_ptr_in(ptr, alloc) + } + } +} + +impl Arc<[T]> { + /// Allocates an `ArcInner<[T]>` with the given length. + #[cfg(not(no_global_oom_handling))] + unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { + // ignore-tidy-undocumented-unsafe + unsafe { + Self::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| Global.allocate(layout), + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[T]>, + ) + } + } + + /// Copy elements from slice into newly allocated `Arc<[T]>` + /// + /// Unsafe because the caller must either take ownership, bind `T: Copy` or + /// bind `T: TrivialClone`. + #[cfg(not(no_global_oom_handling))] + unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { + // ignore-tidy-undocumented-unsafe + unsafe { + let ptr = Self::allocate_for_slice(v.len()); + + ptr::copy_nonoverlapping(v.as_ptr(), (&raw mut (*ptr).data) as *mut T, v.len()); + + Self::from_ptr(ptr) + } + } + + /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size. + /// + /// Behavior is undefined should the size be wrong. + #[cfg(not(no_global_oom_handling))] + unsafe fn from_iter_exact(iter: impl Iterator, len: usize) -> Arc<[T]> { + // Panic guard while cloning T elements. + // In the event of a panic, elements that have been written + // into the new ArcInner will be dropped, then the memory freed. + struct Guard { + mem: NonNull, + elems: *mut T, + layout: Layout, + n_elems: usize, + } + + impl Drop for Guard { + fn drop(&mut self) { + // ignore-tidy-undocumented-unsafe + unsafe { + let slice = from_raw_parts_mut(self.elems, self.n_elems); + ptr::drop_in_place(slice); + + Global.deallocate(self.mem, self.layout); + } + } + } + + // ignore-tidy-undocumented-unsafe + unsafe { + let ptr = Self::allocate_for_slice(len); + + let mem = ptr as *mut _ as *mut u8; + let layout = Layout::for_value_raw(ptr); + + // Pointer to first element + let elems = (&raw mut (*ptr).data) as *mut T; + + let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; + + for (i, item) in iter.enumerate() { + ptr::write(elems.add(i), item); + guard.n_elems += 1; + } + + // All clear. Forget the guard so it doesn't free the new ArcInner. + mem::forget(guard); + + Self::from_ptr(ptr) + } + } +} + +impl Arc<[T], A> { + /// Allocates an `ArcInner<[T]>` with the given length. + #[inline] + #[cfg(not(no_global_oom_handling))] + unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut ArcInner<[T]> { + // ignore-tidy-undocumented-unsafe + unsafe { + Arc::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| alloc.allocate(layout), + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[T]>, + ) + } + } +} + +/// Specialization trait used for `From<&[T]>`. +#[cfg(not(no_global_oom_handling))] +trait ArcFromSlice { + fn from_slice(slice: &[T]) -> Self; +} + +#[cfg(not(no_global_oom_handling))] +impl ArcFromSlice for Arc<[T]> { + #[inline] + default fn from_slice(v: &[T]) -> Self { + // ignore-tidy-undocumented-unsafe + unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) } + } +} + +#[cfg(not(no_global_oom_handling))] +impl ArcFromSlice for Arc<[T]> { + #[inline] + fn from_slice(v: &[T]) -> Self { + // SAFETY: `T` implements `TrivialClone`, so this is sound and equivalent + // to the above. + unsafe { Arc::copy_from_slice(v) } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for Arc { + /// Makes a clone of the `Arc` pointer. + /// + /// This creates another pointer to the same allocation, increasing the + /// strong reference count. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// let _ = Arc::clone(&five); + /// ``` + #[inline] + fn clone(&self) -> Arc { + // Using a relaxed ordering is alright here, as knowledge of the + // original reference prevents other threads from erroneously deleting + // the object. + // + // As explained in the [Boost documentation][1], Increasing the + // reference counter can always be done with memory_order_relaxed: New + // references to an object can only be formed from an existing + // reference, and passing an existing reference from one thread to + // another must already provide any required synchronization. + // + // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) + let old_size = self.inner().strong.fetch_add(1, Relaxed); + + // However we need to guard against massive refcounts in case someone is `mem::forget`ing + // Arcs. If we don't do this the count can overflow and users will use-after free. This + // branch will never be taken in any realistic program. We abort because such a program is + // incredibly degenerate, and we don't care to support it. + // + // This check is not 100% water-proof: we error when the refcount grows beyond `isize::MAX`. + // But we do that check *after* having done the increment, so there is a chance here that + // the worst already happened and we actually do overflow the `usize` counter. However, that + // requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment + // above and the `abort` below, which seems exceedingly unlikely. + // + // This is a global invariant, and also applies when using a compare-exchange loop to increment + // counters in other methods. + // Otherwise, the counter could be brought to an almost-overflow using a compare-exchange loop, + // and then overflow using a few `fetch_add`s. + if old_size > MAX_REFCOUNT { + abort(); + } + + // SAFETY: Pointer is valid & allocator corresponds to the one used to allocate it. + unsafe { Self::from_inner_in(self.ptr, self.alloc.clone()) } + } +} + +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for Arc {} + +#[unstable(feature = "share_trait", issue = "156756")] +impl Share for Arc {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Deref for Arc { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.inner().data + } +} + +// The API of this pointer type enforces that if the `T` is pinned, then *all* +// clones of this `Arc` are wrapped as `Pin>`. Since an `&Arc` +// could be used to obtain an `Arc` that is not wrapped in `Pin` (and later +// used with `Arc::get_mut`), this means that this type treats `&Arc` as +// evidence that the `T` is not pinned. The implementations of various traits +// are written accordingly. Since this type is not fundamental, downstream +// crates cannot provide malicious implementations of any of the traits relevant +// for `Pin`. +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] +unsafe impl PinSafePointer for Arc {} + +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for Arc {} + +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for Arc {} + +#[cfg(not(no_global_oom_handling))] +impl Arc { + /// Makes a mutable reference into the given `Arc`. + /// + /// If there are other `Arc` pointers to the same allocation, then `make_mut` will + /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also + /// referred to as clone-on-write. + /// + /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`] + /// pointers, then the [`Weak`] pointers will be dissociated and the inner value will not + /// be cloned. + /// + /// See also [`get_mut`], which will fail rather than cloning the inner value + /// or dissociating [`Weak`] pointers. + /// + /// [`clone`]: Clone::clone + /// [`get_mut`]: Arc::get_mut + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut data = Arc::new(5); + /// + /// *Arc::make_mut(&mut data) += 1; // Won't clone anything + /// let mut other_data = Arc::clone(&data); // Won't clone inner data + /// *Arc::make_mut(&mut data) += 1; // Clones inner data + /// *Arc::make_mut(&mut data) += 1; // Won't clone anything + /// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything + /// + /// // Now `data` and `other_data` point to different allocations. + /// assert_eq!(*data, 8); + /// assert_eq!(*other_data, 12); + /// ``` + /// + /// [`Weak`] pointers will be dissociated: + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut data = Arc::new(75); + /// let weak = Arc::downgrade(&data); + /// + /// assert!(75 == *data); + /// assert!(75 == *weak.upgrade().unwrap()); + /// + /// *Arc::make_mut(&mut data) += 1; + /// + /// assert!(76 == *data); + /// assert!(weak.upgrade().is_none()); + /// ``` + #[inline] + #[stable(feature = "arc_unique", since = "1.4.0")] + pub fn make_mut(this: &mut Self) -> &mut T { + let size_of_val = size_of_val::(&**this); + + // Note that we hold both a strong reference and a weak reference. + // Thus, releasing our strong reference only will not, by itself, cause + // the memory to be deallocated. + // + // Use Acquire to ensure that we see any writes to `weak` that happen + // before release writes (i.e., decrements) to `strong`. Since we hold a + // weak count, there's no chance the ArcInner itself could be + // deallocated. + if this.inner().strong.compare_exchange(1, 0, Acquire, Relaxed).is_err() { + // Another strong pointer exists, so we must clone. + *this = Arc::clone_from_ref_in(&**this, this.alloc.clone()); + } else if this.inner().weak.load(Relaxed) != 1 { + // Relaxed suffices in the above because this is fundamentally an + // optimization: we are always racing with weak pointers being + // dropped. Worst case, we end up allocated a new Arc unnecessarily. + + // We removed the last strong ref, but there are additional weak + // refs remaining. We'll move the contents to a new Arc, and + // invalidate the other weak refs. + + // Note that it is not possible for the read of `weak` to yield + // usize::MAX (i.e., locked), since the weak count can only be + // locked by a thread with a strong reference. + + // Guard against panics while using the allocator. + // If we unwind before the Arc is overwritten, we expose a strong + // count of 0, resulting in a UAF (#155746, #157203). + // Until the new Arc is written, the old Arc must remain valid + struct Guard<'a, T: ?Sized> { + inner: &'a ArcInner, + } + impl<'a, T: ?Sized> Drop for Guard<'a, T> { + fn drop(&mut self) { + self.inner.strong.store(1, Release); + } + } + let guard = Guard { inner: this.inner() }; + + // Can just steal the data, all that's left is Weaks + // Note that this can panic in two ways: + // - The allocation can fail + // - The allocator clone can fail + let mut in_progress: UniqueArcUninit = + UniqueArcUninit::new(&**this, this.alloc.clone()); + + // ignore-tidy-undocumented-unsafe + unsafe { + // Initialize `in_progress` with move of **this. + // We have to express this in terms of bytes because `T: ?Sized`; there is no + // operation that just copies a value based on its `size_of_val()`. + ptr::copy_nonoverlapping( + ptr::from_ref(&**this).cast::(), + in_progress.data_ptr().cast::(), + size_of_val, + ); + + // We are now safe from panics. + mem::forget(guard); + + // Materialize our own implicit weak pointer, so that it can clean + // up the ArcInner as needed. + // Make sure the allocator is not leaked when the Arc is overwritten. + // Only drop at the end of the scope to avoid panics. + let _weak = Weak { ptr: this.ptr, alloc: ptr::read(&this.alloc) }; + + ptr::write(this, in_progress.into_arc()); + } + } else { + // We were the sole reference of either kind; bump back up the + // strong ref count. + this.inner().strong.store(1, Release); + } + + // SAFETY: As with `get_mut()`, our reference was + // either unique to begin with, or became one upon cloning the contents. + unsafe { Self::get_mut_unchecked(this) } + } +} + +impl Arc { + /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the + /// clone. + /// + /// Assuming `arc_t` is of type `Arc`, this function is functionally equivalent to + /// `(*arc_t).clone()`, but will avoid cloning the inner value where possible. + /// + /// # Examples + /// + /// ``` + /// # use std::{ptr, sync::Arc}; + /// let inner = String::from("test"); + /// let ptr = inner.as_ptr(); + /// + /// let arc = Arc::new(inner); + /// let inner = Arc::unwrap_or_clone(arc); + /// // The inner value was not cloned + /// assert!(ptr::eq(ptr, inner.as_ptr())); + /// + /// let arc = Arc::new(inner); + /// let arc2 = arc.clone(); + /// let inner = Arc::unwrap_or_clone(arc); + /// // Because there were 2 references, we had to clone the inner value. + /// assert!(!ptr::eq(ptr, inner.as_ptr())); + /// // `arc2` is the last reference, so when we unwrap it we get back + /// // the original `String`. + /// let inner = Arc::unwrap_or_clone(arc2); + /// assert!(ptr::eq(ptr, inner.as_ptr())); + /// ``` + #[inline] + #[stable(feature = "arc_unwrap_or_clone", since = "1.76.0")] + pub fn unwrap_or_clone(this: Self) -> T { + Arc::try_unwrap(this).unwrap_or_else(|arc| (*arc).clone()) + } +} + +impl Arc { + /// Returns a mutable reference into the given `Arc`, if there are + /// no other `Arc` or [`Weak`] pointers to the same allocation. + /// + /// Returns [`None`] otherwise, because it is not safe to + /// mutate a shared value. + /// + /// See also [`make_mut`][make_mut], which will [`clone`][clone] + /// the inner value when there are other `Arc` pointers. + /// + /// [make_mut]: Arc::make_mut + /// [clone]: Clone::clone + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut x = Arc::new(3); + /// *Arc::get_mut(&mut x).unwrap() = 4; + /// assert_eq!(*x, 4); + /// + /// let _y = Arc::clone(&x); + /// assert!(Arc::get_mut(&mut x).is_none()); + /// ``` + #[inline] + #[stable(feature = "arc_unique", since = "1.4.0")] + pub fn get_mut(this: &mut Self) -> Option<&mut T> { + if Self::is_unique(this) { + // SAFETY: We're guaranteed that the pointer + // returned is the *only* pointer that will ever be returned to T. Our + // reference count is guaranteed to be 1 at this point, and we required + // the Arc itself to be `mut`, so we're returning the only possible + // reference to the inner data. + unsafe { Some(Arc::get_mut_unchecked(this)) } + } else { + None + } + } + + /// Returns a mutable reference into the given `Arc`, + /// without any check. + /// + /// See also [`get_mut`], which is safe and does appropriate checks. + /// + /// [`get_mut`]: Arc::get_mut + /// + /// # Safety + /// + /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then + /// they must not be dereferenced or have active borrows for the duration + /// of the returned borrow, and their inner type must be exactly the same as the + /// inner type of this Arc (including lifetimes). This is trivially the case if no + /// such pointers exist, for example immediately after `Arc::new`. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_mut_unchecked)] + /// + /// use std::sync::Arc; + /// + /// let mut x = Arc::new(String::new()); + /// unsafe { + /// Arc::get_mut_unchecked(&mut x).push_str("foo") + /// } + /// assert_eq!(*x, "foo"); + /// ``` + /// Other `Arc` pointers to the same allocation must be to the same type. + /// ```no_run + /// #![feature(get_mut_unchecked)] + /// + /// use std::sync::Arc; + /// + /// let x: Arc = Arc::from("Hello, world!"); + /// let mut y: Arc<[u8]> = x.clone().into(); + /// unsafe { + /// // this is Undefined Behavior, because x's inner type is str, not [u8] + /// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8 + /// } + /// println!("{}", &*x); // Invalid UTF-8 in a str + /// ``` + /// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes. + /// ```no_run + /// #![feature(get_mut_unchecked)] + /// + /// use std::sync::Arc; + /// + /// let x: Arc<&str> = Arc::new("Hello, world!"); + /// { + /// let s = String::from("Oh, no!"); + /// let mut y: Arc<&str> = x.clone(); + /// unsafe { + /// // this is Undefined Behavior, because x's inner type + /// // is &'long str, not &'short str + /// *Arc::get_mut_unchecked(&mut y) = &s; + /// } + /// } + /// println!("{}", &*x); // Use-after-free + /// ``` + #[inline] + #[unstable(feature = "get_mut_unchecked", issue = "63292")] + pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T { + // We are careful to *not* create a reference covering the "count" fields, as + // this would alias with concurrent access to the reference counts (e.g. by `Weak`). + // ignore-tidy-undocumented-unsafe + unsafe { &mut (*this.ptr.as_ptr()).data } + } + + /// Determine whether this is the unique reference to the underlying data. + /// + /// Returns `true` if there are no other `Arc` or [`Weak`] pointers to the same allocation; + /// returns `false` otherwise. + /// + /// If this function returns `true`, then is guaranteed to be safe to call [`get_mut_unchecked`] + /// on this `Arc`, so long as no clones occur in between. + /// + /// # Examples + /// + /// ``` + /// #![feature(arc_is_unique)] + /// + /// use std::sync::Arc; + /// + /// let x = Arc::new(3); + /// assert!(Arc::is_unique(&x)); + /// + /// let y = Arc::clone(&x); + /// assert!(!Arc::is_unique(&x)); + /// drop(y); + /// + /// // Weak references also count, because they could be upgraded at any time. + /// let z = Arc::downgrade(&x); + /// assert!(!Arc::is_unique(&x)); + /// ``` + /// + /// # Pointer invalidation + /// + /// This function will always return the same value as `Arc::get_mut(arc).is_some()`. However, + /// unlike that operation it does not produce any mutable references to the underlying data, + /// meaning no pointers to the data inside the `Arc` are invalidated by the call. Thus, the + /// following code is valid, even though it would be UB if it used `Arc::get_mut`: + /// + /// ``` + /// #![feature(arc_is_unique)] + /// + /// use std::sync::Arc; + /// + /// let arc = Arc::new(5); + /// let pointer: *const i32 = &*arc; + /// assert!(Arc::is_unique(&arc)); + /// assert_eq!(unsafe { *pointer }, 5); + /// ``` + /// + /// # Atomic orderings + /// + /// Concurrent drops to other `Arc` pointers to the same allocation will synchronize with this + /// call - that is, this call performs an `Acquire` operation on the underlying strong and weak + /// ref counts. This ensures that calling `get_mut_unchecked` is safe. + /// + /// Note that this operation requires locking the weak ref count, so concurrent calls to + /// `downgrade` may spin-loop for a short period of time. + /// + /// [`get_mut_unchecked`]: Self::get_mut_unchecked + #[inline] + #[unstable(feature = "arc_is_unique", issue = "138938")] + pub fn is_unique(this: &Self) -> bool { + // lock the weak pointer count if we appear to be the sole weak pointer + // holder. + // + // The acquire label here ensures a happens-before relationship with any + // writes to `strong` (in particular in `Weak::upgrade`) prior to decrements + // of the `weak` count (via `Weak::drop`, which uses release). If the upgraded + // weak ref was never dropped, the CAS here will fail so we do not care to synchronize. + if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() { + // This needs to be an `Acquire` to synchronize with the decrement of the `strong` + // counter in `drop` -- the only access that happens when any but the last reference + // is being dropped. + let unique = this.inner().strong.load(Acquire) == 1; + + // The release write here synchronizes with a read in `downgrade`, + // effectively preventing the above read of `strong` from happening + // after the write. + this.inner().weak.store(1, Release); // release the lock + unique + } else { + false + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Arc { + /// Drops the `Arc`. + /// + /// This will decrement the strong reference count. If the strong reference + /// count reaches zero then the only other references (if any) are + /// [`Weak`], so we `drop` the inner value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// struct Foo; + /// + /// impl Drop for Foo { + /// fn drop(&mut self) { + /// println!("dropped!"); + /// } + /// } + /// + /// let foo = Arc::new(Foo); + /// let foo2 = Arc::clone(&foo); + /// + /// drop(foo); // Doesn't print anything + /// drop(foo2); // Prints "dropped!" + /// ``` + #[inline] + fn drop(&mut self) { + // Because `fetch_sub` is already atomic, we do not need to synchronize + // with other threads unless we are going to delete the object. This + // same logic applies to the below `fetch_sub` to the `weak` count. + if self.inner().strong.fetch_sub(1, Release) != 1 { + return; + } + + // This fence is needed to prevent reordering of use of the data and + // deletion of the data. Because it is marked `Release`, the decreasing + // of the reference count synchronizes with this `Acquire` fence. This + // means that use of the data happens before decreasing the reference + // count, which happens before this fence, which happens before the + // deletion of the data. + // + // As explained in the [Boost documentation][1], + // + // > It is important to enforce any possible access to the object in one + // > thread (through an existing reference) to *happen before* deleting + // > the object in a different thread. This is achieved by a "release" + // > operation after dropping a reference (any access to the object + // > through this reference must obviously happened before), and an + // > "acquire" operation before deleting the object. + // + // In particular, while the contents of an Arc are usually immutable, it's + // possible to have interior writes to something like a Mutex. Since a + // Mutex is not acquired when it is deleted, we can't rely on its + // synchronization logic to make writes in thread A visible to a destructor + // running in thread B. + // + // Also note that the Acquire fence here could probably be replaced with an + // Acquire load, which could improve performance in highly-contended + // situations. See [2]. + // + // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) + // [2]: (https://github.com/rust-lang/rust/pull/41714) + acquire!(self.inner().strong); + + // Make sure we aren't trying to "drop" the shared static for empty slices + // used by Default::default. + debug_assert!( + !ptr::addr_eq(self.ptr.as_ptr(), &STATIC_INNER_SLICE.inner), + "Arcs backed by a static should never reach a strong count of 0. \ + Likely decrement_strong_count or from_raw were called too many times.", + ); + + // ignore-tidy-undocumented-unsafe + unsafe { + self.drop_slow(); + } + } +} + +impl Arc { + /// Attempts to downcast the `Arc` to a concrete type. + /// + /// # Examples + /// + /// ``` + /// use std::any::Any; + /// use std::sync::Arc; + /// + /// fn print_if_string(value: Arc) { + /// if let Ok(string) = value.downcast::() { + /// println!("String ({}): {}", string.len(), string); + /// } + /// } + /// + /// let my_string = "Hello World".to_string(); + /// print_if_string(Arc::new(my_string)); + /// print_if_string(Arc::new(0i8)); + /// ``` + #[inline] + #[stable(feature = "rc_downcast", since = "1.29.0")] + pub fn downcast(self) -> Result, Self> + where + T: Any + Send + Sync, + { + if (*self).is::() { + // SAFETY: Check ensures the typecast is okay. + unsafe { + let (ptr, alloc) = Arc::into_inner_with_allocator(self); + Ok(Arc::from_inner_in(ptr.cast(), alloc)) + } + } else { + Err(self) + } + } + + /// Downcasts the `Arc` to a concrete type. + /// + /// For a safe alternative see [`downcast`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(downcast_unchecked)] + /// + /// use std::any::Any; + /// use std::sync::Arc; + /// + /// let x: Arc = Arc::new(1_usize); + /// + /// unsafe { + /// assert_eq!(*x.downcast_unchecked::(), 1); + /// } + /// ``` + /// + /// # Safety + /// + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. + /// + /// + /// [`downcast`]: Self::downcast + #[inline] + #[unstable(feature = "downcast_unchecked", issue = "90850")] + pub unsafe fn downcast_unchecked(self) -> Arc + where + T: Any + Send + Sync, + { + // SAFETY: Upheld by caller. + unsafe { + let (ptr, alloc) = Arc::into_inner_with_allocator(self); + Arc::from_inner_in(ptr.cast(), alloc) + } + } +} + +impl Weak { + /// Constructs a new `Weak`, without allocating any memory. + /// Calling [`upgrade`] on the return value always gives [`None`]. + /// + /// [`upgrade`]: Weak::upgrade + /// + /// # Examples + /// + /// ``` + /// use std::sync::Weak; + /// + /// let empty: Weak = Weak::new(); + /// assert!(empty.upgrade().is_none()); + /// ``` + #[inline] + #[stable(feature = "downgraded_weak", since = "1.10.0")] + #[rustc_const_stable(feature = "const_weak_new", since = "1.73.0")] + #[must_use] + pub const fn new() -> Weak { + Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc: Global } + } +} + +impl Weak { + /// Constructs a new `Weak`, without allocating any memory, technically in the provided + /// allocator. + /// Calling [`upgrade`] on the return value always gives [`None`]. + /// + /// [`upgrade`]: Weak::upgrade + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// + /// use std::sync::Weak; + /// use std::alloc::System; + /// + /// let empty: Weak = Weak::new_in(System); + /// assert!(empty.upgrade().is_none()); + /// ``` + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn new_in(alloc: A) -> Weak { + Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc } + } +} + +/// Helper type to allow accessing the reference counts without +/// making any assertions about the data field. +struct WeakInner<'a> { + weak: &'a Atomic, + strong: &'a Atomic, +} + +impl Weak { + /// Converts a raw pointer previously created by [`into_raw`] back into `Weak`. + /// + /// This can be used to safely get a strong reference (by calling [`upgrade`] + /// later) or to deallocate the weak count by dropping the `Weak`. + /// + /// It takes ownership of one weak reference (with the exception of pointers created by [`new`], + /// as these don't own anything; the method still works on them). + /// + /// # Safety + /// + /// The pointer must have originated from the [`into_raw`] and must still own its potential + /// weak reference, and must point to a block of memory allocated by global allocator. + /// + /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this + /// takes ownership of one weak reference currently represented as a raw pointer (the weak + /// count is not modified by this operation) and therefore it must be paired with a previous + /// call to [`into_raw`]. + /// # Examples + /// + /// ``` + /// use std::sync::{Arc, Weak}; + /// + /// let strong = Arc::new("hello".to_owned()); + /// + /// let raw_1 = Arc::downgrade(&strong).into_raw(); + /// let raw_2 = Arc::downgrade(&strong).into_raw(); + /// + /// assert_eq!(2, Arc::weak_count(&strong)); + /// + /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); + /// assert_eq!(1, Arc::weak_count(&strong)); + /// + /// drop(strong); + /// + /// // Decrement the last weak count. + /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); + /// ``` + /// + /// [`new`]: Weak::new + /// [`into_raw`]: Weak::into_raw + /// [`upgrade`]: Weak::upgrade + #[inline] + #[stable(feature = "weak_into_raw", since = "1.45.0")] + pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Upheld by caller. + unsafe { Weak::from_raw_in(ptr, Global) } + } + + /// Consumes the `Weak` and turns it into a raw pointer. + /// + /// This converts the weak pointer into a raw pointer, while still preserving the ownership of + /// one weak reference (the weak count is not modified by this operation). It can be turned + /// back into the `Weak` with [`from_raw`]. + /// + /// The same restrictions of accessing the target of the pointer as with + /// [`as_ptr`] apply. + /// + /// # Examples + /// + /// ``` + /// use std::sync::{Arc, Weak}; + /// + /// let strong = Arc::new("hello".to_owned()); + /// let weak = Arc::downgrade(&strong); + /// let raw = weak.into_raw(); + /// + /// assert_eq!(1, Arc::weak_count(&strong)); + /// assert_eq!("hello", unsafe { &*raw }); + /// + /// drop(unsafe { Weak::from_raw(raw) }); + /// assert_eq!(0, Arc::weak_count(&strong)); + /// ``` + /// + /// [`from_raw`]: Weak::from_raw + /// [`as_ptr`]: Weak::as_ptr + #[must_use = "losing the pointer will leak memory"] + #[stable(feature = "weak_into_raw", since = "1.45.0")] + pub fn into_raw(self) -> *const T { + ManuallyDrop::new(self).as_ptr() + } +} + +impl Weak { + /// Returns a reference to the underlying allocator. + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn allocator(&self) -> &A { + &self.alloc + } + + /// Returns a raw pointer to the object `T` pointed to by this `Weak`. + /// + /// The pointer is valid only if there are some strong references. The pointer may be dangling, + /// unaligned or even [`null`] otherwise. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use std::ptr; + /// + /// let strong = Arc::new("hello".to_owned()); + /// let weak = Arc::downgrade(&strong); + /// // Both point to the same object + /// assert!(ptr::eq(&*strong, weak.as_ptr())); + /// // The strong here keeps it alive, so we can still access the object. + /// assert_eq!("hello", unsafe { &*weak.as_ptr() }); + /// + /// drop(strong); + /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to + /// // undefined behavior. + /// // assert_eq!("hello", unsafe { &*weak.as_ptr() }); + /// ``` + /// + /// [`null`]: core::ptr::null "ptr::null" + #[must_use] + #[stable(feature = "weak_into_raw", since = "1.45.0")] + pub fn as_ptr(&self) -> *const T { + let ptr: *mut ArcInner = NonNull::as_ptr(self.ptr); + + if is_dangling(ptr) { + // If the pointer is dangling, we return the sentinel directly. This cannot be + // a valid payload address, as the payload is at least as aligned as ArcInner (usize). + ptr as *const T + } else { + // SAFETY: if is_dangling returns false, then the pointer is dereferenceable. + // The payload may be dropped at this point, and we have to maintain provenance, + // so use raw pointer manipulation. + unsafe { &raw mut (*ptr).data } + } + } + + /// Consumes the `Weak`, returning the wrapped pointer and allocator. + /// + /// This converts the weak pointer into a raw pointer, while still preserving the ownership of + /// one weak reference (the weak count is not modified by this operation). It can be turned + /// back into the `Weak` with [`from_raw_in`]. + /// + /// The same restrictions of accessing the target of the pointer as with + /// [`as_ptr`] apply. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// use std::sync::{Arc, Weak}; + /// use std::alloc::System; + /// + /// let strong = Arc::new_in("hello".to_owned(), System); + /// let weak = Arc::downgrade(&strong); + /// let (raw, alloc) = weak.into_raw_with_allocator(); + /// + /// assert_eq!(1, Arc::weak_count(&strong)); + /// assert_eq!("hello", unsafe { &*raw }); + /// + /// drop(unsafe { Weak::from_raw_in(raw, alloc) }); + /// assert_eq!(0, Arc::weak_count(&strong)); + /// ``` + /// + /// [`from_raw_in`]: Weak::from_raw_in + /// [`as_ptr`]: Weak::as_ptr + #[must_use = "losing the pointer will leak memory"] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub fn into_raw_with_allocator(self) -> (*const T, A) { + let this = mem::ManuallyDrop::new(self); + let result = this.as_ptr(); + // SAFETY: `this` is ManuallyDrop so the allocator will not be double-dropped + let alloc = unsafe { ptr::read(&this.alloc) }; + (result, alloc) + } + + /// Converts a raw pointer previously created by [`into_raw`] back into `Weak` in the provided + /// allocator. + /// + /// This can be used to safely get a strong reference (by calling [`upgrade`] + /// later) or to deallocate the weak count by dropping the `Weak`. + /// + /// It takes ownership of one weak reference (with the exception of pointers created by [`new`], + /// as these don't own anything; the method still works on them). + /// + /// # Safety + /// + /// The pointer must have originated from the [`into_raw`] and must still own its potential + /// weak reference, and must point to a block of memory allocated by `alloc`. + /// + /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this + /// takes ownership of one weak reference currently represented as a raw pointer (the weak + /// count is not modified by this operation) and therefore it must be paired with a previous + /// call to [`into_raw`]. + /// # Examples + /// + /// ``` + /// use std::sync::{Arc, Weak}; + /// + /// let strong = Arc::new("hello".to_owned()); + /// + /// let raw_1 = Arc::downgrade(&strong).into_raw(); + /// let raw_2 = Arc::downgrade(&strong).into_raw(); + /// + /// assert_eq!(2, Arc::weak_count(&strong)); + /// + /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); + /// assert_eq!(1, Arc::weak_count(&strong)); + /// + /// drop(strong); + /// + /// // Decrement the last weak count. + /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); + /// ``` + /// + /// [`new`]: Weak::new + /// [`into_raw`]: Weak::into_raw + /// [`upgrade`]: Weak::upgrade + #[inline] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { + // See Weak::as_ptr for context on how the input pointer is derived. + + let ptr = if is_dangling(ptr) { + // This is a dangling Weak. + ptr as *mut ArcInner + } else { + // Otherwise, we're guaranteed the pointer came from a nondangling Weak. + // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T. + let offset = unsafe { data_offset(ptr) }; + // Thus, we reverse the offset to get the whole ArcInner. + // SAFETY: the pointer originated from a Weak, so this offset is safe. + unsafe { ptr.byte_sub(offset) as *mut ArcInner } + }; + + // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. + Weak { ptr: unsafe { NonNull::new_unchecked(ptr) }, alloc } + } +} + +impl Weak { + /// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying + /// dropping of the inner value if successful. + /// + /// Returns [`None`] in the following cases: + /// + /// 1. The inner value has since been dropped or moved out. + /// + /// 2. This `Weak` does not point to an allocation. + /// + /// 3. The owning reference this `Weak` is associated with is either not fully-constructed or does not allow an upgrade. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// let weak_five = Arc::downgrade(&five); + /// + /// let strong_five: Option> = weak_five.upgrade(); + /// assert!(strong_five.is_some()); + /// + /// // Destroy all strong pointers. + /// drop(strong_five); + /// drop(five); + /// + /// assert!(weak_five.upgrade().is_none()); + /// ``` + #[must_use = "this returns a new `Arc`, \ + without modifying the original weak pointer"] + #[stable(feature = "arc_weak", since = "1.4.0")] + pub fn upgrade(&self) -> Option> + where + A: AllocatorClone, + { + #[inline] + fn checked_increment(n: usize) -> Option { + // Any write of 0 we can observe leaves the field in permanently zero state. + if n == 0 { + return None; + } + // See comments in `Arc::clone` for why we do this (for `mem::forget`). + if n > MAX_REFCOUNT { + panic_arc_overflow(); + } + Some(n + 1) + } + + // We use a CAS loop to increment the strong count instead of a + // fetch_add as this function should never take the reference count + // from zero to one. + // + // Relaxed is fine for the failure case because we don't have any expectations about the new state. + // Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner + // value can be initialized after `Weak` references have already been created. In that case, we + // expect to observe the fully initialized value. + if self.inner()?.strong.try_update(Acquire, Relaxed, checked_increment).is_ok() { + // SAFETY: pointer is not null, verified in checked_increment + unsafe { Some(Arc::from_inner_in(self.ptr, self.alloc.clone())) } + } else { + None + } + } + + /// Gets the number of strong (`Arc`) pointers pointing to this allocation. + /// + /// If `self` was created using [`Weak::new`], this will return 0. + #[must_use] + #[stable(feature = "weak_counts", since = "1.41.0")] + pub fn strong_count(&self) -> usize { + if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 } + } + + /// Gets an approximation of the number of `Weak` pointers pointing to this + /// allocation. + /// + /// If `self` was created using [`Weak::new`], or if there are no remaining + /// strong pointers, this will return 0. + /// + /// # Accuracy + /// + /// Due to implementation details, the returned value can be off by 1 in + /// either direction when other threads are manipulating any `Arc`s or + /// `Weak`s pointing to the same allocation. + #[must_use] + #[stable(feature = "weak_counts", since = "1.41.0")] + pub fn weak_count(&self) -> usize { + if let Some(inner) = self.inner() { + let weak = inner.weak.load(Acquire); + let strong = inner.strong.load(Relaxed); + if strong == 0 { + 0 + } else { + // Since we observed that there was at least one strong pointer + // after reading the weak count, we know that the implicit weak + // reference (present whenever any strong references are alive) + // was still around when we observed the weak count, and can + // therefore safely subtract it. + weak - 1 + } + } else { + 0 + } + } + + /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`, + /// (i.e., when this `Weak` was created by `Weak::new`). + #[inline] + fn inner(&self) -> Option> { + let ptr = self.ptr.as_ptr(); + if is_dangling(ptr) { + None + } else { + // We are careful to *not* create a reference covering the "data" field, as + // the field may be mutated concurrently (for example, if the last `Arc` + // is dropped, the data field will be dropped in-place). + // ignore-tidy-undocumented-unsafe + Some(unsafe { WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak } }) + } + } + + /// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if + /// both don't point to any allocation (because they were created with `Weak::new()`). However, + /// this function ignores the metadata of `dyn Trait` pointers. + /// + /// # Notes + /// + /// Since this compares pointers it means that `Weak::new()` will equal each + /// other, even though they don't point to any allocation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let first_rc = Arc::new(5); + /// let first = Arc::downgrade(&first_rc); + /// let second = Arc::downgrade(&first_rc); + /// + /// assert!(first.ptr_eq(&second)); + /// + /// let third_rc = Arc::new(5); + /// let third = Arc::downgrade(&third_rc); + /// + /// assert!(!first.ptr_eq(&third)); + /// ``` + /// + /// Comparing `Weak::new`. + /// + /// ``` + /// use std::sync::{Arc, Weak}; + /// + /// let first = Weak::new(); + /// let second = Weak::new(); + /// assert!(first.ptr_eq(&second)); + /// + /// let third_rc = Arc::new(()); + /// let third = Arc::downgrade(&third_rc); + /// assert!(!first.ptr_eq(&third)); + /// ``` + /// + /// [`ptr::eq`]: core::ptr::eq "ptr::eq" + #[inline] + #[must_use] + #[stable(feature = "weak_ptr_eq", since = "1.39.0")] + pub fn ptr_eq(&self, other: &Self) -> bool { + ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr()) + } +} + +#[stable(feature = "arc_weak", since = "1.4.0")] +impl Clone for Weak { + /// Makes a clone of the `Weak` pointer that points to the same allocation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::{Arc, Weak}; + /// + /// let weak_five = Arc::downgrade(&Arc::new(5)); + /// + /// let _ = Weak::clone(&weak_five); + /// ``` + #[inline] + fn clone(&self) -> Weak { + if let Some(inner) = self.inner() { + // See comments in Arc::clone() for why this is relaxed. This can use a + // fetch_add (ignoring the lock) because the weak count is only locked + // where are *no other* weak pointers in existence. (So we can't be + // running this code in that case). + let old_size = inner.weak.fetch_add(1, Relaxed); + + // See comments in Arc::clone() for why we do this (for mem::forget). + if old_size > MAX_REFCOUNT { + abort(); + } + } + + Weak { ptr: self.ptr, alloc: self.alloc.clone() } + } +} + +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for Weak {} + +#[stable(feature = "downgraded_weak", since = "1.10.0")] +impl Default for Weak { + /// Constructs a new `Weak`, without allocating memory. + /// Calling [`upgrade`] on the return value always + /// gives [`None`]. + /// + /// [`upgrade`]: Weak::upgrade + /// + /// # Examples + /// + /// ``` + /// use std::sync::Weak; + /// + /// let empty: Weak = Default::default(); + /// assert!(empty.upgrade().is_none()); + /// ``` + fn default() -> Weak { + Weak::new() + } +} + +#[stable(feature = "arc_weak", since = "1.4.0")] +unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak { + /// Drops the `Weak` pointer. + /// + /// # Examples + /// + /// ``` + /// use std::sync::{Arc, Weak}; + /// + /// struct Foo; + /// + /// impl Drop for Foo { + /// fn drop(&mut self) { + /// println!("dropped!"); + /// } + /// } + /// + /// let foo = Arc::new(Foo); + /// let weak_foo = Arc::downgrade(&foo); + /// let other_weak_foo = Weak::clone(&weak_foo); + /// + /// drop(weak_foo); // Doesn't print anything + /// drop(foo); // Prints "dropped!" + /// + /// assert!(other_weak_foo.upgrade().is_none()); + /// ``` + fn drop(&mut self) { + // If we find out that we were the last weak pointer, then its time to + // deallocate the data entirely. See the discussion in Arc::drop() about + // the memory orderings + // + // It's not necessary to check for the locked state here, because the + // weak count can only be locked if there was precisely one weak ref, + // meaning that drop could only subsequently run ON that remaining weak + // ref, which can only happen after the lock is released. + let inner = if let Some(inner) = self.inner() { inner } else { return }; + + if inner.weak.fetch_sub(1, Release) == 1 { + acquire!(inner.weak); + + // Make sure we aren't trying to "deallocate" the shared static for empty slices + // used by Default::default. + debug_assert!( + !ptr::addr_eq(self.ptr.as_ptr(), &STATIC_INNER_SLICE.inner), + "Arc/Weaks backed by a static should never be deallocated. \ + Likely decrement_strong_count or from_raw were called too many times.", + ); + + // ignore-tidy-undocumented-unsafe + unsafe { + self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())) + } + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +trait ArcEqIdent { + fn eq(&self, other: &Arc) -> bool; + fn ne(&self, other: &Arc) -> bool; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ArcEqIdent for Arc { + #[inline] + default fn eq(&self, other: &Arc) -> bool { + **self == **other + } + #[inline] + default fn ne(&self, other: &Arc) -> bool { + **self != **other + } +} + +/// We're doing this specialization here, and not as a more general optimization on `&T`, because it +/// would otherwise add a cost to all equality checks on refs. We assume that `Arc`s are used to +/// store large values, that are slow to clone, but also heavy to check for equality, causing this +/// cost to pay off more easily. It's also more likely to have two `Arc` clones, that point to +/// the same value, than two `&T`s. +/// +/// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive. +#[stable(feature = "rust1", since = "1.0.0")] +impl ArcEqIdent for Arc { + #[inline] + fn eq(&self, other: &Arc) -> bool { + ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) || **self == **other + } + + #[inline] + fn ne(&self, other: &Arc) -> bool { + !ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) && **self != **other + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq for Arc { + /// Equality for two `Arc`s. + /// + /// Two `Arc`s are equal if their inner values are equal, even if they are + /// stored in different allocation. + /// + /// If `T` also implements `Eq` (implying reflexivity of equality), + /// two `Arc`s that point to the same allocation are always equal. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// assert!(five == Arc::new(5)); + /// ``` + #[inline] + fn eq(&self, other: &Arc) -> bool { + ArcEqIdent::eq(self, other) + } + + /// Inequality for two `Arc`s. + /// + /// Two `Arc`s are not equal if their inner values are not equal. + /// + /// If `T` also implements `Eq` (implying reflexivity of equality), + /// two `Arc`s that point to the same value are always equal. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// assert!(five != Arc::new(6)); + /// ``` + #[inline] + fn ne(&self, other: &Arc) -> bool { + ArcEqIdent::ne(self, other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialOrd for Arc { + /// Partial comparison for two `Arc`s. + /// + /// The two are compared by calling `partial_cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use std::cmp::Ordering; + /// + /// let five = Arc::new(5); + /// + /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6))); + /// ``` + fn partial_cmp(&self, other: &Arc) -> Option { + (**self).partial_cmp(&**other) + } + + /// Less-than comparison for two `Arc`s. + /// + /// The two are compared by calling `<` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// assert!(five < Arc::new(6)); + /// ``` + fn lt(&self, other: &Arc) -> bool { + *(*self) < *(*other) + } + + /// 'Less than or equal to' comparison for two `Arc`s. + /// + /// The two are compared by calling `<=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// assert!(five <= Arc::new(5)); + /// ``` + fn le(&self, other: &Arc) -> bool { + *(*self) <= *(*other) + } + + /// Greater-than comparison for two `Arc`s. + /// + /// The two are compared by calling `>` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// assert!(five > Arc::new(4)); + /// ``` + fn gt(&self, other: &Arc) -> bool { + *(*self) > *(*other) + } + + /// 'Greater than or equal to' comparison for two `Arc`s. + /// + /// The two are compared by calling `>=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// assert!(five >= Arc::new(5)); + /// ``` + fn ge(&self, other: &Arc) -> bool { + *(*self) >= *(*other) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl Ord for Arc { + /// Comparison for two `Arc`s. + /// + /// The two are compared by calling `cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use std::cmp::Ordering; + /// + /// let five = Arc::new(5); + /// + /// assert_eq!(Ordering::Less, five.cmp(&Arc::new(6))); + /// ``` + fn cmp(&self, other: &Arc) -> Ordering { + (**self).cmp(&**other) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for Arc {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for Arc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Arc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Pointer for Arc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&(&raw const **self), f) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for Arc { + /// Creates a new `Arc`, with the `Default` value for `T`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x: Arc = Default::default(); + /// assert_eq!(*x, 0); + /// ``` + fn default() -> Arc { + // ignore-tidy-undocumented-unsafe + unsafe { + Self::from_inner(Box::into_non_null(Box::write( + Box::new_uninit(), + ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data: T::default(), + }, + ))) + } + } +} + +/// Struct to hold the static `ArcInner` used for empty `Arc` as +/// returned by `Default::default`. +/// +/// Layout notes: +/// * `repr(align(16))` so we can use it for `[T]` with `align_of::() <= 16`. +/// * `repr(C)` so `inner` is at offset 0 (and thus guaranteed to actually be aligned to 16). +/// * `[u8; 1]` (to be initialized with 0) so it can be used for `Arc`. +#[repr(C, align(16))] +struct SliceArcInnerForStatic { + inner: ArcInner<[u8; 1]>, +} +#[cfg(not(no_global_oom_handling))] +const MAX_STATIC_INNER_SLICE_ALIGNMENT: usize = 16; + +static STATIC_INNER_SLICE: SliceArcInnerForStatic = SliceArcInnerForStatic { + inner: ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data: [0], + }, +}; + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] +impl Default for Arc { + /// Creates an empty str inside an Arc + /// + /// This may or may not share an allocation with other Arcs. + #[inline] + fn default() -> Self { + let arc: Arc<[u8]> = Default::default(); + debug_assert!(core::str::from_utf8(&arc).is_ok()); + let (ptr, alloc) = Arc::into_inner_with_allocator(arc); + // ignore-tidy-undocumented-unsafe + unsafe { Arc::from_ptr_in(ptr.as_ptr() as *mut ArcInner, alloc) } + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] +impl Default for Arc { + /// Creates an empty CStr inside an Arc + /// + /// This may or may not share an allocation with other Arcs. + #[inline] + fn default() -> Self { + use core::ffi::CStr; + let inner: NonNull> = NonNull::from(&STATIC_INNER_SLICE.inner); + let inner: NonNull> = + NonNull::new(inner.as_ptr() as *mut ArcInner).unwrap(); + // `this` semantically is the Arc "owned" by the static, so make sure not to drop it. + let this: mem::ManuallyDrop> = + // ignore-tidy-undocumented-unsafe + unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) }; + (*this).clone() + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] +impl Default for Arc<[T]> { + /// Creates an empty `[T]` inside an Arc + /// + /// This may or may not share an allocation with other Arcs. + #[inline] + fn default() -> Self { + if align_of::() <= MAX_STATIC_INNER_SLICE_ALIGNMENT { + // We take a reference to the whole struct instead of the ArcInner<[u8; 1]> inside it so + // we don't shrink the range of bytes the ptr is allowed to access under Stacked Borrows. + // (Miri complains on 32-bit targets with Arc<[Align16]> otherwise.) + // (Note that NonNull::from(&STATIC_INNER_SLICE.inner) is fine under Tree Borrows.) + let inner: NonNull = NonNull::from(&STATIC_INNER_SLICE); + let inner: NonNull> = inner.cast(); + // `this` semantically is the Arc "owned" by the static, so make sure not to drop it. + let this: mem::ManuallyDrop> = + // ignore-tidy-undocumented-unsafe + unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) }; + return (*this).clone(); + } + + // If T's alignment is too large for the static, make a new unique allocation. + let arr: [T; 0] = []; + Arc::from(arr) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "pin_default_impls", since = "1.91.0")] +impl Default for Pin> +where + T: ?Sized, + Arc: Default, +{ + #[inline] + fn default() -> Self { + // SAFETY: We own and create the pinned pointer. + unsafe { Pin::new_unchecked(Arc::::default()) } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Arc { + fn hash(&self, state: &mut H) { + (**self).hash(state) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "from_for_ptrs", since = "1.6.0")] +impl From for Arc { + /// Converts a `T` into an `Arc` + /// + /// The conversion moves the value into a + /// newly allocated `Arc`. It is equivalent to + /// calling `Arc::new(t)`. + /// + /// # Example + /// ```rust + /// # use std::sync::Arc; + /// let x = 5; + /// let arc = Arc::new(5); + /// + /// assert_eq!(Arc::from(x), arc); + /// ``` + fn from(t: T) -> Self { + Arc::new(t) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_array", since = "1.74.0")] +impl From<[T; N]> for Arc<[T]> { + /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`. + /// + /// The conversion moves the array into a newly allocated `Arc`. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let original: [i32; 3] = [1, 2, 3]; + /// let shared: Arc<[i32]> = Arc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: [T; N]) -> Arc<[T]> { + Arc::<[T; N]>::from(v) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_slice", since = "1.21.0")] +impl From<&[T]> for Arc<[T]> { + /// Allocates a reference-counted slice and fills it by cloning `v`'s items. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let original: &[i32] = &[1, 2, 3]; + /// let shared: Arc<[i32]> = Arc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: &[T]) -> Arc<[T]> { + >::from_slice(v) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] +impl From<&mut [T]> for Arc<[T]> { + /// Allocates a reference-counted slice and fills it by cloning `v`'s items. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let mut original = [1, 2, 3]; + /// let original: &mut [i32] = &mut original; + /// let shared: Arc<[i32]> = Arc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: &mut [T]) -> Arc<[T]> { + Arc::from(&*v) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_slice", since = "1.21.0")] +impl From<&str> for Arc { + /// Allocates a reference-counted `str` and copies `v` into it. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let shared: Arc = Arc::from("eggplant"); + /// assert_eq!("eggplant", &shared[..]); + /// ``` + #[inline] + fn from(v: &str) -> Arc { + let arc = Arc::<[u8]>::from(v.as_bytes()); + // ignore-tidy-undocumented-unsafe + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const str) } + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] +impl From<&mut str> for Arc { + /// Allocates a reference-counted `str` and copies `v` into it. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let mut original = String::from("eggplant"); + /// let original: &mut str = &mut original; + /// let shared: Arc = Arc::from(original); + /// assert_eq!("eggplant", &shared[..]); + /// ``` + #[inline] + fn from(v: &mut str) -> Arc { + Arc::from(&*v) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_slice", since = "1.21.0")] +impl From for Arc { + /// Allocates a reference-counted `str` and copies `v` into it. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let unique: String = "eggplant".to_owned(); + /// let shared: Arc = Arc::from(unique); + /// assert_eq!("eggplant", &shared[..]); + /// ``` + #[inline] + fn from(v: String) -> Arc { + Arc::from(&v[..]) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_slice", since = "1.21.0")] +impl From> for Arc { + /// Move a boxed object to a new, reference-counted allocation. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let unique: Box = Box::from("eggplant"); + /// let shared: Arc = Arc::from(unique); + /// assert_eq!("eggplant", &shared[..]); + /// ``` + #[inline] + fn from(v: Box) -> Arc { + Arc::from_box_in(v) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_slice", since = "1.21.0")] +impl From> for Arc<[T], A> { + /// Allocates a reference-counted slice and moves `v`'s items into it. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let unique: Vec = vec![1, 2, 3]; + /// let shared: Arc<[i32]> = Arc::from(unique); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: Vec) -> Arc<[T], A> { + // ignore-tidy-undocumented-unsafe + unsafe { + let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_allocator(); + + let rc_ptr = Self::allocate_for_slice_in(len, &alloc); + ptr::copy_nonoverlapping(vec_ptr, (&raw mut (*rc_ptr).data) as *mut T, len); + + // Create a `Vec` with length 0, to deallocate the buffer + // without dropping its contents or the allocator + let _ = Vec::from_raw_parts_in(vec_ptr, 0, cap, &alloc); + + Self::from_ptr_in(rc_ptr, alloc) + } + } +} + +#[stable(feature = "shared_from_cow", since = "1.45.0")] +impl<'a, B> From> for Arc +where + B: ToOwned + ?Sized, + Arc: From<&'a B> + From, +{ + /// Creates an atomically reference-counted pointer from a clone-on-write + /// pointer by copying its content. + /// + /// # Example + /// + /// ```rust + /// # use std::sync::Arc; + /// # use std::borrow::Cow; + /// let cow: Cow<'_, str> = Cow::Borrowed("eggplant"); + /// let shared: Arc = Arc::from(cow); + /// assert_eq!("eggplant", &shared[..]); + /// ``` + #[inline] + fn from(cow: Cow<'a, B>) -> Arc { + match cow { + Cow::Borrowed(s) => Arc::from(s), + Cow::Owned(s) => Arc::from(s), + } + } +} + +#[stable(feature = "shared_from_str", since = "1.62.0")] +impl From> for Arc<[u8]> { + /// Converts an atomically reference-counted string slice into a byte slice. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let string: Arc = Arc::from("eggplant"); + /// let bytes: Arc<[u8]> = Arc::from(string); + /// assert_eq!("eggplant".as_bytes(), bytes.as_ref()); + /// ``` + #[inline] + fn from(rc: Arc) -> Self { + // SAFETY: `str` has the same layout as `[u8]`. + unsafe { Arc::from_raw(Arc::into_raw(rc) as *const [u8]) } + } +} + +#[stable(feature = "boxed_slice_try_from", since = "1.43.0")] +impl TryFrom> for Arc<[T; N], A> { + type Error = Arc<[T], A>; + + fn try_from(boxed_slice: Arc<[T], A>) -> Result { + if boxed_slice.len() == N { + let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice); + // ignore-tidy-undocumented-unsafe + Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) }) + } else { + Err(boxed_slice) + } + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_iter", since = "1.37.0")] +impl FromIterator for Arc<[T]> { + /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`. + /// + /// # Performance characteristics + /// + /// ## The general case + /// + /// In the general case, collecting into `Arc<[T]>` is done by first + /// collecting into a `Vec`. That is, when writing the following: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect(); + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// this behaves as if we wrote: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0) + /// .collect::>() // The first set of allocations happens here. + /// .into(); // A second allocation for `Arc<[T]>` happens here. + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// This will allocate as many times as needed for constructing the `Vec` + /// and then it will allocate once for turning the `Vec` into the `Arc<[T]>`. + /// + /// ## Iterators of known length + /// + /// When your `Iterator` implements `TrustedLen` and is of an exact size, + /// a single allocation will be made for the `Arc<[T]>`. For example: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here. + /// # assert_eq!(&*evens, &*(0..10).collect::>()); + /// ``` + fn from_iter>(iter: I) -> Self { + ToArcSlice::to_arc_slice(iter.into_iter()) + } +} + +#[cfg(not(no_global_oom_handling))] +/// Specialization trait used for collecting into `Arc<[T]>`. +trait ToArcSlice: Iterator + Sized { + fn to_arc_slice(self) -> Arc<[T]>; +} + +#[cfg(not(no_global_oom_handling))] +impl> ToArcSlice for I { + default fn to_arc_slice(self) -> Arc<[T]> { + self.collect::>().into() + } +} + +#[cfg(not(no_global_oom_handling))] +impl> ToArcSlice for I { + fn to_arc_slice(self) -> Arc<[T]> { + // This is the case for a `TrustedLen` iterator. + let (low, high) = self.size_hint(); + if let Some(high) = high { + debug_assert_eq!( + low, + high, + "TrustedLen iterator's size hint is not exact: {:?}", + (low, high) + ); + + // SAFETY: We need to ensure that the iterator has an exact length and we have. + unsafe { Arc::from_iter_exact(self, low) } + } else { + // TrustedLen contract guarantees that `upper_bound == None` implies an iterator + // length exceeding `usize::MAX`. + // The default implementation would collect into a vec which would panic. + // Thus we panic here immediately without invoking `Vec` code. + panic!("capacity overflow"); + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl borrow::Borrow for Arc { + fn borrow(&self) -> &T { + self + } +} + +#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] +impl AsRef for Arc { + fn as_ref(&self) -> &T { + self + } +} + +#[stable(feature = "pin", since = "1.33.0")] +impl Unpin for Arc {} + +/// Gets the offset within an `ArcInner` for the payload behind a pointer. +/// +/// # Safety +/// +/// The pointer must point to (and have valid metadata for) a previously +/// valid instance of T, but the T is allowed to be dropped. +unsafe fn data_offset(ptr: *const T) -> usize { + // Align the unsized value to the end of the ArcInner. + // Because ArcInner is repr(C), it will always be the last field in memory. + // SAFETY: since the only unsized types possible are slices, trait objects, + // and extern types, the input safety requirement is currently enough to + // satisfy the requirements of Alignment::of_val_raw; this is an implementation + // detail of the language that must not be relied upon outside of std. + unsafe { data_offset_alignment(Alignment::of_val_raw(ptr)) } +} + +#[inline] +fn data_offset_alignment(alignment: Alignment) -> usize { + let layout = Layout::new::>(); + layout.size() + layout.padding_needed_for(alignment) +} + +/// A unique owning pointer to an [`ArcInner`] **that does not imply the contents are initialized,** +/// but will deallocate it (without dropping the value) when dropped. +/// +/// This is a helper for [`Arc::make_mut()`] to ensure correct cleanup on panic. +struct UniqueArcUninit { + ptr: NonNull>, + layout_for_value: Layout, + alloc: Option, +} + +impl UniqueArcUninit { + /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it. + #[cfg(not(no_global_oom_handling))] + fn new(for_value: &T, alloc: A) -> UniqueArcUninit { + let layout = Layout::for_value(for_value); + // ignore-tidy-undocumented-unsafe + let ptr = unsafe { + Arc::allocate_for_layout( + layout, + |layout_for_arcinner| alloc.allocate(layout_for_arcinner), + |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const ArcInner), + ) + }; + Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) } + } + + /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it, + /// returning an error if allocation fails. + fn try_new(for_value: &T, alloc: A) -> Result, AllocError> { + let layout = Layout::for_value(for_value); + // ignore-tidy-undocumented-unsafe + let ptr = unsafe { + Arc::try_allocate_for_layout( + layout, + |layout_for_arcinner| alloc.allocate(layout_for_arcinner), + |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const ArcInner), + )? + }; + Ok(Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) }) + } + + /// Returns the pointer to be written into to initialize the [`Arc`]. + fn data_ptr(&mut self) -> *mut T { + let offset = data_offset_alignment(self.layout_for_value.alignment()); + // ignore-tidy-undocumented-unsafe + unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } + } + + /// Upgrade this into a normal [`Arc`]. + /// + /// # Safety + /// + /// The data must have been initialized (by writing to [`Self::data_ptr()`]). + unsafe fn into_arc(self) -> Arc { + let mut this = ManuallyDrop::new(self); + let ptr = this.ptr.as_ptr(); + let alloc = this.alloc.take().unwrap(); + + // SAFETY: The pointer is valid as per `UniqueArcUninit::new`, and the caller is responsible + // for having initialized the data. + unsafe { Arc::from_ptr_in(ptr, alloc) } + } +} + +impl Drop for UniqueArcUninit { + fn drop(&mut self) { + // SAFETY: + // * new() produced a pointer safe to deallocate. + // * We own the pointer unless into_arc() was called, which forgets us. + unsafe { + self.alloc.take().unwrap().deallocate( + self.ptr.cast(), + arcinner_layout_for_value_layout(self.layout_for_value), + ); + } + } +} + +#[stable(feature = "arc_error", since = "1.52.0")] +impl core::error::Error for Arc { + #[allow(deprecated)] + fn cause(&self) -> Option<&dyn core::error::Error> { + core::error::Error::cause(&**self) + } + + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { + core::error::Error::source(&**self) + } + + fn provide<'a>(&'a self, req: &mut core::error::Request<'a>) { + core::error::Error::provide(&**self, req); + } +} + +/// A uniquely owned [`Arc`]. +/// +/// This represents an `Arc` that is known to be uniquely owned -- that is, have exactly one strong +/// reference. Multiple weak pointers can be created, but attempts to upgrade those to strong +/// references will fail unless the `UniqueArc` they point to has been converted into a regular `Arc`. +/// +/// Because it is uniquely owned, the contents of a `UniqueArc` can be freely mutated. A common +/// use case is to have an object be mutable during its initialization phase but then have it become +/// immutable and converted to a normal `Arc`. +/// +/// This can be used as a flexible way to create cyclic data structures, as in the example below. +/// +/// ``` +/// #![feature(unique_rc_arc)] +/// use std::sync::{Arc, Weak, UniqueArc}; +/// +/// struct Gadget { +/// me: Weak, +/// } +/// +/// fn create_gadget() -> Option> { +/// let mut rc = UniqueArc::new(Gadget { +/// me: Weak::new(), +/// }); +/// rc.me = UniqueArc::downgrade(&rc); +/// Some(UniqueArc::into_arc(rc)) +/// } +/// +/// create_gadget().unwrap(); +/// ``` +/// +/// An advantage of using `UniqueArc` over [`Arc::new_cyclic`] to build cyclic data structures is that +/// [`Arc::new_cyclic`]'s `data_fn` parameter cannot be async or return a [`Result`]. As shown in the +/// previous example, `UniqueArc` allows for more flexibility in the construction of cyclic data, +/// including fallible or async constructors. +#[unstable(feature = "unique_rc_arc", issue = "112566")] +pub struct UniqueArc< + T: ?Sized, + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: Allocator = Global, +> { + ptr: NonNull>, + // Define the ownership of `ArcInner` for drop-check + _marker: PhantomData>, + // Invariance is necessary for soundness: once other `Weak` + // references exist, we already have a form of shared mutability! + _marker2: PhantomData<*mut T>, + alloc: A, +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +unsafe impl Send for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +unsafe impl Sync for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +// #[unstable(feature = "coerce_unsized", issue = "18598")] +impl, U: ?Sized, A: Allocator> CoerceUnsized> + for UniqueArc +{ +} + +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl, U: ?Sized> DispatchFromDyn> for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl fmt::Display for UniqueArc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl fmt::Debug for UniqueArc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl fmt::Pointer for UniqueArc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&(&raw const **self), f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl borrow::Borrow for UniqueArc { + fn borrow(&self) -> &T { + self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl borrow::BorrowMut for UniqueArc { + fn borrow_mut(&mut self) -> &mut T { + self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsRef for UniqueArc { + fn as_ref(&self) -> &T { + self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsMut for UniqueArc { + fn as_mut(&mut self) -> &mut T { + self + } +} + +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl From for UniqueArc { + #[inline(always)] + fn from(value: T) -> Self { + Self::new(value) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Unpin for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl PartialEq for UniqueArc { + /// Equality for two `UniqueArc`s. + /// + /// Two `UniqueArc`s are equal if their inner values are equal. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// + /// let five = UniqueArc::new(5); + /// + /// assert!(five == UniqueArc::new(5)); + /// ``` + #[inline] + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl PartialOrd for UniqueArc { + /// Partial comparison for two `UniqueArc`s. + /// + /// The two are compared by calling `partial_cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// use std::cmp::Ordering; + /// + /// let five = UniqueArc::new(5); + /// + /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueArc::new(6))); + /// ``` + #[inline(always)] + fn partial_cmp(&self, other: &UniqueArc) -> Option { + (**self).partial_cmp(&**other) + } + + /// Less-than comparison for two `UniqueArc`s. + /// + /// The two are compared by calling `<` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// + /// let five = UniqueArc::new(5); + /// + /// assert!(five < UniqueArc::new(6)); + /// ``` + #[inline(always)] + fn lt(&self, other: &UniqueArc) -> bool { + **self < **other + } + + /// 'Less than or equal to' comparison for two `UniqueArc`s. + /// + /// The two are compared by calling `<=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// + /// let five = UniqueArc::new(5); + /// + /// assert!(five <= UniqueArc::new(5)); + /// ``` + #[inline(always)] + fn le(&self, other: &UniqueArc) -> bool { + **self <= **other + } + + /// Greater-than comparison for two `UniqueArc`s. + /// + /// The two are compared by calling `>` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// + /// let five = UniqueArc::new(5); + /// + /// assert!(five > UniqueArc::new(4)); + /// ``` + #[inline(always)] + fn gt(&self, other: &UniqueArc) -> bool { + **self > **other + } + + /// 'Greater than or equal to' comparison for two `UniqueArc`s. + /// + /// The two are compared by calling `>=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// + /// let five = UniqueArc::new(5); + /// + /// assert!(five >= UniqueArc::new(5)); + /// ``` + #[inline(always)] + fn ge(&self, other: &UniqueArc) -> bool { + **self >= **other + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Ord for UniqueArc { + /// Comparison for two `UniqueArc`s. + /// + /// The two are compared by calling `cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::sync::UniqueArc; + /// use std::cmp::Ordering; + /// + /// let five = UniqueArc::new(5); + /// + /// assert_eq!(Ordering::Less, five.cmp(&UniqueArc::new(6))); + /// ``` + #[inline] + fn cmp(&self, other: &UniqueArc) -> Ordering { + (**self).cmp(&**other) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Eq for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Hash for UniqueArc { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} + +impl UniqueArc { + /// Creates a new `UniqueArc`. + /// + /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading + /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`]. + /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will + /// point to the new [`Arc`]. + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "unique_rc_arc", issue = "112566")] + #[must_use] + pub fn new(value: T) -> Self { + Self::new_in(value, Global) + } + + /// Like [`new`](Self::new), but returns an error if the allocation + /// fails, instead of calling [`handle_alloc_error`]. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + pub fn try_new(value: T) -> Result { + Self::try_new_in(value, Global) + } +} + +impl UniqueArc { + /// Creates a new `UniqueArc` in the provided allocator. + /// + /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading + /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`]. + /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will + /// point to the new [`Arc`]. + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "unique_rc_arc", issue = "112566")] + // #[unstable(feature = "allocator_api", issue = "163177")] + #[must_use] + pub fn new_in(data: T, alloc: A) -> Self { + let (ptr, alloc) = Box::into_non_null_with_allocator(Box::new_in( + ArcInner { + strong: atomic::AtomicUsize::new(0), + // keep one weak reference so if all the weak pointers that are created are dropped + // the UniqueArc still stays valid. + weak: atomic::AtomicUsize::new(1), + data, + }, + alloc, + )); + Self { ptr, _marker: PhantomData, _marker2: PhantomData, alloc } + } + + /// Like [`new_in`](Self::new_in), but returns an error if the allocation + /// fails, instead of calling [`handle_alloc_error`]. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + // #[unstable(feature = "allocator_api", issue = "163177")] + pub fn try_new_in(data: T, alloc: A) -> Result { + let (ptr, alloc) = Box::into_non_null_with_allocator(Box::try_new_in( + ArcInner { + strong: atomic::AtomicUsize::new(0), + // keep one weak reference so if all the weak pointers that are created are dropped + // the UniqueArc still stays valid. + weak: atomic::AtomicUsize::new(1), + data, + }, + alloc, + )?); + Ok(Self { ptr, _marker: PhantomData, _marker2: PhantomData, alloc }) + } + + /// Consumes the `UniqueArc`, returning its wrapped value and allocator. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + // #[unstable(feature = "allocator_api", issue = "163177")] + #[must_use] + pub fn unwrap_with_allocator(this: Self) -> (T, A) { + let inner_ptr = this.ptr; + let (data_ptr, alloc) = Self::into_raw_with_allocator(this); + + // SAFETY: Conceptually moves out of the `UniqueRc`. + // We do not use the data inside ever again. + let val = unsafe { data_ptr.read() }; + + // Drop the strong-weak ref + drop(Weak { ptr: inner_ptr, alloc: &alloc }); + + (val, alloc) + } + + /// Consumes the `UniqueArc`, returning its wrapped value. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + #[must_use] + pub fn unwrap(this: Self) -> T { + Self::unwrap_with_allocator(this).0 + } + + /// Maps the value in a `UniqueArc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `UniqueArc`, and the result is returned, + /// also in a `UniqueArc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `UniqueArc::map(u, f)` instead of `u.map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// + /// use std::sync::UniqueArc; + /// + /// let r = UniqueArc::new(7); + /// let new = UniqueArc::map(r, |i| i + 7); + /// assert_eq!(*new, 14); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "unique_rc_arc", issue = "112566")] + pub fn map(this: Self, f: impl FnOnce(T) -> U) -> UniqueArc { + if size_of::() == size_of::() + && align_of::() == align_of::() + && UniqueArc::weak_count(&this) == 0 + { + // ignore-tidy-undocumented-unsafe + unsafe { + let (ptr, alloc) = UniqueArc::into_raw_with_allocator(this); + let value = ptr.read(); + let allocation = + UniqueArc::from_raw_with_allocator(ptr.cast::>(), alloc); + + UniqueArc::write(allocation, f(value)) + } + } else { + let (val, alloc) = UniqueArc::unwrap_with_allocator(this); + UniqueArc::new_in(f(val), alloc) + } + } + + /// Attempts to map the value in a `UniqueArc`, reusing the allocation if possible. + /// + /// `f` is called on a reference to the value in the `UniqueArc`, and if the operation succeeds, + /// the result is returned, also in a `UniqueArc`. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `UniqueArc::try_map(u, f)` instead of `u.try_map(f)`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// # Examples + /// + /// ``` + /// #![feature(smart_pointer_try_map)] + /// #![feature(unique_rc_arc)] + /// + /// use std::sync::UniqueArc; + /// + /// let b = UniqueArc::new(7); + /// let new = UniqueArc::try_map(b, u32::try_from).unwrap(); + /// assert_eq!(*new, 7); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + pub fn try_map( + this: Self, + f: impl FnOnce(T) -> R, + ) -> >>::TryType + where + R: Try, + R::Residual: Residual>, + { + if size_of::() == size_of::() + && align_of::() == align_of::() + && UniqueArc::weak_count(&this) == 0 + { + // ignore-tidy-undocumented-unsafe + unsafe { + let (ptr, alloc) = UniqueArc::into_raw_with_allocator(this); + let value = ptr.read(); + let allocation = UniqueArc::from_raw_with_allocator( + ptr.cast::>(), + alloc, + ); + + try { UniqueArc::write(allocation, f(value)?) } + } + } else { + let (val, alloc) = UniqueArc::unwrap_with_allocator(this); + try { UniqueArc::new_in(f(val)?, alloc) } + } + } +} + +impl UniqueArc { + #[cfg(not(no_global_oom_handling))] + unsafe fn from_raw_with_allocator(ptr: *const T, alloc: A) -> Self { + // SAFETY: Upheld by caller. + let offset = unsafe { data_offset(ptr) }; + + // Reverse the offset to find the original ArcInner. + // SAFETY: Upheld by caller. + let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut ArcInner }; + + Self { + // SAFETY: Upheld by caller. + ptr: unsafe { NonNull::new_unchecked(rc_ptr) }, + _marker: PhantomData, + _marker2: PhantomData, + alloc, + } + } + + fn into_raw_with_allocator(this: Self) -> (*const T, A) { + let this = ManuallyDrop::new(this); + // SAFETY: The copy of the allocator stored in `this` is forgotten + (Self::as_ptr(&*this), unsafe { ptr::read(&this.alloc) }) + } + + /// Converts the `UniqueArc` into a regular [`Arc`]. + /// + /// This consumes the `UniqueArc` and returns a regular [`Arc`] that contains the `value` that + /// is passed to `into_arc`. + /// + /// Any weak references created before this method is called can now be upgraded to strong + /// references. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + #[must_use] + pub fn into_arc(this: Self) -> Arc { + let this = ManuallyDrop::new(this); + + // Move the allocator out. + // SAFETY: `this.alloc` will not be accessed again, nor dropped because it is in + // a `ManuallyDrop`. + let alloc: A = unsafe { ptr::read(&this.alloc) }; + + // SAFETY: This pointer was allocated at creation time so we know it is valid. + unsafe { + // Convert our weak reference into a strong reference + (*this.ptr.as_ptr()).strong.store(1, Release); + Arc::from_inner_in(this.ptr, alloc) + } + } + + #[cfg(not(no_global_oom_handling))] + fn weak_count(this: &Self) -> usize { + this.inner().weak.load(Acquire) - 1 + } + + #[cfg(not(no_global_oom_handling))] + fn inner(&self) -> &ArcInner { + // SAFETY: while this UniqueArc is alive we're guaranteed that the inner pointer is valid. + unsafe { self.ptr.as_ref() } + } + + fn as_ptr(this: &Self) -> *const T { + let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); + + // SAFETY: This cannot go through Deref::deref or UniqueArc::inner because + // this is required to retain raw/mut provenance such that e.g. `get_mut` can + // write through the pointer after the Rc is recovered through `from_raw`. + unsafe { &raw mut (*ptr).data } + } + + #[inline] + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + let this = mem::ManuallyDrop::new(this); + // SAFETY: Pointer is valid for reads and only read once. + (this.ptr, unsafe { ptr::read(&this.alloc) }) + } + + #[inline] + unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { + Self { ptr, _marker: PhantomData, _marker2: PhantomData, alloc } + } +} + +impl UniqueArc { + /// Creates a new weak reference to the `UniqueArc`. + /// + /// Attempting to upgrade this weak reference will fail before the `UniqueArc` has been converted + /// to a [`Arc`] using [`UniqueArc::into_arc`]. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + #[must_use] + pub fn downgrade(this: &Self) -> Weak { + // Using a relaxed ordering is alright here, as knowledge of the + // original reference prevents other threads from erroneously deleting + // the object or converting the object to a normal `Arc`. + // + // Note that we don't need to test if the weak counter is locked because there + // are no such operations like `Arc::get_mut` or `Arc::make_mut` that will lock + // the weak counter. + // + // SAFETY: This pointer was allocated at creation time so we know it is valid. + let old_size = unsafe { (*this.ptr.as_ptr()).weak.fetch_add(1, Relaxed) }; + + // See comments in Arc::clone() for why we do this (for mem::forget). + if old_size > MAX_REFCOUNT { + abort(); + } + + Weak { ptr: this.ptr, alloc: this.alloc.clone() } + } +} + +impl UniqueArc, A> { + /// Writes the value and converts to `UniqueArc`. + /// + /// This method converts similarly to [`assume_init`](Self::assume_init) but + /// writes `value` into it before conversion, thus guaranteeing safety. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + #[must_use] + pub fn write(mut this: Self, value: T) -> UniqueArc { + // SAFETY: Writing initialises the wrapped value. + unsafe { + this.write(value); + this.assume_init() + } + } + + /// Converts to `UniqueArc`. + /// + /// # Safety + /// + /// As with [`MaybeUninit::assume_init`], + /// it is up to the caller to guarantee that the value + /// really is in an initialized state. + /// Calling this when the content is not yet fully initialized + /// causes immediate undefined behavior. + /// + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init + #[unstable(feature = "unique_rc_arc", issue = "112566")] + #[must_use] + pub unsafe fn assume_init(self) -> UniqueArc { + let (ptr, alloc) = UniqueArc::into_inner_with_allocator(self); + // SAFETY: Upheld by caller. + unsafe { UniqueArc::from_inner_in(ptr.cast(), alloc) } + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Deref for UniqueArc { + type Target = T; + + fn deref(&self) -> &T { + // SAFETY: This pointer was allocated at creation time so we know it is valid. + unsafe { &self.ptr.as_ref().data } + } +} + +// #[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] +unsafe impl PinSafePointer for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl DerefMut for UniqueArc { + fn deref_mut(&mut self) -> &mut T { + // SAFETY: This pointer was allocated at creation time so we know it is valid. We know we + // have unique ownership and therefore it's safe to make a mutable reference because + // `UniqueArc` owns the only strong reference to itself. + // We also need to be careful to only create a mutable reference to the `data` field, + // as a mutable reference to the entire `ArcInner` would assert uniqueness over the + // ref count fields too, invalidating any attempt by `Weak`s to access the ref count. + unsafe { &mut (*self.ptr.as_ptr()).data } + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +// #[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for UniqueArc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueArc { + fn drop(&mut self) { + // See `Arc::drop_slow` which drops an `Arc` with a strong count of 0. + // SAFETY: This pointer was allocated at creation time so we know it is valid. + let _weak = Weak { ptr: self.ptr, alloc: &self.alloc }; + + // ignore-tidy-undocumented-unsafe + unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; + } +} + +#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +unsafe impl Allocator for Arc { + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate(layout) + } + + #[inline] + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate_zeroed(layout) + } + + #[inline] + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).deallocate(ptr, layout) } + } + + #[inline] + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).shrink(ptr, old_layout, new_layout) } + } +} + +#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] +unsafe impl AllocatorClone for Arc {} diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rcs/rc.rs similarity index 100% rename from library/alloc/src/rc.rs rename to library/alloc/src/rcs/rc.rs diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index e412cee62d8f6..afb1848d21a24 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -8,5207 +8,7 @@ //! loads and stores of pointers. This may be detected at compile time using //! `#[cfg(target_has_atomic = "ptr")]`. -use core::any::Any; -use core::cell::CloneFromCell; -#[cfg(not(no_global_oom_handling))] -use core::clone::TrivialClone; -use core::clone::{CloneToUninit, Share, UseCloned}; -use core::cmp::Ordering; -use core::hash::{Hash, Hasher}; -use core::intrinsics::abort; -#[cfg(not(no_global_oom_handling))] -use core::iter; -use core::marker::{PhantomData, Unsize}; -use core::mem::{self, Alignment, ManuallyDrop}; -use core::num::NonZeroUsize; -use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; -#[cfg(not(no_global_oom_handling))] -use core::ops::{Residual, Try}; -use core::panic::{RefUnwindSafe, UnwindSafe}; -use core::pin::{Pin, PinSafePointer}; -use core::ptr::{self, NonNull}; -#[cfg(not(no_global_oom_handling))] -use core::slice::from_raw_parts_mut; -use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; -use core::sync::atomic::{self, Atomic}; -use core::{borrow, fmt, hint}; - -use crate::alloc::{AllocError, Allocator, AllocatorClone, Global, Layout, StaticAllocator}; -#[cfg(not(no_global_oom_handling))] -use crate::alloc::{AllocatorNightly, handle_alloc_error}; -use crate::borrow::{Cow, ToOwned}; -use crate::boxed::Box; -use crate::rc::is_dangling; -#[cfg(not(no_global_oom_handling))] -use crate::string::String; -#[cfg(not(no_global_oom_handling))] -use crate::vec::Vec; - -/// A soft limit on the amount of references that may be made to an `Arc`. -/// -/// Going above this limit will abort your program (although not -/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references. -/// Trying to go above it might call a `panic` (if not actually going above it). -/// -/// This is a global invariant, and also applies when using a compare-exchange loop. -/// -/// See comment in `Arc::clone`. -const MAX_REFCOUNT: usize = (isize::MAX) as usize; - -#[cold] -#[cfg_attr(not(panic = "immediate-abort"), inline(never))] -#[cfg_attr(panic = "immediate-abort", inline)] -#[track_caller] -fn panic_arc_overflow() -> ! { - panic!("Arc counter overflow"); -} - -#[cfg(not(sanitize = "thread"))] -macro_rules! acquire { - ($x:expr) => { - atomic::fence(Acquire) - }; -} - -// ThreadSanitizer does not support memory fences. To avoid false positive -// reports in Arc / Weak implementation use atomic loads for synchronization -// instead. -#[cfg(sanitize = "thread")] -macro_rules! acquire { - ($x:expr) => { - $x.load(Acquire) - }; -} - -/// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically -/// Reference Counted'. -/// -/// The type `Arc` provides shared ownership of a value of type `T`, -/// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces -/// a new `Arc` instance, which points to the same allocation on the heap as the -/// source `Arc`, while increasing a reference count. When the last `Arc` -/// pointer to a given allocation is destroyed, the value stored in that allocation (often -/// referred to as "inner value") is also dropped. -/// -/// Shared references in Rust disallow mutation by default, and `Arc` is no -/// exception: you cannot generally obtain a mutable reference to something -/// inside an `Arc`. If you do need to mutate through an `Arc`, you have several options: -/// -/// 1. Use interior mutability with synchronization primitives like [`Mutex`][mutex], -/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. -/// -/// 2. Use clone-on-write semantics with [`Arc::make_mut`] which provides efficient mutation -/// without requiring interior mutability. This approach clones the data only when -/// needed (when there are multiple references) and can be more efficient when mutations -/// are infrequent. -/// -/// 3. Use [`Arc::get_mut`] when you know your `Arc` is not shared (has a reference count of 1), -/// which provides direct mutable access to the inner value without any cloning. -/// -/// ``` -/// use std::sync::Arc; -/// -/// let mut data = Arc::new(vec![1, 2, 3]); -/// -/// // This will clone the vector only if there are other references to it -/// Arc::make_mut(&mut data).push(4); -/// -/// assert_eq!(*data, vec![1, 2, 3, 4]); -/// ``` -/// -/// **Note**: This type is only available on platforms that support atomic -/// loads and stores of pointers, which includes all platforms that support -/// the `std` crate but not all those which only support [`alloc`](crate). -/// This may be detected at compile time using `#[cfg(target_has_atomic = "ptr")]`. -/// -/// ## Thread Safety -/// -/// Unlike [`Rc`], `Arc` uses atomic operations for its reference -/// counting. This means that it is thread-safe. The disadvantage is that -/// atomic operations are more expensive than ordinary memory accesses. If you -/// are not sharing reference-counted allocations between threads, consider using -/// [`Rc`] for lower overhead. [`Rc`] is a safe default, because the -/// compiler will catch any attempt to send an [`Rc`] between threads. -/// However, a library might choose `Arc` in order to give library consumers -/// more flexibility. -/// -/// `Arc` will implement [`Send`] and [`Sync`] as long as the `T` implements -/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an -/// `Arc` to make it thread-safe? This may be a bit counter-intuitive at -/// first: after all, isn't the point of `Arc` thread safety? The key is -/// this: `Arc` makes it thread safe to have multiple ownership of the same -/// data, but it doesn't add thread safety to its data. Consider -/// Arc<[RefCell\]>. [`RefCell`] isn't [`Sync`], and if `Arc` was always -/// [`Send`], Arc<[RefCell\]> would be as well. But then we'd have a problem: -/// [`RefCell`] is not thread safe; it keeps track of the borrowing count using -/// non-atomic operations. -/// -/// In the end, this means that you may need to pair `Arc` with some sort of -/// [`std::sync`] type, usually [`Mutex`][mutex]. -/// -/// ## Breaking cycles with `Weak` -/// -/// The [`downgrade`][downgrade] method can be used to create a non-owning -/// [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d -/// to an `Arc`, but this will return [`None`] if the value stored in the allocation has -/// already been dropped. In other words, `Weak` pointers do not keep the value -/// inside the allocation alive; however, they *do* keep the allocation -/// (the backing store for the value) alive. -/// -/// A cycle between `Arc` pointers will never be deallocated. For this reason, -/// [`Weak`] is used to break cycles. For example, a tree could have -/// strong `Arc` pointers from parent nodes to children, and [`Weak`] -/// pointers from children back to their parents. -/// -/// # Cloning references -/// -/// Creating a new reference from an existing reference-counted pointer is done using the -/// `Clone` trait implemented for [`Arc`][Arc] and [`Weak`][Weak]. -/// -/// ``` -/// use std::sync::Arc; -/// let foo = Arc::new(vec![1.0, 2.0, 3.0]); -/// // The two syntaxes below are equivalent. -/// let a = foo.clone(); -/// let b = Arc::clone(&foo); -/// // a, b, and foo are all Arcs that point to the same memory location -/// ``` -/// -/// ## `Deref` behavior -/// -/// `Arc` automatically dereferences to `T` (via the [`Deref`] trait), -/// so you can call `T`'s methods on a value of type `Arc`. To avoid name -/// clashes with `T`'s methods, the methods of `Arc` itself are associated -/// functions, called using [fully qualified syntax]: -/// -/// ``` -/// use std::sync::Arc; -/// -/// let my_arc = Arc::new(()); -/// let my_weak = Arc::downgrade(&my_arc); -/// ``` -/// -/// `Arc`'s implementations of traits like `Clone` may also be called using -/// fully qualified syntax. Some people prefer to use fully qualified syntax, -/// while others prefer using method-call syntax. -/// -/// ``` -/// use std::sync::Arc; -/// -/// let arc = Arc::new(()); -/// // Method-call syntax -/// let arc2 = arc.clone(); -/// // Fully qualified syntax -/// let arc3 = Arc::clone(&arc); -/// ``` -/// -/// [`Weak`][Weak] does not auto-dereference to `T`, because the inner value may have -/// already been dropped. -/// -/// [`Rc`]: crate::rc::Rc -/// [clone]: Clone::clone -/// [mutex]: ../../std/sync/struct.Mutex.html -/// [rwlock]: ../../std/sync/struct.RwLock.html -/// [atomic]: core::sync::atomic -/// [downgrade]: Arc::downgrade -/// [upgrade]: Weak::upgrade -/// [RefCell\]: core::cell::RefCell -/// [`RefCell`]: core::cell::RefCell -/// [`std::sync`]: ../../std/sync/index.html -/// [`Arc::clone(&from)`]: Arc::clone -/// [fully qualified syntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name -/// -/// # Examples -/// -/// Sharing some immutable data between threads: -/// -/// ``` -/// use std::sync::Arc; -/// use std::thread; -/// -/// let five = Arc::new(5); -/// -/// for _ in 0..10 { -/// let five = Arc::clone(&five); -/// -/// thread::spawn(move || { -/// println!("{five:?}"); -/// }); -/// } -/// ``` -/// -/// Sharing a mutable [`AtomicUsize`]: -/// -/// [`AtomicUsize`]: core::sync::atomic::AtomicUsize "sync::atomic::AtomicUsize" -/// -/// ``` -/// use std::sync::Arc; -/// use std::sync::atomic::{AtomicUsize, Ordering}; -/// use std::thread; -/// -/// let val = Arc::new(AtomicUsize::new(5)); -/// -/// for _ in 0..10 { -/// let val = Arc::clone(&val); -/// -/// thread::spawn(move || { -/// let v = val.fetch_add(1, Ordering::Relaxed); -/// println!("{v:?}"); -/// }); -/// } -/// ``` -/// -/// See the [`rc` documentation][rc_examples] for more examples of reference -/// counting in general. -/// -/// [rc_examples]: crate::rc#examples -#[doc(search_unbox)] -#[rustc_diagnostic_item = "Arc"] -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_insignificant_dtor] -#[diagnostic::on_move( - message = "the type `{Self}` does not implement `Copy`", - label = "this move could be avoided by cloning the original `{Self}`, which is inexpensive", - note = "consider using `Arc::clone`" -)] -pub struct Arc< - T: ?Sized, - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: Allocator = Global, -> { - ptr: NonNull>, - phantom: PhantomData>, - alloc: A, -} - -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for Arc {} -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for Arc {} - -#[stable(feature = "catch_unwind", since = "1.9.0")] -impl UnwindSafe - for Arc -{ -} - -#[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: ?Sized, A: Allocator> CoerceUnsized> for Arc {} - -#[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: ?Sized> DispatchFromDyn> for Arc {} - -// SAFETY: `Arc::clone` doesn't access any `Cell`s which could contain the `Arc` being cloned. -#[unstable(feature = "cell_get_cloned", issue = "145329")] -unsafe impl CloneFromCell for Arc {} - -impl Arc { - unsafe fn from_inner(ptr: NonNull>) -> Self { - // SAFETY: Upheld by caller. - unsafe { Self::from_inner_in(ptr, Global) } - } - - unsafe fn from_ptr(ptr: *mut ArcInner) -> Self { - // SAFETY: Upheld by caller. - unsafe { Self::from_ptr_in(ptr, Global) } - } -} - -impl Arc { - #[inline] - fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { - let this = mem::ManuallyDrop::new(this); - // SAFETY: Pointer is valid for reads. - (this.ptr, unsafe { ptr::read(&this.alloc) }) - } - - #[inline] - unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { - Self { ptr, phantom: PhantomData, alloc } - } - - #[inline] - unsafe fn from_ptr_in(ptr: *mut ArcInner, alloc: A) -> Self { - // SAFETY: Upheld by caller. - unsafe { Self::from_inner_in(NonNull::new_unchecked(ptr), alloc) } - } -} - -/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the -/// managed allocation. -/// -/// The allocation is accessed by calling [`upgrade`] on the `Weak` -/// pointer, which returns an [Option]<[Arc]\>. -/// -/// Since a `Weak` reference does not count towards ownership, it will not -/// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no -/// guarantees about the value still being present. Thus it may return [`None`] -/// when [`upgrade`]d. Note however that a `Weak` reference *does* prevent the allocation -/// itself (the backing store) from being deallocated. -/// -/// A `Weak` pointer is useful for keeping a temporary reference to the allocation -/// managed by [`Arc`] without preventing its inner value from being dropped. It is also used to -/// prevent circular references between [`Arc`] pointers, since mutual owning references -/// would never allow either [`Arc`] to be dropped. For example, a tree could -/// have strong [`Arc`] pointers from parent nodes to children, and `Weak` -/// pointers from children back to their parents. -/// -/// The typical way to obtain a `Weak` pointer is to call [`Arc::downgrade`]. -/// -/// [`upgrade`]: Weak::upgrade -#[stable(feature = "arc_weak", since = "1.4.0")] -#[rustc_diagnostic_item = "ArcWeak"] -pub struct Weak< - T: ?Sized, - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: Allocator = Global, -> { - // This is a `NonNull` to allow optimizing the size of this type in enums, - // but it is not necessarily a valid pointer. - // `Weak::new` sets this to `usize::MAX` so that it doesn’t need - // to allocate space on the heap. That's not a value a real pointer - // will ever have because ArcInner has alignment at least 2. - ptr: NonNull>, - alloc: A, -} - -#[stable(feature = "arc_weak", since = "1.4.0")] -unsafe impl Send for Weak {} -#[stable(feature = "arc_weak", since = "1.4.0")] -unsafe impl Sync for Weak {} - -#[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: ?Sized, A: Allocator> CoerceUnsized> for Weak {} -#[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: ?Sized> DispatchFromDyn> for Weak {} - -// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned. -#[unstable(feature = "cell_get_cloned", issue = "145329")] -unsafe impl CloneFromCell for Weak {} - -#[stable(feature = "arc_weak", since = "1.4.0")] -impl fmt::Debug for Weak { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "(Weak)") - } -} - -// This is repr(C) to future-proof against possible field-reordering, which -// would interfere with otherwise safe [into|from]_raw() of transmutable -// inner types. -// Unlike RcInner, repr(align(2)) is not strictly required because atomic types -// have the alignment same as its size, but we use it for consistency and clarity. -#[repr(C, align(2))] -struct ArcInner { - strong: Atomic, - - // the value usize::MAX acts as a sentinel for temporarily "locking" the - // weak count, preventing `Arc::downgrade` from racing to create new - // `Weak` references. `Arc::is_unique` (which backs `Arc::get_mut`) - // needs to observe both the strong and weak counts as indicating - // uniqueness in one logical atomic step; since they live in separate - // atomic words, it locks the weak count while reading the strong - // count to keep the two reads consistent. - weak: Atomic, - - data: T, -} - -/// Calculate layout for `ArcInner` using the inner value's layout -fn arcinner_layout_for_value_layout(layout: Layout) -> Layout { - // Calculate layout using the given value layout. - // Previously, layout was calculated on the expression - // `&*(ptr as *const ArcInner)`, but this created a misaligned - // reference (see #54908). - Layout::new::>() - .extend(layout) - .unwrap_or_else(|_| panic!("capacity overflow")) - .0 - .pad_to_align() -} - -unsafe impl Send for ArcInner {} -unsafe impl Sync for ArcInner {} - -impl Arc { - /// Constructs a new `Arc`. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(data: T) -> Arc { - // Start the weak pointer count as 1 which is the weak pointer that's - // held by all the strong pointers (kinda), see std/rc.rs for more info - let x: Box<_> = Box::new(ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data, - }); - // SAFETY: Pointer is valid. - unsafe { Self::from_inner(Box::into_non_null(x)) } - } - - /// Constructs a new `Arc` while giving you a `Weak` to the allocation, - /// to allow you to construct a `T` which holds a weak pointer to itself. - /// - /// Generally, a structure circularly referencing itself, either directly or - /// indirectly, should not hold a strong reference to itself to prevent a memory leak. - /// Using this function, you get access to the weak pointer during the - /// initialization of `T`, before the `Arc` is created, such that you can - /// clone and store it inside the `T`. - /// - /// `new_cyclic` first allocates the managed allocation for the `Arc`, - /// then calls your closure, giving it a `Weak` to this allocation, - /// and only afterwards completes the construction of the `Arc` by placing - /// the `T` returned from your closure into the allocation. - /// - /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic` - /// returns, calling [`upgrade`] on the weak reference inside your closure will - /// fail and result in a `None` value. - /// - /// # Panics - /// - /// If `data_fn` panics, the panic is propagated to the caller, and the - /// temporary [`Weak`] is dropped normally. - /// - /// # Example - /// - /// ``` - /// # #![allow(dead_code)] - /// use std::sync::{Arc, Weak}; - /// - /// struct Gadget { - /// me: Weak, - /// } - /// - /// impl Gadget { - /// /// Constructs a reference counted Gadget. - /// fn new() -> Arc { - /// // `me` is a `Weak` pointing at the new allocation of the - /// // `Arc` we're constructing. - /// Arc::new_cyclic(|me| { - /// // Create the actual struct here. - /// Gadget { me: me.clone() } - /// }) - /// } - /// - /// /// Returns a reference counted pointer to Self. - /// fn me(&self) -> Arc { - /// self.me.upgrade().unwrap() - /// } - /// } - /// ``` - /// [`upgrade`]: Weak::upgrade - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "arc_new_cyclic", since = "1.60.0")] - pub fn new_cyclic(data_fn: F) -> Arc - where - F: FnOnce(&Weak) -> T, - { - Self::new_cyclic_in(data_fn, Global) - } - - /// Constructs a new `Arc` with uninitialized contents. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut five = Arc::::new_uninit(); - /// - /// // Deferred initialization: - /// Arc::get_mut(&mut five).unwrap().write(5); - /// - /// let five = unsafe { five.assume_init() }; - /// - /// assert_eq!(*five, 5) - /// ``` - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "new_uninit", since = "1.82.0")] - #[must_use] - pub fn new_uninit() -> Arc> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::from_ptr(Arc::allocate_for_layout( - Layout::new::(), - |layout| Global.allocate(layout), - <*mut u8>::cast, - )) - } - } - - /// Constructs a new `Arc` with uninitialized contents, with the memory - /// being filled with `0` bytes. - /// - /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage - /// of this method. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let zero = Arc::::new_zeroed(); - /// let zero = unsafe { zero.assume_init() }; - /// - /// assert_eq!(*zero, 0) - /// ``` - /// - /// [zeroed]: mem::MaybeUninit::zeroed - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] - #[must_use] - pub fn new_zeroed() -> Arc> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::from_ptr(Arc::allocate_for_layout( - Layout::new::(), - |layout| Global.allocate_zeroed(layout), - <*mut u8>::cast, - )) - } - } - - /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then - /// `data` will be pinned in memory and unable to be moved. - #[cfg(not(no_global_oom_handling))] - #[stable(feature = "pin", since = "1.33.0")] - #[must_use] - pub fn pin(data: T) -> Pin> { - // SAFETY: We own and create the pinned pointer. - unsafe { Pin::new_unchecked(Arc::new(data)) } - } - - /// Constructs a new `Pin>`, return an error if allocation fails. - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn try_pin(data: T) -> Result>, AllocError> { - // SAFETY: We own and create the pinned pointer. - unsafe { Ok(Pin::new_unchecked(Arc::try_new(data)?)) } - } - - /// Constructs a new `Arc`, returning an error if allocation fails. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// use std::sync::Arc; - /// - /// let five = Arc::try_new(5)?; - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn try_new(data: T) -> Result, AllocError> { - // Start the weak pointer count as 1 which is the weak pointer that's - // held by all the strong pointers (kinda), see std/rc.rs for more info - let x: Box<_> = Box::try_new(ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data, - })?; - // SAFETY: Pointer is valid. - unsafe { Ok(Self::from_inner(Box::into_non_null(x))) } - } - - /// Constructs a new `Arc` with uninitialized contents, returning an error - /// if allocation fails. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// - /// let mut five = Arc::::try_new_uninit()?; - /// - /// // Deferred initialization: - /// Arc::get_mut(&mut five).unwrap().write(5); - /// - /// let five = unsafe { five.assume_init() }; - /// - /// assert_eq!(*five, 5); - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn try_new_uninit() -> Result>, AllocError> { - // ignore-tidy-undocumented-unsafe - unsafe { - Ok(Arc::from_ptr(Arc::try_allocate_for_layout( - Layout::new::(), - |layout| Global.allocate(layout), - <*mut u8>::cast, - )?)) - } - } - - /// Constructs a new `Arc` with uninitialized contents, with the memory - /// being filled with `0` bytes, returning an error if allocation fails. - /// - /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage - /// of this method. - /// - /// # Examples - /// - /// ``` - /// #![feature( allocator_ext)] - /// - /// use std::sync::Arc; - /// - /// let zero = Arc::::try_new_zeroed()?; - /// let zero = unsafe { zero.assume_init() }; - /// - /// assert_eq!(*zero, 0); - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - /// - /// [zeroed]: mem::MaybeUninit::zeroed - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn try_new_zeroed() -> Result>, AllocError> { - // ignore-tidy-undocumented-unsafe - unsafe { - Ok(Arc::from_ptr(Arc::try_allocate_for_layout( - Layout::new::(), - |layout| Global.allocate_zeroed(layout), - <*mut u8>::cast, - )?)) - } - } -} - -impl Arc { - /// Constructs a new `Arc` in the provided allocator. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let five = Arc::new_in(5, System); - /// ``` - #[inline] - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn new_in(data: T, alloc: A) -> Arc { - // Start the weak pointer count as 1 which is the weak pointer that's - // held by all the strong pointers (kinda), see std/rc.rs for more info - let x = Box::new_in( - ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data, - }, - alloc, - ); - let (ptr, alloc) = Box::into_non_null_with_allocator(x); - // SAFETY: Pointer is valid. - unsafe { Self::from_inner_in(ptr, alloc) } - } - - /// Constructs a new `Arc` with uninitialized contents in the provided allocator. - /// - /// # Examples - /// - /// ``` - /// #![feature(get_mut_unchecked)] - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let mut five = Arc::::new_uninit_in(System); - /// - /// let five = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); - /// - /// five.assume_init() - /// }; - /// - /// assert_eq!(*five, 5) - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn new_uninit_in(alloc: A) -> Arc, A> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::from_ptr_in( - Arc::allocate_for_layout( - Layout::new::(), - |layout| alloc.allocate(layout), - <*mut u8>::cast, - ), - alloc, - ) - } - } - - /// Constructs a new `Arc` with uninitialized contents, with the memory - /// being filled with `0` bytes, in the provided allocator. - /// - /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage - /// of this method. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let zero = Arc::::new_zeroed_in(System); - /// let zero = unsafe { zero.assume_init() }; - /// - /// assert_eq!(*zero, 0) - /// ``` - /// - /// [zeroed]: mem::MaybeUninit::zeroed - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn new_zeroed_in(alloc: A) -> Arc, A> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::from_ptr_in( - Arc::allocate_for_layout( - Layout::new::(), - |layout| alloc.allocate_zeroed(layout), - <*mut u8>::cast, - ), - alloc, - ) - } - } - - /// Constructs a new `Arc` in the given allocator while giving you a `Weak` to the allocation, - /// to allow you to construct a `T` which holds a weak pointer to itself. - /// - /// Generally, a structure circularly referencing itself, either directly or - /// indirectly, should not hold a strong reference to itself to prevent a memory leak. - /// Using this function, you get access to the weak pointer during the - /// initialization of `T`, before the `Arc` is created, such that you can - /// clone and store it inside the `T`. - /// - /// `new_cyclic_in` first allocates the managed allocation for the `Arc`, - /// then calls your closure, giving it a `Weak` to this allocation, - /// and only afterwards completes the construction of the `Arc` by placing - /// the `T` returned from your closure into the allocation. - /// - /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic_in` - /// returns, calling [`upgrade`] on the weak reference inside your closure will - /// fail and result in a `None` value. - /// - /// # Panics - /// - /// If `data_fn` panics, the panic is propagated to the caller, and the - /// temporary [`Weak`] is dropped normally. - /// - /// # Example - /// - /// See [`new_cyclic`] - /// - /// [`new_cyclic`]: Arc::new_cyclic - /// [`upgrade`]: Weak::upgrade - #[cfg(not(no_global_oom_handling))] - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn new_cyclic_in(data_fn: F, alloc: A) -> Arc - where - F: FnOnce(&Weak) -> T, - { - // Construct the inner in the "uninitialized" state with a single - // weak reference. - let (uninit_ptr, alloc) = Box::into_non_null_with_allocator(Box::new_in( - ArcInner { - strong: atomic::AtomicUsize::new(0), - weak: atomic::AtomicUsize::new(1), - data: mem::MaybeUninit::::uninit(), - }, - alloc, - )); - let init_ptr: NonNull> = uninit_ptr.cast(); - - let weak = Weak { ptr: init_ptr, alloc }; - - // It's important we don't give up ownership of the weak pointer, or - // else the memory might be freed by the time `data_fn` returns. If - // we really wanted to pass ownership, we could create an additional - // weak pointer for ourselves, but this would result in additional - // updates to the weak reference count which might not be necessary - // otherwise. - let data = data_fn(&weak); - - // Now we can properly initialize the inner value and turn our weak - // reference into a strong reference. - let inner = init_ptr.as_ptr(); - // ignore-tidy-undocumented-unsafe - unsafe { - ptr::write(&raw mut (*inner).data, data); - - // The above write to the data field must be visible to any threads which - // observe a non-zero strong count. Therefore we need at least "Release" ordering - // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`. - // - // "Acquire" ordering is not required. When considering the possible behaviors - // of `data_fn` we only need to look at what it could do with a reference to a - // non-upgradeable `Weak`: - // - It can *clone* the `Weak`, increasing the weak reference count. - // - It can drop those clones, decreasing the weak reference count (but never to zero). - // - // These side effects do not impact us in any way, and no other side effects are - // possible with safe code alone. - let prev_value = (*inner).strong.fetch_add(1, Release); - debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); - - // Strong references should collectively own a shared weak reference, - // so don't run the destructor for our old weak reference. - // Calling into_raw_with_allocator has the double effect of giving us back the allocator, - // and forgetting the weak reference. - let alloc = weak.into_raw_with_allocator().1; - - Arc::from_inner_in(init_ptr, alloc) - } - } - - /// Constructs a new `Pin>` in the provided allocator. If `T` does not implement `Unpin`, - /// then `data` will be pinned in memory and unable to be moved. - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn pin_in(data: T, alloc: A) -> Pin> - where - A: StaticAllocator, - { - // SAFETY: We own and create the pinned pointer. - unsafe { Pin::new_unchecked(Arc::new_in(data, alloc)) } - } - - /// Constructs a new `Pin>` in the provided allocator, return an error if allocation - /// fails. - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn try_pin_in(data: T, alloc: A) -> Result>, AllocError> - where - A: StaticAllocator, - { - // SAFETY: We own and create the pinned pointer. - unsafe { Ok(Pin::new_unchecked(Arc::try_new_in(data, alloc)?)) } - } - - /// Constructs a new `Arc` in the provided allocator, returning an error if allocation fails. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let five = Arc::try_new_in(5, System)?; - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn try_new_in(data: T, alloc: A) -> Result, AllocError> { - // Start the weak pointer count as 1 which is the weak pointer that's - // held by all the strong pointers (kinda), see std/rc.rs for more info - let x = Box::try_new_in( - ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data, - }, - alloc, - )?; - let (ptr, alloc) = Box::into_non_null_with_allocator(x); - // SAFETY: Pointer is valid since we created it. - Ok(unsafe { Self::from_inner_in(ptr, alloc) }) - } - - /// Constructs a new `Arc` with uninitialized contents, in the provided allocator, returning an - /// error if allocation fails. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// #![feature(get_mut_unchecked)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let mut five = Arc::::try_new_uninit_in(System)?; - /// - /// let five = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); - /// - /// five.assume_init() - /// }; - /// - /// assert_eq!(*five, 5); - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> { - // ignore-tidy-undocumented-unsafe - unsafe { - Ok(Arc::from_ptr_in( - Arc::try_allocate_for_layout( - Layout::new::(), - |layout| alloc.allocate(layout), - <*mut u8>::cast, - )?, - alloc, - )) - } - } - - /// Constructs a new `Arc` with uninitialized contents, with the memory - /// being filled with `0` bytes, in the provided allocator, returning an error if allocation - /// fails. - /// - /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage - /// of this method. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let zero = Arc::::try_new_zeroed_in(System)?; - /// let zero = unsafe { zero.assume_init() }; - /// - /// assert_eq!(*zero, 0); - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - /// - /// [zeroed]: mem::MaybeUninit::zeroed - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> { - // ignore-tidy-undocumented-unsafe - unsafe { - Ok(Arc::from_ptr_in( - Arc::try_allocate_for_layout( - Layout::new::(), - |layout| alloc.allocate_zeroed(layout), - <*mut u8>::cast, - )?, - alloc, - )) - } - } - /// Returns the inner value, if the `Arc` has exactly one strong reference. - /// - /// Otherwise, an [`Err`] is returned with the same `Arc` that was - /// passed in. - /// - /// This will succeed even if there are outstanding weak references. - /// - /// It is strongly recommended to use [`Arc::into_inner`] instead if you don't - /// keep the `Arc` in the [`Err`] case. - /// Immediately dropping the [`Err`]-value, as the expression - /// `Arc::try_unwrap(this).ok()` does, can cause the strong count to - /// drop to zero and the inner value of the `Arc` to be dropped. - /// For instance, if two threads execute such an expression in parallel, - /// there is a race condition without the possibility of unsafety: - /// The threads could first both check whether they own the last instance - /// in `Arc::try_unwrap`, determine that they both do not, and then both - /// discard and drop their instance in the call to [`ok`][`Result::ok`]. - /// In this scenario, the value inside the `Arc` is safely destroyed - /// by exactly one of the threads, but neither thread will ever be able - /// to use the value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let x = Arc::new(3); - /// assert_eq!(Arc::try_unwrap(x), Ok(3)); - /// - /// let x = Arc::new(4); - /// let _y = Arc::clone(&x); - /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4); - /// ``` - #[inline] - #[stable(feature = "arc_unique", since = "1.4.0")] - pub fn try_unwrap(this: Self) -> Result { - if this.inner().strong.compare_exchange(1, 0, Relaxed, Relaxed).is_err() { - return Err(this); - } - - acquire!(this.inner().strong); - - let this = ManuallyDrop::new(this); - // SAFETY: Pointer is valid for reads, contains initialised memory, - // and not dropped multiple times (we return it). - let elem: T = unsafe { ptr::read(&this.ptr.as_ref().data) }; - // SAFETY: As above, but we explicitly drop the allocator only once - // upon creating and dropping a weak pointer. - let alloc: A = unsafe { ptr::read(&this.alloc) }; // copy the allocator - - // Make a weak pointer to clean up the implicit strong-weak reference - let _weak = Weak { ptr: this.ptr, alloc }; - - Ok(elem) - } - - /// Returns the inner value, if the `Arc` has exactly one strong reference. - /// - /// Otherwise, [`None`] is returned and the `Arc` is dropped. - /// - /// This will succeed even if there are outstanding weak references. - /// - /// If `Arc::into_inner` is called on every clone of this `Arc`, - /// it is guaranteed that exactly one of the calls returns the inner value. - /// This means in particular that the inner value is not dropped. - /// - /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it - /// is meant for different use-cases. If used as a direct replacement - /// for `Arc::into_inner` anyway, such as with the expression - /// [Arc::try_unwrap]\(this).[ok][Result::ok](), then it does - /// **not** give the same guarantee as described in the previous paragraph. - /// For more information, see the examples below and read the documentation - /// of [`Arc::try_unwrap`]. - /// - /// # Examples - /// - /// Minimal example demonstrating the guarantee that `Arc::into_inner` gives. - /// ``` - /// use std::sync::Arc; - /// - /// let x = Arc::new(3); - /// let y = Arc::clone(&x); - /// - /// // Two threads calling `Arc::into_inner` on both clones of an `Arc`: - /// let x_thread = std::thread::spawn(|| Arc::into_inner(x)); - /// let y_thread = std::thread::spawn(|| Arc::into_inner(y)); - /// - /// let x_inner_value = x_thread.join().unwrap(); - /// let y_inner_value = y_thread.join().unwrap(); - /// - /// // One of the threads is guaranteed to receive the inner value: - /// assert!(matches!( - /// (x_inner_value, y_inner_value), - /// (None, Some(3)) | (Some(3), None) - /// )); - /// // The result could also be `(None, None)` if the threads called - /// // `Arc::try_unwrap(x).ok()` and `Arc::try_unwrap(y).ok()` instead. - /// ``` - /// - /// A more practical example demonstrating the need for `Arc::into_inner`: - /// ``` - /// use std::sync::Arc; - /// - /// // Definition of a simple singly linked list using `Arc`: - /// #[derive(Clone)] - /// struct LinkedList(Option>>); - /// struct Node(T, Option>>); - /// - /// // Dropping a long `LinkedList` relying on the destructor of `Arc` - /// // can cause a stack overflow. To prevent this, we can provide a - /// // manual `Drop` implementation that does the destruction in a loop: - /// impl Drop for LinkedList { - /// fn drop(&mut self) { - /// let mut link = self.0.take(); - /// while let Some(arc_node) = link.take() { - /// if let Some(Node(_value, next)) = Arc::into_inner(arc_node) { - /// link = next; - /// } - /// } - /// } - /// } - /// - /// // Implementation of `new` and `push` omitted - /// impl LinkedList { - /// /* ... */ - /// # fn new() -> Self { - /// # LinkedList(None) - /// # } - /// # fn push(&mut self, x: T) { - /// # self.0 = Some(Arc::new(Node(x, self.0.take()))); - /// # } - /// } - /// - /// // The following code could have still caused a stack overflow - /// // despite the manual `Drop` impl if that `Drop` impl had used - /// // `Arc::try_unwrap(arc).ok()` instead of `Arc::into_inner(arc)`. - /// - /// // Create a long list and clone it - /// let mut x = LinkedList::new(); - /// let size = 100000; - /// # let size = if cfg!(miri) { 100 } else { size }; - /// for i in 0..size { - /// x.push(i); // Adds i to the front of x - /// } - /// let y = x.clone(); - /// - /// // Drop the clones in parallel - /// let x_thread = std::thread::spawn(|| drop(x)); - /// let y_thread = std::thread::spawn(|| drop(y)); - /// x_thread.join().unwrap(); - /// y_thread.join().unwrap(); - /// ``` - #[inline] - #[stable(feature = "arc_into_inner", since = "1.70.0")] - pub fn into_inner(this: Self) -> Option { - // Make sure that the ordinary `Drop` implementation isn’t called as well - let mut this = mem::ManuallyDrop::new(this); - - // Following the implementation of `drop` and `drop_slow` - if this.inner().strong.fetch_sub(1, Release) != 1 { - return None; - } - - acquire!(this.inner().strong); - - // SAFETY: This mirrors the line - // - // unsafe { ptr::drop_in_place(Self::get_mut_unchecked(self)) }; - // - // in `drop_slow`. Instead of dropping the value behind the pointer, - // it is read and eventually returned; `ptr::read` has the same - // safety conditions as `ptr::drop_in_place`. - let inner = unsafe { ptr::read(Self::get_mut_unchecked(&mut this)) }; - // SAFETY: Pointer is valid for reads. - let alloc = unsafe { ptr::read(&this.alloc) }; - - drop(Weak { ptr: this.ptr, alloc }); - - Some(inner) - } - - /// Maps the value in an `Arc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `Arc`, and the result is returned, also in - /// an `Arc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Arc::map(a, f)` instead of `r.map(a)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let r = Arc::new(7); - /// let new = Arc::map(r, |i| i + 7); - /// assert_eq!(*new, 14); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] - pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Arc { - if size_of::() == size_of::() - && align_of::() == align_of::() - && Arc::is_unique(&this) - { - // ignore-tidy-undocumented-unsafe - unsafe { - let (ptr, alloc) = Arc::into_raw_with_allocator(this); - let value = ptr.read(); - let mut allocation = Arc::from_raw_in(ptr.cast::>(), alloc); - - Arc::get_mut_unchecked(&mut allocation).write(f(&value)); - allocation.assume_init() - } - } else { - let output = f(&*this); - let (ptr, alloc) = Arc::into_raw_with_allocator(this); - // ignore-tidy-undocumented-unsafe - unsafe { Arc::decrement_strong_count_in(ptr, &alloc) } - - Arc::new_in(output, alloc) - } - } - - /// Attempts to map the value in an `Arc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `Arc`, and if the operation succeeds, the - /// result is returned, also in an `Arc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Arc::try_map(a, f)` instead of `a.try_map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// - /// use std::sync::Arc; - /// - /// let b = Arc::new(7); - /// let new = Arc::try_map(b, |&i| u32::try_from(i)).unwrap(); - /// assert_eq!(*new, 7); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn try_map( - this: Self, - f: impl FnOnce(&T) -> R, - ) -> >>::TryType - where - R: Try, - R::Residual: Residual>, - { - if size_of::() == size_of::() - && align_of::() == align_of::() - && Arc::is_unique(&this) - { - // ignore-tidy-undocumented-unsafe - unsafe { - let (ptr, alloc) = Arc::into_raw_with_allocator(this); - let value = ptr.read(); - let mut allocation = - Arc::from_raw_in(ptr.cast::>(), alloc); - - Arc::get_mut_unchecked(&mut allocation).write(f(&value)?); - try { allocation.assume_init() } - } - } else { - let output = f(&*this)?; - let (ptr, alloc) = Arc::into_raw_with_allocator(this); - // ignore-tidy-undocumented-unsafe - unsafe { Arc::decrement_strong_count_in(ptr, &alloc) } - - try { Arc::new_in(output, alloc) } - } - } -} - -impl Arc<[T]> { - /// Constructs a new atomically reference-counted slice with uninitialized contents. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut values = Arc::<[u32]>::new_uninit_slice(3); - /// - /// // Deferred initialization: - /// let data = Arc::get_mut(&mut values).unwrap(); - /// data[0].write(1); - /// data[1].write(2); - /// data[2].write(3); - /// - /// let values = unsafe { values.assume_init() }; - /// - /// assert_eq!(*values, [1, 2, 3]) - /// ``` - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "new_uninit", since = "1.82.0")] - #[must_use] - pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit]> { - // ignore-tidy-undocumented-unsafe - unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) } - } - - /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being - /// filled with `0` bytes. - /// - /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and - /// incorrect usage of this method. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let values = Arc::<[u32]>::new_zeroed_slice(3); - /// let values = unsafe { values.assume_init() }; - /// - /// assert_eq!(*values, [0, 0, 0]) - /// ``` - /// - /// [zeroed]: mem::MaybeUninit::zeroed - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] - #[must_use] - pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::from_ptr(Arc::allocate_for_layout( - Layout::array::(len).unwrap(), - |layout| Global.allocate_zeroed(layout), - |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[mem::MaybeUninit]>, - )) - } - } -} - -impl Arc<[T], A> { - /// Constructs a new atomically reference-counted slice with uninitialized contents in the - /// provided allocator. - /// - /// # Examples - /// - /// ``` - /// #![feature(get_mut_unchecked)] - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let mut values = Arc::<[u32], _>::new_uninit_slice_in(3, System); - /// - /// let values = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1); - /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2); - /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3); - /// - /// values.assume_init() - /// }; - /// - /// assert_eq!(*values, [1, 2, 3]) - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn new_uninit_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { - // ignore-tidy-undocumented-unsafe - unsafe { Arc::from_ptr_in(Arc::allocate_for_slice_in(len, &alloc), alloc) } - } - - /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being - /// filled with `0` bytes, in the provided allocator. - /// - /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and - /// incorrect usage of this method. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let values = Arc::<[u32], _>::new_zeroed_slice_in(3, System); - /// let values = unsafe { values.assume_init() }; - /// - /// assert_eq!(*values, [0, 0, 0]) - /// ``` - /// - /// [zeroed]: mem::MaybeUninit::zeroed - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - #[inline] - pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::from_ptr_in( - Arc::allocate_for_layout( - Layout::array::(len).unwrap(), - |layout| alloc.allocate_zeroed(layout), - |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[mem::MaybeUninit]>, - ), - alloc, - ) - } - } - - /// Converts the reference-counted slice into a reference-counted array. - /// - /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. - /// - /// # Errors - /// - /// Returns the original `Arc<[T]>` in the `Err` variant if `self.len()` does not equal `N`. - /// - /// # Examples - /// - /// ``` - /// #![feature(alloc_slice_into_array)] - /// use std::sync::Arc; - /// - /// let arc_slice: Arc<[i32]> = Arc::new([1, 2, 3]); - /// - /// let arc_array: Arc<[i32; 3]> = arc_slice.into_array().unwrap(); - /// ``` - #[unstable(feature = "alloc_slice_into_array", issue = "148082")] - #[inline] - pub fn into_array(self) -> Result, Self> { - if self.len() == N { - let (ptr, alloc) = Self::into_raw_with_allocator(self); - let ptr = ptr as *const [T; N]; - - // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. - let me = unsafe { Arc::from_raw_in(ptr, alloc) }; - Ok(me) - } else { - Err(self) - } - } -} - -impl Arc, A> { - /// Converts to `Arc`. - /// - /// # Safety - /// - /// As with [`MaybeUninit::assume_init`], - /// it is up to the caller to guarantee that the inner value - /// really is in an initialized state. - /// Calling this when the content is not yet fully initialized - /// causes immediate undefined behavior. - /// - /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut five = Arc::::new_uninit(); - /// - /// // Deferred initialization: - /// Arc::get_mut(&mut five).unwrap().write(5); - /// - /// let five = unsafe { five.assume_init() }; - /// - /// assert_eq!(*five, 5) - /// ``` - #[stable(feature = "new_uninit", since = "1.82.0")] - #[must_use = "`self` will be dropped if the result is not used"] - #[inline] - pub unsafe fn assume_init(self) -> Arc { - let (ptr, alloc) = Arc::into_inner_with_allocator(self); - // ignore-tidy-undocumented-unsafe - unsafe { Arc::from_inner_in(ptr.cast(), alloc) } - } -} - -impl Arc { - /// Constructs a new `Arc` with a clone of `value`. - /// - /// # Examples - /// - /// ``` - /// #![feature(clone_from_ref)] - /// use std::sync::Arc; - /// - /// let hello: Arc = Arc::clone_from_ref("hello"); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "clone_from_ref", issue = "149075")] - pub fn clone_from_ref(value: &T) -> Arc { - Arc::clone_from_ref_in(value, Global) - } - - /// Constructs a new `Arc` with a clone of `value`, returning an error if allocation fails - /// - /// # Examples - /// - /// ``` - /// #![feature(clone_from_ref)] - /// use std::sync::Arc; - /// - /// let hello: Arc = Arc::try_clone_from_ref("hello")?; - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - #[unstable(feature = "clone_from_ref", issue = "149075")] - //#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn try_clone_from_ref(value: &T) -> Result, AllocError> { - Arc::try_clone_from_ref_in(value, Global) - } -} - -impl Arc { - /// Constructs a new `Arc` with a clone of `value` in the provided allocator. - /// - /// # Examples - /// - /// ``` - /// #![feature(clone_from_ref)] - /// #![feature(allocator_ext)] - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let hello: Arc = Arc::clone_from_ref_in("hello", System); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "clone_from_ref", issue = "149075")] - //#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn clone_from_ref_in(value: &T, alloc: A) -> Arc { - // `in_progress` drops the allocation if we panic before finishing initializing it. - let mut in_progress: UniqueArcUninit = UniqueArcUninit::new(value, alloc); - - // Initialize with clone of value. - // ignore-tidy-undocumented-unsafe - unsafe { - // Clone. If the clone panics, `in_progress` will be dropped and clean up. - value.clone_to_uninit(in_progress.data_ptr().cast()); - // Cast type of pointer, now that it is initialized. - in_progress.into_arc() - } - } - - /// Constructs a new `Arc` with a clone of `value` in the provided allocator, returning an error if allocation fails - /// - /// # Examples - /// - /// ``` - /// #![feature(clone_from_ref)] - /// #![feature(allocator_ext)] - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let hello: Arc = Arc::try_clone_from_ref_in("hello", System)?; - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - #[unstable(feature = "clone_from_ref", issue = "149075")] - //#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn try_clone_from_ref_in(value: &T, alloc: A) -> Result, AllocError> { - // `in_progress` drops the allocation if we panic before finishing initializing it. - let mut in_progress: UniqueArcUninit = UniqueArcUninit::try_new(value, alloc)?; - - // Initialize with clone of value. - // ignore-tidy-undocumented-unsafe - let initialized_clone = unsafe { - // Clone. If the clone panics, `in_progress` will be dropped and clean up. - value.clone_to_uninit(in_progress.data_ptr().cast()); - // Cast type of pointer, now that it is initialized. - in_progress.into_arc() - }; - - Ok(initialized_clone) - } -} - -impl Arc<[mem::MaybeUninit], A> { - /// Converts to `Arc<[T]>`. - /// - /// # Safety - /// - /// As with [`MaybeUninit::assume_init`], - /// it is up to the caller to guarantee that the inner value - /// really is in an initialized state. - /// Calling this when the content is not yet fully initialized - /// causes immediate undefined behavior. - /// - /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut values = Arc::<[u32]>::new_uninit_slice(3); - /// - /// // Deferred initialization: - /// let data = Arc::get_mut(&mut values).unwrap(); - /// data[0].write(1); - /// data[1].write(2); - /// data[2].write(3); - /// - /// let values = unsafe { values.assume_init() }; - /// - /// assert_eq!(*values, [1, 2, 3]) - /// ``` - #[stable(feature = "new_uninit", since = "1.82.0")] - #[must_use = "`self` will be dropped if the result is not used"] - #[inline] - pub unsafe fn assume_init(self) -> Arc<[T], A> { - let (ptr, alloc) = Arc::into_inner_with_allocator(self); - // SAFETY: Upheld by caller. - unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) } - } -} - -impl Arc { - /// Constructs an `Arc` from a raw pointer. - /// - /// The raw pointer must have been previously returned by a call to - /// [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator]. - /// - /// # Safety - /// - /// * Creating a `Arc` from a pointer other than one returned from - /// [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator] - /// is undefined behavior. - /// * If `U` is sized, it must have the same size and alignment as `T`. This - /// is trivially true if `U` is `T`. - /// * If `U` is unsized, its data pointer must have the same size and - /// alignment as `T`. This is trivially true if `Arc` was constructed - /// through `Arc` and then converted to `Arc` through an [unsized - /// coercion]. - /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size - /// and alignment, this is basically like transmuting references of - /// different types. See [`mem::transmute`][transmute] for more information - /// on what restrictions apply in this case. - /// * The raw pointer must point to a block of memory allocated by the global allocator. - /// * The user of `from_raw` has to make sure a specific value of `T` is only - /// dropped once. - /// - /// This function is unsafe because improper use may lead to memory unsafety, - /// even if the returned `Arc` is never accessed. - /// - /// [into_raw]: Arc::into_raw - /// [into_raw_with_allocator]: Arc::into_raw_with_allocator - /// [transmute]: core::mem::transmute - /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let x = Arc::new("hello".to_owned()); - /// let x_ptr = Arc::into_raw(x); - /// - /// unsafe { - /// // Convert back to an `Arc` to prevent leak. - /// let x = Arc::from_raw(x_ptr); - /// assert_eq!(&*x, "hello"); - /// - /// // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe. - /// } - /// - /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! - /// ``` - /// - /// Convert a slice back into its original array: - /// - /// ``` - /// use std::sync::Arc; - /// - /// let x: Arc<[u32]> = Arc::new([1, 2, 3]); - /// let x_ptr: *const [u32] = Arc::into_raw(x); - /// - /// unsafe { - /// let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>()); - /// assert_eq!(&*x, &[1, 2, 3]); - /// } - /// ``` - #[inline] - #[stable(feature = "rc_raw", since = "1.17.0")] - pub unsafe fn from_raw(ptr: *const T) -> Self { - // SAFETY: Upheld by caller. - unsafe { Arc::from_raw_in(ptr, Global) } - } - - /// Consumes the `Arc`, returning the wrapped pointer. - /// - /// To avoid a memory leak the pointer must be converted back to an `Arc` using - /// [`Arc::from_raw`]. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let x = Arc::new("hello".to_owned()); - /// let x_ptr = Arc::into_raw(x); - /// assert_eq!(unsafe { &*x_ptr }, "hello"); - /// # // Prevent leaks for Miri. - /// # drop(unsafe { Arc::from_raw(x_ptr) }); - /// ``` - #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "rc_raw", since = "1.17.0")] - #[rustc_never_returns_null_ptr] - pub fn into_raw(this: Self) -> *const T { - let this = ManuallyDrop::new(this); - Self::as_ptr(&*this) - } - - /// Increments the strong reference count on the `Arc` associated with the - /// provided pointer by one. - /// - /// # Safety - /// - /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the - /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. - /// The associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by the global allocator. - /// - /// [from_raw_in]: Arc::from_raw_in - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// unsafe { - /// let ptr = Arc::into_raw(five); - /// Arc::increment_strong_count(ptr); - /// - /// // This assertion is deterministic because we haven't shared - /// // the `Arc` between threads. - /// let five = Arc::from_raw(ptr); - /// assert_eq!(2, Arc::strong_count(&five)); - /// # // Prevent leaks for Miri. - /// # Arc::decrement_strong_count(ptr); - /// } - /// ``` - #[inline] - #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] - pub unsafe fn increment_strong_count(ptr: *const T) { - // SAFETY: Upheld by caller. - unsafe { Arc::increment_strong_count_in(ptr, Global) } - } - - /// Decrements the strong reference count on the `Arc` associated with the - /// provided pointer by one. - /// - /// # Safety - /// - /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the - /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. - /// The associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by the global allocator. This method can be used to release the final - /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been - /// released. - /// - /// [from_raw_in]: Arc::from_raw_in - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// unsafe { - /// let ptr = Arc::into_raw(five); - /// Arc::increment_strong_count(ptr); - /// - /// // Those assertions are deterministic because we haven't shared - /// // the `Arc` between threads. - /// let five = Arc::from_raw(ptr); - /// assert_eq!(2, Arc::strong_count(&five)); - /// Arc::decrement_strong_count(ptr); - /// assert_eq!(1, Arc::strong_count(&five)); - /// } - /// ``` - #[inline] - #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] - pub unsafe fn decrement_strong_count(ptr: *const T) { - // SAFETY: Upheld by caller. - unsafe { Arc::decrement_strong_count_in(ptr, Global) } - } - - /// Gets the number of strong (`Arc`) pointers to the allocation behind the given raw - /// pointer. - /// - /// This method does not consume or drop the `Arc` behind this pointer. - /// - /// # Safety - /// - /// The pointer must point to (and have valid metadata for) the value inside a live `Arc` - /// allocation, such as a pointer returned by [`Arc::into_raw`], - /// [`Arc::into_raw_with_allocator`], or [`Arc::as_ptr`]. - /// `T` must have the same alignment as that value. - /// The associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) for the duration of this method. - /// - /// Using this method correctly also requires extra care: another thread can change the - /// strong count at any time, including between calling this method and acting on the - /// result. - /// - /// # Examples - /// - /// ``` - /// #![feature(arc_raw_get_strong)] - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// let _also_five = Arc::clone(&five); - /// let ptr = Arc::into_raw(five); - /// - /// unsafe { - /// // This assertion is deterministic because we haven't shared - /// // the `Arc` between threads. - /// assert_eq!(2, Arc::strong_count_from_raw(ptr)); - /// - /// // Convert back to an `Arc` to avoid leaking memory. - /// let five = Arc::from_raw(ptr); - /// assert_eq!(2, Arc::strong_count(&five)); - /// } - /// ``` - #[inline] - #[must_use] - #[unstable(feature = "arc_raw_get_strong", issue = "157021")] - pub unsafe fn strong_count_from_raw(ptr: *const T) -> usize { - // SAFETY: Upheld by caller. - let offset = unsafe { data_offset(ptr) }; - // Reverse the offset to find the original ArcInner. - // SAFETY: Caller ensures this pointer was to an `Arc` allocation, - // so offsetting must be inbounds. - let arc_ptr = unsafe { ptr.byte_sub(offset) as *mut ArcInner }; - // SAFETY: Per the above, an `ArcInner` is stored here. - unsafe { (*arc_ptr).strong.load(Relaxed) } - } -} - -impl Arc { - /// Returns a reference to the underlying allocator. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `Arc::allocator(&a)` instead of `a.allocator()`. This - /// is so that there is no conflict with a method on the inner type. - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn allocator(this: &Self) -> &A { - &this.alloc - } - - /// Consumes the `Arc`, returning the wrapped pointer and allocator. - /// - /// To avoid a memory leak the pointer must be converted back to an `Arc` using - /// [`Arc::from_raw_in`]. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let x = Arc::new_in("hello".to_owned(), System); - /// let (ptr, alloc) = Arc::into_raw_with_allocator(x); - /// assert_eq!(unsafe { &*ptr }, "hello"); - /// let x = unsafe { Arc::from_raw_in(ptr, alloc) }; - /// assert_eq!(&*x, "hello"); - /// ``` - #[must_use = "losing the pointer will leak memory"] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn into_raw_with_allocator(this: Self) -> (*const T, A) { - let this = mem::ManuallyDrop::new(this); - let ptr = Self::as_ptr(&this); - // SAFETY: `this` is ManuallyDrop so the allocator will not be double-dropped - let alloc = unsafe { ptr::read(&this.alloc) }; - (ptr, alloc) - } - - /// Provides a raw pointer to the data. - /// - /// The counts are not affected in any way and the `Arc` is not consumed. The pointer is valid for - /// as long as there are strong counts in the `Arc`. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let x = Arc::new("hello".to_owned()); - /// let y = Arc::clone(&x); - /// let x_ptr = Arc::as_ptr(&x); - /// assert_eq!(x_ptr, Arc::as_ptr(&y)); - /// assert_eq!(unsafe { &*x_ptr }, "hello"); - /// ``` - #[must_use] - #[stable(feature = "rc_as_ptr", since = "1.45.0")] - #[rustc_never_returns_null_ptr] - pub fn as_ptr(this: &Self) -> *const T { - let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); - - // SAFETY: This cannot go through Deref::deref or ArcInnerPtr::inner because - // this is required to retain raw/mut provenance such that e.g. `get_mut` can - // write through the pointer after the Arc is recovered through `from_raw`. - unsafe { &raw mut (*ptr).data } - } - - /// Constructs an `Arc` from a raw pointer. - /// - /// The raw pointer must have been previously returned by a call to [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator]. - /// - /// # Safety - /// - /// * Creating a `Arc` from a pointer other than one returned from - /// [`Arc::into_raw`][into_raw] or [`Arc::into_raw_with_allocator`][into_raw_with_allocator] - /// is undefined behavior. - /// * If `U` is sized, it must have the same size and alignment as `T`. This - /// is trivially true if `U` is `T`. - /// * If `U` is unsized, its data pointer must have the same size and - /// alignment as `T`. This is trivially true if `Arc` was constructed - /// through `Arc` and then converted to `Arc` through an [unsized - /// coercion]. - /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size - /// and alignment, this is basically like transmuting references of - /// different types. See [`mem::transmute`][transmute] for more information - /// on what restrictions apply in this case. - /// * The raw pointer must point to a block of memory allocated by `alloc` - /// * The user of `from_raw` has to make sure a specific value of `T` is only - /// dropped once. - /// - /// This function is unsafe because improper use may lead to memory unsafety, - /// even if the returned `Arc` is never accessed. - /// - /// [into_raw]: Arc::into_raw - /// [into_raw_with_allocator]: Arc::into_raw_with_allocator - /// [transmute]: core::mem::transmute - /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let x = Arc::new_in("hello".to_owned(), System); - /// let (x_ptr, alloc) = Arc::into_raw_with_allocator(x); - /// - /// unsafe { - /// // Convert back to an `Arc` to prevent leak. - /// let x = Arc::from_raw_in(x_ptr, System); - /// assert_eq!(&*x, "hello"); - /// - /// // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe. - /// } - /// - /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! - /// ``` - /// - /// Convert a slice back into its original array: - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let x: Arc<[u32], _> = Arc::new_in([1, 2, 3], System); - /// let x_ptr: *const [u32] = Arc::into_raw_with_allocator(x).0; - /// - /// unsafe { - /// let x: Arc<[u32; 3], _> = Arc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System); - /// assert_eq!(&*x, &[1, 2, 3]); - /// } - /// ``` - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { - // SAFETY: Upheld by caller. - unsafe { - let offset = data_offset(ptr); - - // Reverse the offset to find the original ArcInner. - let arc_ptr = ptr.byte_sub(offset) as *mut ArcInner; - - Self::from_ptr_in(arc_ptr, alloc) - } - } - - /// Creates a new [`Weak`] pointer to this allocation. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// let weak_five = Arc::downgrade(&five); - /// ``` - #[must_use = "this returns a new `Weak` pointer, \ - without modifying the original `Arc`"] - #[stable(feature = "arc_weak", since = "1.4.0")] - pub fn downgrade(this: &Self) -> Weak - where - A: AllocatorClone, - { - // This Relaxed is OK because we're checking the value in the CAS - // below. - let mut cur = this.inner().weak.load(Relaxed); - - loop { - // check if the weak counter is currently "locked"; if so, spin. - if cur == usize::MAX { - hint::spin_loop(); - cur = this.inner().weak.load(Relaxed); - continue; - } - - // We can't allow the refcount to increase much past `MAX_REFCOUNT`. - if cur > MAX_REFCOUNT { - panic_arc_overflow(); - } - // NOTE: this code currently ignores the possibility of overflow - // into usize::MAX; in general both Rc and Arc need to be adjusted - // to deal with overflow. - - // Unlike with Clone(), we need this to be an Acquire read to - // synchronize with the write coming from `is_unique`, so that the - // events prior to that write happen before this read. - match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) { - Ok(_) => { - // Make sure we do not create a dangling Weak - debug_assert!(!is_dangling(this.ptr.as_ptr())); - return Weak { ptr: this.ptr, alloc: this.alloc.clone() }; - } - Err(old) => cur = old, - } - } - } - - /// Gets the number of [`Weak`] pointers to this allocation. - /// - /// # Safety - /// - /// This method by itself is safe, but using it correctly requires extra care. - /// Another thread can change the weak count at any time, - /// including potentially between calling this method and acting on the result. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// let _weak_five = Arc::downgrade(&five); - /// - /// // This assertion is deterministic because we haven't shared - /// // the `Arc` or `Weak` between threads. - /// assert_eq!(1, Arc::weak_count(&five)); - /// ``` - #[inline] - #[must_use] - #[stable(feature = "arc_counts", since = "1.15.0")] - pub fn weak_count(this: &Self) -> usize { - let cnt = this.inner().weak.load(Relaxed); - // If the weak count is currently locked, the value of the - // count was 0 just before taking the lock. - if cnt == usize::MAX { 0 } else { cnt - 1 } - } - - /// Gets the number of strong (`Arc`) pointers to this allocation. - /// - /// # Safety - /// - /// This method by itself is safe, but using it correctly requires extra care. - /// Another thread can change the strong count at any time, - /// including potentially between calling this method and acting on the result. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// let _also_five = Arc::clone(&five); - /// - /// // This assertion is deterministic because we haven't shared - /// // the `Arc` between threads. - /// assert_eq!(2, Arc::strong_count(&five)); - /// ``` - #[inline] - #[must_use] - #[stable(feature = "arc_counts", since = "1.15.0")] - pub fn strong_count(this: &Self) -> usize { - this.inner().strong.load(Relaxed) - } - - /// Increments the strong reference count on the `Arc` associated with the - /// provided pointer by one. - /// - /// # Safety - /// - /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the - /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. - /// The associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by `alloc`. - /// - /// [from_raw_in]: Arc::from_raw_in - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let five = Arc::new_in(5, System); - /// - /// unsafe { - /// let (ptr, _alloc) = Arc::into_raw_with_allocator(five); - /// Arc::increment_strong_count_in(ptr, System); - /// - /// // This assertion is deterministic because we haven't shared - /// // the `Arc` between threads. - /// let five = Arc::from_raw_in(ptr, System); - /// assert_eq!(2, Arc::strong_count(&five)); - /// # // Prevent leaks for Miri. - /// # Arc::decrement_strong_count_in(ptr, System); - /// } - /// ``` - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub unsafe fn increment_strong_count_in(ptr: *const T, alloc: A) - where - A: AllocatorClone, - { - // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop - // SAFETY: Upheld by caller. - let arc = unsafe { mem::ManuallyDrop::new(Arc::from_raw_in(ptr, alloc)) }; - // Now increase refcount, but don't drop new refcount either - let _arc_clone: mem::ManuallyDrop<_> = arc.clone(); - } - - /// Decrements the strong reference count on the `Arc` associated with the - /// provided pointer by one. - /// - /// # Safety - /// - /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the - /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. - /// The associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by `alloc`. This method can be used to release the final - /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been - /// released. - /// - /// [from_raw_in]: Arc::from_raw_in - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Arc; - /// use std::alloc::System; - /// - /// let five = Arc::new_in(5, System); - /// - /// unsafe { - /// let (ptr, _alloc) = Arc::into_raw_with_allocator(five); - /// Arc::increment_strong_count_in(ptr, System); - /// - /// // Those assertions are deterministic because we haven't shared - /// // the `Arc` between threads. - /// let five = Arc::from_raw_in(ptr, System); - /// assert_eq!(2, Arc::strong_count(&five)); - /// Arc::decrement_strong_count_in(ptr, System); - /// assert_eq!(1, Arc::strong_count(&five)); - /// } - /// ``` - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A) { - // SAFETY: Upheld by caller. - unsafe { drop(Arc::from_raw_in(ptr, alloc)) }; - } - - #[inline] - fn inner(&self) -> &ArcInner { - // SAFETY: While this arc is alive we're guaranteed - // that the inner pointer is valid. Furthermore, we know that the - // `ArcInner` structure itself is `Sync` if the inner data is - // `Sync` as well, so we're ok loaning out an immutable pointer to these - // contents. - unsafe { self.ptr.as_ref() } - } - - // Non-inlined part of `drop`. - #[inline(never)] - unsafe fn drop_slow(&mut self) { - // Drop the weak ref collectively held by all strong references when this - // variable goes out of scope. This ensures that the memory is deallocated - // even if the destructor of `T` panics. - // Take a reference to `self.alloc` instead of cloning because 1. it'll last long - // enough, and 2. you should be able to drop `Arc`s with unclonable allocators - let _weak = Weak { ptr: self.ptr, alloc: &self.alloc }; - - // Destroy the data at this time, even though we must not free the box - // allocation itself (there might still be weak pointers lying around). - // We cannot use `get_mut_unchecked` here, because `self.alloc` is borrowed. - // ignore-tidy-undocumented-unsafe - unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; - } - - /// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to - /// [`ptr::eq`]. This function ignores the metadata of `dyn Trait` pointers. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// let same_five = Arc::clone(&five); - /// let other_five = Arc::new(5); - /// - /// assert!(Arc::ptr_eq(&five, &same_five)); - /// assert!(!Arc::ptr_eq(&five, &other_five)); - /// ``` - /// - /// [`ptr::eq`]: core::ptr::eq "ptr::eq" - #[inline] - #[must_use] - #[stable(feature = "ptr_eq", since = "1.17.0")] - pub fn ptr_eq(this: &Self, other: &Self) -> bool { - ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr()) - } -} - -impl Arc { - /// Allocates an `ArcInner` with sufficient space for - /// a possibly-unsized inner value where the value has the layout provided. - /// - /// The function `mem_to_arcinner` is called with the data pointer - /// and must return back a (potentially fat)-pointer for the `ArcInner`. - #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_layout( - value_layout: Layout, - allocate: impl FnOnce(Layout) -> Result, AllocError>, - mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, - ) -> *mut ArcInner { - let layout = arcinner_layout_for_value_layout(value_layout); - - let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout)); - - // ignore-tidy-undocumented-unsafe - unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) } - } - - /// Allocates an `ArcInner` with sufficient space for - /// a possibly-unsized inner value where the value has the layout provided, - /// returning an error if allocation fails. - /// - /// The function `mem_to_arcinner` is called with the data pointer - /// and must return back a (potentially fat)-pointer for the `ArcInner`. - unsafe fn try_allocate_for_layout( - value_layout: Layout, - allocate: impl FnOnce(Layout) -> Result, AllocError>, - mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, - ) -> Result<*mut ArcInner, AllocError> { - let layout = arcinner_layout_for_value_layout(value_layout); - - let ptr = allocate(layout)?; - - // ignore-tidy-undocumented-unsafe - let inner = unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) }; - - Ok(inner) - } - - unsafe fn initialize_arcinner( - ptr: NonNull<[u8]>, - layout: Layout, - mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, - ) -> *mut ArcInner { - let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr()); - // SAFETY: Upheld by caller. - debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); - - // ignore-tidy-undocumented-unsafe - unsafe { - (&raw mut (*inner).strong).write(atomic::AtomicUsize::new(1)); - (&raw mut (*inner).weak).write(atomic::AtomicUsize::new(1)); - } - - inner - } -} - -impl Arc { - /// Allocates an `ArcInner` with sufficient space for an unsized inner value. - #[inline] - #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_ptr_in(ptr: *const T, alloc: &A) -> *mut ArcInner { - // Allocate for the `ArcInner` using the given value. - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::allocate_for_layout( - Layout::for_value_raw(ptr), - |layout| alloc.allocate(layout), - |mem| mem.with_metadata_of(ptr as *const ArcInner), - ) - } - } - - #[cfg(not(no_global_oom_handling))] - fn from_box_in(src: Box) -> Arc { - // ignore-tidy-undocumented-unsafe - unsafe { - let value_size = size_of_val(&*src); - let ptr = Self::allocate_for_ptr_in(&*src, Box::allocator(&src)); - - // Copy value as bytes - ptr::copy_nonoverlapping( - (&raw const *src) as *const u8, - (&raw mut (*ptr).data) as *mut u8, - value_size, - ); - - // Free the allocation without dropping its contents - let (bptr, alloc) = Box::into_raw_with_allocator(src); - let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop, &alloc); - drop(src); - - Self::from_ptr_in(ptr, alloc) - } - } -} - -impl Arc<[T]> { - /// Allocates an `ArcInner<[T]>` with the given length. - #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { - // ignore-tidy-undocumented-unsafe - unsafe { - Self::allocate_for_layout( - Layout::array::(len).unwrap(), - |layout| Global.allocate(layout), - |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[T]>, - ) - } - } - - /// Copy elements from slice into newly allocated `Arc<[T]>` - /// - /// Unsafe because the caller must either take ownership, bind `T: Copy` or - /// bind `T: TrivialClone`. - #[cfg(not(no_global_oom_handling))] - unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { - // ignore-tidy-undocumented-unsafe - unsafe { - let ptr = Self::allocate_for_slice(v.len()); - - ptr::copy_nonoverlapping(v.as_ptr(), (&raw mut (*ptr).data) as *mut T, v.len()); - - Self::from_ptr(ptr) - } - } - - /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size. - /// - /// Behavior is undefined should the size be wrong. - #[cfg(not(no_global_oom_handling))] - unsafe fn from_iter_exact(iter: impl Iterator, len: usize) -> Arc<[T]> { - // Panic guard while cloning T elements. - // In the event of a panic, elements that have been written - // into the new ArcInner will be dropped, then the memory freed. - struct Guard { - mem: NonNull, - elems: *mut T, - layout: Layout, - n_elems: usize, - } - - impl Drop for Guard { - fn drop(&mut self) { - // ignore-tidy-undocumented-unsafe - unsafe { - let slice = from_raw_parts_mut(self.elems, self.n_elems); - ptr::drop_in_place(slice); - - Global.deallocate(self.mem, self.layout); - } - } - } - - // ignore-tidy-undocumented-unsafe - unsafe { - let ptr = Self::allocate_for_slice(len); - - let mem = ptr as *mut _ as *mut u8; - let layout = Layout::for_value_raw(ptr); - - // Pointer to first element - let elems = (&raw mut (*ptr).data) as *mut T; - - let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; - - for (i, item) in iter.enumerate() { - ptr::write(elems.add(i), item); - guard.n_elems += 1; - } - - // All clear. Forget the guard so it doesn't free the new ArcInner. - mem::forget(guard); - - Self::from_ptr(ptr) - } - } -} - -impl Arc<[T], A> { - /// Allocates an `ArcInner<[T]>` with the given length. - #[inline] - #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut ArcInner<[T]> { - // ignore-tidy-undocumented-unsafe - unsafe { - Arc::allocate_for_layout( - Layout::array::(len).unwrap(), - |layout| alloc.allocate(layout), - |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[T]>, - ) - } - } -} - -/// Specialization trait used for `From<&[T]>`. -#[cfg(not(no_global_oom_handling))] -trait ArcFromSlice { - fn from_slice(slice: &[T]) -> Self; -} - -#[cfg(not(no_global_oom_handling))] -impl ArcFromSlice for Arc<[T]> { - #[inline] - default fn from_slice(v: &[T]) -> Self { - // ignore-tidy-undocumented-unsafe - unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) } - } -} - -#[cfg(not(no_global_oom_handling))] -impl ArcFromSlice for Arc<[T]> { - #[inline] - fn from_slice(v: &[T]) -> Self { - // SAFETY: `T` implements `TrivialClone`, so this is sound and equivalent - // to the above. - unsafe { Arc::copy_from_slice(v) } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Arc { - /// Makes a clone of the `Arc` pointer. - /// - /// This creates another pointer to the same allocation, increasing the - /// strong reference count. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// let _ = Arc::clone(&five); - /// ``` - #[inline] - fn clone(&self) -> Arc { - // Using a relaxed ordering is alright here, as knowledge of the - // original reference prevents other threads from erroneously deleting - // the object. - // - // As explained in the [Boost documentation][1], Increasing the - // reference counter can always be done with memory_order_relaxed: New - // references to an object can only be formed from an existing - // reference, and passing an existing reference from one thread to - // another must already provide any required synchronization. - // - // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) - let old_size = self.inner().strong.fetch_add(1, Relaxed); - - // However we need to guard against massive refcounts in case someone is `mem::forget`ing - // Arcs. If we don't do this the count can overflow and users will use-after free. This - // branch will never be taken in any realistic program. We abort because such a program is - // incredibly degenerate, and we don't care to support it. - // - // This check is not 100% water-proof: we error when the refcount grows beyond `isize::MAX`. - // But we do that check *after* having done the increment, so there is a chance here that - // the worst already happened and we actually do overflow the `usize` counter. However, that - // requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment - // above and the `abort` below, which seems exceedingly unlikely. - // - // This is a global invariant, and also applies when using a compare-exchange loop to increment - // counters in other methods. - // Otherwise, the counter could be brought to an almost-overflow using a compare-exchange loop, - // and then overflow using a few `fetch_add`s. - if old_size > MAX_REFCOUNT { - abort(); - } - - // SAFETY: Pointer is valid & allocator corresponds to the one used to allocate it. - unsafe { Self::from_inner_in(self.ptr, self.alloc.clone()) } - } -} - -#[unstable(feature = "ergonomic_clones", issue = "132290")] -impl UseCloned for Arc {} - -#[unstable(feature = "share_trait", issue = "156756")] -impl Share for Arc {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Deref for Arc { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - &self.inner().data - } -} - -// The API of this pointer type enforces that if the `T` is pinned, then *all* -// clones of this `Arc` are wrapped as `Pin>`. Since an `&Arc` -// could be used to obtain an `Arc` that is not wrapped in `Pin` (and later -// used with `Arc::get_mut`), this means that this type treats `&Arc` as -// evidence that the `T` is not pinned. The implementations of various traits -// are written accordingly. Since this type is not fundamental, downstream -// crates cannot provide malicious implementations of any of the traits relevant -// for `Pin`. -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl PinSafePointer for Arc {} - -#[unstable(feature = "deref_pure_trait", issue = "87121")] -unsafe impl DerefPure for Arc {} - -#[unstable(feature = "legacy_receiver_trait", issue = "none")] -impl LegacyReceiver for Arc {} - -#[cfg(not(no_global_oom_handling))] -impl Arc { - /// Makes a mutable reference into the given `Arc`. - /// - /// If there are other `Arc` pointers to the same allocation, then `make_mut` will - /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also - /// referred to as clone-on-write. - /// - /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`] - /// pointers, then the [`Weak`] pointers will be dissociated and the inner value will not - /// be cloned. - /// - /// See also [`get_mut`], which will fail rather than cloning the inner value - /// or dissociating [`Weak`] pointers. - /// - /// [`clone`]: Clone::clone - /// [`get_mut`]: Arc::get_mut - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut data = Arc::new(5); - /// - /// *Arc::make_mut(&mut data) += 1; // Won't clone anything - /// let mut other_data = Arc::clone(&data); // Won't clone inner data - /// *Arc::make_mut(&mut data) += 1; // Clones inner data - /// *Arc::make_mut(&mut data) += 1; // Won't clone anything - /// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything - /// - /// // Now `data` and `other_data` point to different allocations. - /// assert_eq!(*data, 8); - /// assert_eq!(*other_data, 12); - /// ``` - /// - /// [`Weak`] pointers will be dissociated: - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut data = Arc::new(75); - /// let weak = Arc::downgrade(&data); - /// - /// assert!(75 == *data); - /// assert!(75 == *weak.upgrade().unwrap()); - /// - /// *Arc::make_mut(&mut data) += 1; - /// - /// assert!(76 == *data); - /// assert!(weak.upgrade().is_none()); - /// ``` - #[inline] - #[stable(feature = "arc_unique", since = "1.4.0")] - pub fn make_mut(this: &mut Self) -> &mut T { - let size_of_val = size_of_val::(&**this); - - // Note that we hold both a strong reference and a weak reference. - // Thus, releasing our strong reference only will not, by itself, cause - // the memory to be deallocated. - // - // Use Acquire to ensure that we see any writes to `weak` that happen - // before release writes (i.e., decrements) to `strong`. Since we hold a - // weak count, there's no chance the ArcInner itself could be - // deallocated. - if this.inner().strong.compare_exchange(1, 0, Acquire, Relaxed).is_err() { - // Another strong pointer exists, so we must clone. - *this = Arc::clone_from_ref_in(&**this, this.alloc.clone()); - } else if this.inner().weak.load(Relaxed) != 1 { - // Relaxed suffices in the above because this is fundamentally an - // optimization: we are always racing with weak pointers being - // dropped. Worst case, we end up allocated a new Arc unnecessarily. - - // We removed the last strong ref, but there are additional weak - // refs remaining. We'll move the contents to a new Arc, and - // invalidate the other weak refs. - - // Note that it is not possible for the read of `weak` to yield - // usize::MAX (i.e., locked), since the weak count can only be - // locked by a thread with a strong reference. - - // Guard against panics while using the allocator. - // If we unwind before the Arc is overwritten, we expose a strong - // count of 0, resulting in a UAF (#155746, #157203). - // Until the new Arc is written, the old Arc must remain valid - struct Guard<'a, T: ?Sized> { - inner: &'a ArcInner, - } - impl<'a, T: ?Sized> Drop for Guard<'a, T> { - fn drop(&mut self) { - self.inner.strong.store(1, Release); - } - } - let guard = Guard { inner: this.inner() }; - - // Can just steal the data, all that's left is Weaks - // Note that this can panic in two ways: - // - The allocation can fail - // - The allocator clone can fail - let mut in_progress: UniqueArcUninit = - UniqueArcUninit::new(&**this, this.alloc.clone()); - - // ignore-tidy-undocumented-unsafe - unsafe { - // Initialize `in_progress` with move of **this. - // We have to express this in terms of bytes because `T: ?Sized`; there is no - // operation that just copies a value based on its `size_of_val()`. - ptr::copy_nonoverlapping( - ptr::from_ref(&**this).cast::(), - in_progress.data_ptr().cast::(), - size_of_val, - ); - - // We are now safe from panics. - mem::forget(guard); - - // Materialize our own implicit weak pointer, so that it can clean - // up the ArcInner as needed. - // Make sure the allocator is not leaked when the Arc is overwritten. - // Only drop at the end of the scope to avoid panics. - let _weak = Weak { ptr: this.ptr, alloc: ptr::read(&this.alloc) }; - - ptr::write(this, in_progress.into_arc()); - } - } else { - // We were the sole reference of either kind; bump back up the - // strong ref count. - this.inner().strong.store(1, Release); - } - - // SAFETY: As with `get_mut()`, our reference was - // either unique to begin with, or became one upon cloning the contents. - unsafe { Self::get_mut_unchecked(this) } - } -} - -impl Arc { - /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the - /// clone. - /// - /// Assuming `arc_t` is of type `Arc`, this function is functionally equivalent to - /// `(*arc_t).clone()`, but will avoid cloning the inner value where possible. - /// - /// # Examples - /// - /// ``` - /// # use std::{ptr, sync::Arc}; - /// let inner = String::from("test"); - /// let ptr = inner.as_ptr(); - /// - /// let arc = Arc::new(inner); - /// let inner = Arc::unwrap_or_clone(arc); - /// // The inner value was not cloned - /// assert!(ptr::eq(ptr, inner.as_ptr())); - /// - /// let arc = Arc::new(inner); - /// let arc2 = arc.clone(); - /// let inner = Arc::unwrap_or_clone(arc); - /// // Because there were 2 references, we had to clone the inner value. - /// assert!(!ptr::eq(ptr, inner.as_ptr())); - /// // `arc2` is the last reference, so when we unwrap it we get back - /// // the original `String`. - /// let inner = Arc::unwrap_or_clone(arc2); - /// assert!(ptr::eq(ptr, inner.as_ptr())); - /// ``` - #[inline] - #[stable(feature = "arc_unwrap_or_clone", since = "1.76.0")] - pub fn unwrap_or_clone(this: Self) -> T { - Arc::try_unwrap(this).unwrap_or_else(|arc| (*arc).clone()) - } -} - -impl Arc { - /// Returns a mutable reference into the given `Arc`, if there are - /// no other `Arc` or [`Weak`] pointers to the same allocation. - /// - /// Returns [`None`] otherwise, because it is not safe to - /// mutate a shared value. - /// - /// See also [`make_mut`][make_mut], which will [`clone`][clone] - /// the inner value when there are other `Arc` pointers. - /// - /// [make_mut]: Arc::make_mut - /// [clone]: Clone::clone - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let mut x = Arc::new(3); - /// *Arc::get_mut(&mut x).unwrap() = 4; - /// assert_eq!(*x, 4); - /// - /// let _y = Arc::clone(&x); - /// assert!(Arc::get_mut(&mut x).is_none()); - /// ``` - #[inline] - #[stable(feature = "arc_unique", since = "1.4.0")] - pub fn get_mut(this: &mut Self) -> Option<&mut T> { - if Self::is_unique(this) { - // SAFETY: We're guaranteed that the pointer - // returned is the *only* pointer that will ever be returned to T. Our - // reference count is guaranteed to be 1 at this point, and we required - // the Arc itself to be `mut`, so we're returning the only possible - // reference to the inner data. - unsafe { Some(Arc::get_mut_unchecked(this)) } - } else { - None - } - } - - /// Returns a mutable reference into the given `Arc`, - /// without any check. - /// - /// See also [`get_mut`], which is safe and does appropriate checks. - /// - /// [`get_mut`]: Arc::get_mut - /// - /// # Safety - /// - /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then - /// they must not be dereferenced or have active borrows for the duration - /// of the returned borrow, and their inner type must be exactly the same as the - /// inner type of this Arc (including lifetimes). This is trivially the case if no - /// such pointers exist, for example immediately after `Arc::new`. - /// - /// # Examples - /// - /// ``` - /// #![feature(get_mut_unchecked)] - /// - /// use std::sync::Arc; - /// - /// let mut x = Arc::new(String::new()); - /// unsafe { - /// Arc::get_mut_unchecked(&mut x).push_str("foo") - /// } - /// assert_eq!(*x, "foo"); - /// ``` - /// Other `Arc` pointers to the same allocation must be to the same type. - /// ```no_run - /// #![feature(get_mut_unchecked)] - /// - /// use std::sync::Arc; - /// - /// let x: Arc = Arc::from("Hello, world!"); - /// let mut y: Arc<[u8]> = x.clone().into(); - /// unsafe { - /// // this is Undefined Behavior, because x's inner type is str, not [u8] - /// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8 - /// } - /// println!("{}", &*x); // Invalid UTF-8 in a str - /// ``` - /// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes. - /// ```no_run - /// #![feature(get_mut_unchecked)] - /// - /// use std::sync::Arc; - /// - /// let x: Arc<&str> = Arc::new("Hello, world!"); - /// { - /// let s = String::from("Oh, no!"); - /// let mut y: Arc<&str> = x.clone(); - /// unsafe { - /// // this is Undefined Behavior, because x's inner type - /// // is &'long str, not &'short str - /// *Arc::get_mut_unchecked(&mut y) = &s; - /// } - /// } - /// println!("{}", &*x); // Use-after-free - /// ``` - #[inline] - #[unstable(feature = "get_mut_unchecked", issue = "63292")] - pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T { - // We are careful to *not* create a reference covering the "count" fields, as - // this would alias with concurrent access to the reference counts (e.g. by `Weak`). - // ignore-tidy-undocumented-unsafe - unsafe { &mut (*this.ptr.as_ptr()).data } - } - - /// Determine whether this is the unique reference to the underlying data. - /// - /// Returns `true` if there are no other `Arc` or [`Weak`] pointers to the same allocation; - /// returns `false` otherwise. - /// - /// If this function returns `true`, then is guaranteed to be safe to call [`get_mut_unchecked`] - /// on this `Arc`, so long as no clones occur in between. - /// - /// # Examples - /// - /// ``` - /// #![feature(arc_is_unique)] - /// - /// use std::sync::Arc; - /// - /// let x = Arc::new(3); - /// assert!(Arc::is_unique(&x)); - /// - /// let y = Arc::clone(&x); - /// assert!(!Arc::is_unique(&x)); - /// drop(y); - /// - /// // Weak references also count, because they could be upgraded at any time. - /// let z = Arc::downgrade(&x); - /// assert!(!Arc::is_unique(&x)); - /// ``` - /// - /// # Pointer invalidation - /// - /// This function will always return the same value as `Arc::get_mut(arc).is_some()`. However, - /// unlike that operation it does not produce any mutable references to the underlying data, - /// meaning no pointers to the data inside the `Arc` are invalidated by the call. Thus, the - /// following code is valid, even though it would be UB if it used `Arc::get_mut`: - /// - /// ``` - /// #![feature(arc_is_unique)] - /// - /// use std::sync::Arc; - /// - /// let arc = Arc::new(5); - /// let pointer: *const i32 = &*arc; - /// assert!(Arc::is_unique(&arc)); - /// assert_eq!(unsafe { *pointer }, 5); - /// ``` - /// - /// # Atomic orderings - /// - /// Concurrent drops to other `Arc` pointers to the same allocation will synchronize with this - /// call - that is, this call performs an `Acquire` operation on the underlying strong and weak - /// ref counts. This ensures that calling `get_mut_unchecked` is safe. - /// - /// Note that this operation requires locking the weak ref count, so concurrent calls to - /// `downgrade` may spin-loop for a short period of time. - /// - /// [`get_mut_unchecked`]: Self::get_mut_unchecked - #[inline] - #[unstable(feature = "arc_is_unique", issue = "138938")] - pub fn is_unique(this: &Self) -> bool { - // lock the weak pointer count if we appear to be the sole weak pointer - // holder. - // - // The acquire label here ensures a happens-before relationship with any - // writes to `strong` (in particular in `Weak::upgrade`) prior to decrements - // of the `weak` count (via `Weak::drop`, which uses release). If the upgraded - // weak ref was never dropped, the CAS here will fail so we do not care to synchronize. - if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() { - // This needs to be an `Acquire` to synchronize with the decrement of the `strong` - // counter in `drop` -- the only access that happens when any but the last reference - // is being dropped. - let unique = this.inner().strong.load(Acquire) == 1; - - // The release write here synchronizes with a read in `downgrade`, - // effectively preventing the above read of `strong` from happening - // after the write. - this.inner().weak.store(1, Release); // release the lock - unique - } else { - false - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Arc { - /// Drops the `Arc`. - /// - /// This will decrement the strong reference count. If the strong reference - /// count reaches zero then the only other references (if any) are - /// [`Weak`], so we `drop` the inner value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// struct Foo; - /// - /// impl Drop for Foo { - /// fn drop(&mut self) { - /// println!("dropped!"); - /// } - /// } - /// - /// let foo = Arc::new(Foo); - /// let foo2 = Arc::clone(&foo); - /// - /// drop(foo); // Doesn't print anything - /// drop(foo2); // Prints "dropped!" - /// ``` - #[inline] - fn drop(&mut self) { - // Because `fetch_sub` is already atomic, we do not need to synchronize - // with other threads unless we are going to delete the object. This - // same logic applies to the below `fetch_sub` to the `weak` count. - if self.inner().strong.fetch_sub(1, Release) != 1 { - return; - } - - // This fence is needed to prevent reordering of use of the data and - // deletion of the data. Because it is marked `Release`, the decreasing - // of the reference count synchronizes with this `Acquire` fence. This - // means that use of the data happens before decreasing the reference - // count, which happens before this fence, which happens before the - // deletion of the data. - // - // As explained in the [Boost documentation][1], - // - // > It is important to enforce any possible access to the object in one - // > thread (through an existing reference) to *happen before* deleting - // > the object in a different thread. This is achieved by a "release" - // > operation after dropping a reference (any access to the object - // > through this reference must obviously happened before), and an - // > "acquire" operation before deleting the object. - // - // In particular, while the contents of an Arc are usually immutable, it's - // possible to have interior writes to something like a Mutex. Since a - // Mutex is not acquired when it is deleted, we can't rely on its - // synchronization logic to make writes in thread A visible to a destructor - // running in thread B. - // - // Also note that the Acquire fence here could probably be replaced with an - // Acquire load, which could improve performance in highly-contended - // situations. See [2]. - // - // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) - // [2]: (https://github.com/rust-lang/rust/pull/41714) - acquire!(self.inner().strong); - - // Make sure we aren't trying to "drop" the shared static for empty slices - // used by Default::default. - debug_assert!( - !ptr::addr_eq(self.ptr.as_ptr(), &STATIC_INNER_SLICE.inner), - "Arcs backed by a static should never reach a strong count of 0. \ - Likely decrement_strong_count or from_raw were called too many times.", - ); - - // ignore-tidy-undocumented-unsafe - unsafe { - self.drop_slow(); - } - } -} - -impl Arc { - /// Attempts to downcast the `Arc` to a concrete type. - /// - /// # Examples - /// - /// ``` - /// use std::any::Any; - /// use std::sync::Arc; - /// - /// fn print_if_string(value: Arc) { - /// if let Ok(string) = value.downcast::() { - /// println!("String ({}): {}", string.len(), string); - /// } - /// } - /// - /// let my_string = "Hello World".to_string(); - /// print_if_string(Arc::new(my_string)); - /// print_if_string(Arc::new(0i8)); - /// ``` - #[inline] - #[stable(feature = "rc_downcast", since = "1.29.0")] - pub fn downcast(self) -> Result, Self> - where - T: Any + Send + Sync, - { - if (*self).is::() { - // SAFETY: Check ensures the typecast is okay. - unsafe { - let (ptr, alloc) = Arc::into_inner_with_allocator(self); - Ok(Arc::from_inner_in(ptr.cast(), alloc)) - } - } else { - Err(self) - } - } - - /// Downcasts the `Arc` to a concrete type. - /// - /// For a safe alternative see [`downcast`]. - /// - /// # Examples - /// - /// ``` - /// #![feature(downcast_unchecked)] - /// - /// use std::any::Any; - /// use std::sync::Arc; - /// - /// let x: Arc = Arc::new(1_usize); - /// - /// unsafe { - /// assert_eq!(*x.downcast_unchecked::(), 1); - /// } - /// ``` - /// - /// # Safety - /// - /// The contained value must be of type `T`. Calling this method - /// with the incorrect type is *undefined behavior*. - /// - /// - /// [`downcast`]: Self::downcast - #[inline] - #[unstable(feature = "downcast_unchecked", issue = "90850")] - pub unsafe fn downcast_unchecked(self) -> Arc - where - T: Any + Send + Sync, - { - // SAFETY: Upheld by caller. - unsafe { - let (ptr, alloc) = Arc::into_inner_with_allocator(self); - Arc::from_inner_in(ptr.cast(), alloc) - } - } -} - -impl Weak { - /// Constructs a new `Weak`, without allocating any memory. - /// Calling [`upgrade`] on the return value always gives [`None`]. - /// - /// [`upgrade`]: Weak::upgrade - /// - /// # Examples - /// - /// ``` - /// use std::sync::Weak; - /// - /// let empty: Weak = Weak::new(); - /// assert!(empty.upgrade().is_none()); - /// ``` - #[inline] - #[stable(feature = "downgraded_weak", since = "1.10.0")] - #[rustc_const_stable(feature = "const_weak_new", since = "1.73.0")] - #[must_use] - pub const fn new() -> Weak { - Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc: Global } - } -} - -impl Weak { - /// Constructs a new `Weak`, without allocating any memory, technically in the provided - /// allocator. - /// Calling [`upgrade`] on the return value always gives [`None`]. - /// - /// [`upgrade`]: Weak::upgrade - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// - /// use std::sync::Weak; - /// use std::alloc::System; - /// - /// let empty: Weak = Weak::new_in(System); - /// assert!(empty.upgrade().is_none()); - /// ``` - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn new_in(alloc: A) -> Weak { - Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc } - } -} - -/// Helper type to allow accessing the reference counts without -/// making any assertions about the data field. -struct WeakInner<'a> { - weak: &'a Atomic, - strong: &'a Atomic, -} - -impl Weak { - /// Converts a raw pointer previously created by [`into_raw`] back into `Weak`. - /// - /// This can be used to safely get a strong reference (by calling [`upgrade`] - /// later) or to deallocate the weak count by dropping the `Weak`. - /// - /// It takes ownership of one weak reference (with the exception of pointers created by [`new`], - /// as these don't own anything; the method still works on them). - /// - /// # Safety - /// - /// The pointer must have originated from the [`into_raw`] and must still own its potential - /// weak reference, and must point to a block of memory allocated by global allocator. - /// - /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this - /// takes ownership of one weak reference currently represented as a raw pointer (the weak - /// count is not modified by this operation) and therefore it must be paired with a previous - /// call to [`into_raw`]. - /// # Examples - /// - /// ``` - /// use std::sync::{Arc, Weak}; - /// - /// let strong = Arc::new("hello".to_owned()); - /// - /// let raw_1 = Arc::downgrade(&strong).into_raw(); - /// let raw_2 = Arc::downgrade(&strong).into_raw(); - /// - /// assert_eq!(2, Arc::weak_count(&strong)); - /// - /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); - /// assert_eq!(1, Arc::weak_count(&strong)); - /// - /// drop(strong); - /// - /// // Decrement the last weak count. - /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); - /// ``` - /// - /// [`new`]: Weak::new - /// [`into_raw`]: Weak::into_raw - /// [`upgrade`]: Weak::upgrade - #[inline] - #[stable(feature = "weak_into_raw", since = "1.45.0")] - pub unsafe fn from_raw(ptr: *const T) -> Self { - // SAFETY: Upheld by caller. - unsafe { Weak::from_raw_in(ptr, Global) } - } - - /// Consumes the `Weak` and turns it into a raw pointer. - /// - /// This converts the weak pointer into a raw pointer, while still preserving the ownership of - /// one weak reference (the weak count is not modified by this operation). It can be turned - /// back into the `Weak` with [`from_raw`]. - /// - /// The same restrictions of accessing the target of the pointer as with - /// [`as_ptr`] apply. - /// - /// # Examples - /// - /// ``` - /// use std::sync::{Arc, Weak}; - /// - /// let strong = Arc::new("hello".to_owned()); - /// let weak = Arc::downgrade(&strong); - /// let raw = weak.into_raw(); - /// - /// assert_eq!(1, Arc::weak_count(&strong)); - /// assert_eq!("hello", unsafe { &*raw }); - /// - /// drop(unsafe { Weak::from_raw(raw) }); - /// assert_eq!(0, Arc::weak_count(&strong)); - /// ``` - /// - /// [`from_raw`]: Weak::from_raw - /// [`as_ptr`]: Weak::as_ptr - #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "weak_into_raw", since = "1.45.0")] - pub fn into_raw(self) -> *const T { - ManuallyDrop::new(self).as_ptr() - } -} - -impl Weak { - /// Returns a reference to the underlying allocator. - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn allocator(&self) -> &A { - &self.alloc - } - - /// Returns a raw pointer to the object `T` pointed to by this `Weak`. - /// - /// The pointer is valid only if there are some strong references. The pointer may be dangling, - /// unaligned or even [`null`] otherwise. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// use std::ptr; - /// - /// let strong = Arc::new("hello".to_owned()); - /// let weak = Arc::downgrade(&strong); - /// // Both point to the same object - /// assert!(ptr::eq(&*strong, weak.as_ptr())); - /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*weak.as_ptr() }); - /// - /// drop(strong); - /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to - /// // undefined behavior. - /// // assert_eq!("hello", unsafe { &*weak.as_ptr() }); - /// ``` - /// - /// [`null`]: core::ptr::null "ptr::null" - #[must_use] - #[stable(feature = "weak_into_raw", since = "1.45.0")] - pub fn as_ptr(&self) -> *const T { - let ptr: *mut ArcInner = NonNull::as_ptr(self.ptr); - - if is_dangling(ptr) { - // If the pointer is dangling, we return the sentinel directly. This cannot be - // a valid payload address, as the payload is at least as aligned as ArcInner (usize). - ptr as *const T - } else { - // SAFETY: if is_dangling returns false, then the pointer is dereferenceable. - // The payload may be dropped at this point, and we have to maintain provenance, - // so use raw pointer manipulation. - unsafe { &raw mut (*ptr).data } - } - } - - /// Consumes the `Weak`, returning the wrapped pointer and allocator. - /// - /// This converts the weak pointer into a raw pointer, while still preserving the ownership of - /// one weak reference (the weak count is not modified by this operation). It can be turned - /// back into the `Weak` with [`from_raw_in`]. - /// - /// The same restrictions of accessing the target of the pointer as with - /// [`as_ptr`] apply. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_ext)] - /// use std::sync::{Arc, Weak}; - /// use std::alloc::System; - /// - /// let strong = Arc::new_in("hello".to_owned(), System); - /// let weak = Arc::downgrade(&strong); - /// let (raw, alloc) = weak.into_raw_with_allocator(); - /// - /// assert_eq!(1, Arc::weak_count(&strong)); - /// assert_eq!("hello", unsafe { &*raw }); - /// - /// drop(unsafe { Weak::from_raw_in(raw, alloc) }); - /// assert_eq!(0, Arc::weak_count(&strong)); - /// ``` - /// - /// [`from_raw_in`]: Weak::from_raw_in - /// [`as_ptr`]: Weak::as_ptr - #[must_use = "losing the pointer will leak memory"] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub fn into_raw_with_allocator(self) -> (*const T, A) { - let this = mem::ManuallyDrop::new(self); - let result = this.as_ptr(); - // SAFETY: `this` is ManuallyDrop so the allocator will not be double-dropped - let alloc = unsafe { ptr::read(&this.alloc) }; - (result, alloc) - } - - /// Converts a raw pointer previously created by [`into_raw`] back into `Weak` in the provided - /// allocator. - /// - /// This can be used to safely get a strong reference (by calling [`upgrade`] - /// later) or to deallocate the weak count by dropping the `Weak`. - /// - /// It takes ownership of one weak reference (with the exception of pointers created by [`new`], - /// as these don't own anything; the method still works on them). - /// - /// # Safety - /// - /// The pointer must have originated from the [`into_raw`] and must still own its potential - /// weak reference, and must point to a block of memory allocated by `alloc`. - /// - /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this - /// takes ownership of one weak reference currently represented as a raw pointer (the weak - /// count is not modified by this operation) and therefore it must be paired with a previous - /// call to [`into_raw`]. - /// # Examples - /// - /// ``` - /// use std::sync::{Arc, Weak}; - /// - /// let strong = Arc::new("hello".to_owned()); - /// - /// let raw_1 = Arc::downgrade(&strong).into_raw(); - /// let raw_2 = Arc::downgrade(&strong).into_raw(); - /// - /// assert_eq!(2, Arc::weak_count(&strong)); - /// - /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); - /// assert_eq!(1, Arc::weak_count(&strong)); - /// - /// drop(strong); - /// - /// // Decrement the last weak count. - /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); - /// ``` - /// - /// [`new`]: Weak::new - /// [`into_raw`]: Weak::into_raw - /// [`upgrade`]: Weak::upgrade - #[inline] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] - pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { - // See Weak::as_ptr for context on how the input pointer is derived. - - let ptr = if is_dangling(ptr) { - // This is a dangling Weak. - ptr as *mut ArcInner - } else { - // Otherwise, we're guaranteed the pointer came from a nondangling Weak. - // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T. - let offset = unsafe { data_offset(ptr) }; - // Thus, we reverse the offset to get the whole ArcInner. - // SAFETY: the pointer originated from a Weak, so this offset is safe. - unsafe { ptr.byte_sub(offset) as *mut ArcInner } - }; - - // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. - Weak { ptr: unsafe { NonNull::new_unchecked(ptr) }, alloc } - } -} - -impl Weak { - /// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying - /// dropping of the inner value if successful. - /// - /// Returns [`None`] in the following cases: - /// - /// 1. The inner value has since been dropped or moved out. - /// - /// 2. This `Weak` does not point to an allocation. - /// - /// 3. The owning reference this `Weak` is associated with is either not fully-constructed or does not allow an upgrade. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// let weak_five = Arc::downgrade(&five); - /// - /// let strong_five: Option> = weak_five.upgrade(); - /// assert!(strong_five.is_some()); - /// - /// // Destroy all strong pointers. - /// drop(strong_five); - /// drop(five); - /// - /// assert!(weak_five.upgrade().is_none()); - /// ``` - #[must_use = "this returns a new `Arc`, \ - without modifying the original weak pointer"] - #[stable(feature = "arc_weak", since = "1.4.0")] - pub fn upgrade(&self) -> Option> - where - A: AllocatorClone, - { - #[inline] - fn checked_increment(n: usize) -> Option { - // Any write of 0 we can observe leaves the field in permanently zero state. - if n == 0 { - return None; - } - // See comments in `Arc::clone` for why we do this (for `mem::forget`). - if n > MAX_REFCOUNT { - panic_arc_overflow(); - } - Some(n + 1) - } - - // We use a CAS loop to increment the strong count instead of a - // fetch_add as this function should never take the reference count - // from zero to one. - // - // Relaxed is fine for the failure case because we don't have any expectations about the new state. - // Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner - // value can be initialized after `Weak` references have already been created. In that case, we - // expect to observe the fully initialized value. - if self.inner()?.strong.try_update(Acquire, Relaxed, checked_increment).is_ok() { - // SAFETY: pointer is not null, verified in checked_increment - unsafe { Some(Arc::from_inner_in(self.ptr, self.alloc.clone())) } - } else { - None - } - } - - /// Gets the number of strong (`Arc`) pointers pointing to this allocation. - /// - /// If `self` was created using [`Weak::new`], this will return 0. - #[must_use] - #[stable(feature = "weak_counts", since = "1.41.0")] - pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 } - } - - /// Gets an approximation of the number of `Weak` pointers pointing to this - /// allocation. - /// - /// If `self` was created using [`Weak::new`], or if there are no remaining - /// strong pointers, this will return 0. - /// - /// # Accuracy - /// - /// Due to implementation details, the returned value can be off by 1 in - /// either direction when other threads are manipulating any `Arc`s or - /// `Weak`s pointing to the same allocation. - #[must_use] - #[stable(feature = "weak_counts", since = "1.41.0")] - pub fn weak_count(&self) -> usize { - if let Some(inner) = self.inner() { - let weak = inner.weak.load(Acquire); - let strong = inner.strong.load(Relaxed); - if strong == 0 { - 0 - } else { - // Since we observed that there was at least one strong pointer - // after reading the weak count, we know that the implicit weak - // reference (present whenever any strong references are alive) - // was still around when we observed the weak count, and can - // therefore safely subtract it. - weak - 1 - } - } else { - 0 - } - } - - /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`, - /// (i.e., when this `Weak` was created by `Weak::new`). - #[inline] - fn inner(&self) -> Option> { - let ptr = self.ptr.as_ptr(); - if is_dangling(ptr) { - None - } else { - // We are careful to *not* create a reference covering the "data" field, as - // the field may be mutated concurrently (for example, if the last `Arc` - // is dropped, the data field will be dropped in-place). - // ignore-tidy-undocumented-unsafe - Some(unsafe { WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak } }) - } - } - - /// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if - /// both don't point to any allocation (because they were created with `Weak::new()`). However, - /// this function ignores the metadata of `dyn Trait` pointers. - /// - /// # Notes - /// - /// Since this compares pointers it means that `Weak::new()` will equal each - /// other, even though they don't point to any allocation. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let first_rc = Arc::new(5); - /// let first = Arc::downgrade(&first_rc); - /// let second = Arc::downgrade(&first_rc); - /// - /// assert!(first.ptr_eq(&second)); - /// - /// let third_rc = Arc::new(5); - /// let third = Arc::downgrade(&third_rc); - /// - /// assert!(!first.ptr_eq(&third)); - /// ``` - /// - /// Comparing `Weak::new`. - /// - /// ``` - /// use std::sync::{Arc, Weak}; - /// - /// let first = Weak::new(); - /// let second = Weak::new(); - /// assert!(first.ptr_eq(&second)); - /// - /// let third_rc = Arc::new(()); - /// let third = Arc::downgrade(&third_rc); - /// assert!(!first.ptr_eq(&third)); - /// ``` - /// - /// [`ptr::eq`]: core::ptr::eq "ptr::eq" - #[inline] - #[must_use] - #[stable(feature = "weak_ptr_eq", since = "1.39.0")] - pub fn ptr_eq(&self, other: &Self) -> bool { - ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr()) - } -} - -#[stable(feature = "arc_weak", since = "1.4.0")] -impl Clone for Weak { - /// Makes a clone of the `Weak` pointer that points to the same allocation. - /// - /// # Examples - /// - /// ``` - /// use std::sync::{Arc, Weak}; - /// - /// let weak_five = Arc::downgrade(&Arc::new(5)); - /// - /// let _ = Weak::clone(&weak_five); - /// ``` - #[inline] - fn clone(&self) -> Weak { - if let Some(inner) = self.inner() { - // See comments in Arc::clone() for why this is relaxed. This can use a - // fetch_add (ignoring the lock) because the weak count is only locked - // where are *no other* weak pointers in existence. (So we can't be - // running this code in that case). - let old_size = inner.weak.fetch_add(1, Relaxed); - - // See comments in Arc::clone() for why we do this (for mem::forget). - if old_size > MAX_REFCOUNT { - abort(); - } - } - - Weak { ptr: self.ptr, alloc: self.alloc.clone() } - } -} - -#[unstable(feature = "ergonomic_clones", issue = "132290")] -impl UseCloned for Weak {} - -#[stable(feature = "downgraded_weak", since = "1.10.0")] -impl Default for Weak { - /// Constructs a new `Weak`, without allocating memory. - /// Calling [`upgrade`] on the return value always - /// gives [`None`]. - /// - /// [`upgrade`]: Weak::upgrade - /// - /// # Examples - /// - /// ``` - /// use std::sync::Weak; - /// - /// let empty: Weak = Default::default(); - /// assert!(empty.upgrade().is_none()); - /// ``` - fn default() -> Weak { - Weak::new() - } -} - -#[stable(feature = "arc_weak", since = "1.4.0")] -unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak { - /// Drops the `Weak` pointer. - /// - /// # Examples - /// - /// ``` - /// use std::sync::{Arc, Weak}; - /// - /// struct Foo; - /// - /// impl Drop for Foo { - /// fn drop(&mut self) { - /// println!("dropped!"); - /// } - /// } - /// - /// let foo = Arc::new(Foo); - /// let weak_foo = Arc::downgrade(&foo); - /// let other_weak_foo = Weak::clone(&weak_foo); - /// - /// drop(weak_foo); // Doesn't print anything - /// drop(foo); // Prints "dropped!" - /// - /// assert!(other_weak_foo.upgrade().is_none()); - /// ``` - fn drop(&mut self) { - // If we find out that we were the last weak pointer, then its time to - // deallocate the data entirely. See the discussion in Arc::drop() about - // the memory orderings - // - // It's not necessary to check for the locked state here, because the - // weak count can only be locked if there was precisely one weak ref, - // meaning that drop could only subsequently run ON that remaining weak - // ref, which can only happen after the lock is released. - let inner = if let Some(inner) = self.inner() { inner } else { return }; - - if inner.weak.fetch_sub(1, Release) == 1 { - acquire!(inner.weak); - - // Make sure we aren't trying to "deallocate" the shared static for empty slices - // used by Default::default. - debug_assert!( - !ptr::addr_eq(self.ptr.as_ptr(), &STATIC_INNER_SLICE.inner), - "Arc/Weaks backed by a static should never be deallocated. \ - Likely decrement_strong_count or from_raw were called too many times.", - ); - - // ignore-tidy-undocumented-unsafe - unsafe { - self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())) - } - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -trait ArcEqIdent { - fn eq(&self, other: &Arc) -> bool; - fn ne(&self, other: &Arc) -> bool; -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ArcEqIdent for Arc { - #[inline] - default fn eq(&self, other: &Arc) -> bool { - **self == **other - } - #[inline] - default fn ne(&self, other: &Arc) -> bool { - **self != **other - } -} - -/// We're doing this specialization here, and not as a more general optimization on `&T`, because it -/// would otherwise add a cost to all equality checks on refs. We assume that `Arc`s are used to -/// store large values, that are slow to clone, but also heavy to check for equality, causing this -/// cost to pay off more easily. It's also more likely to have two `Arc` clones, that point to -/// the same value, than two `&T`s. -/// -/// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive. -#[stable(feature = "rust1", since = "1.0.0")] -impl ArcEqIdent for Arc { - #[inline] - fn eq(&self, other: &Arc) -> bool { - ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) || **self == **other - } - - #[inline] - fn ne(&self, other: &Arc) -> bool { - !ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) && **self != **other - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for Arc { - /// Equality for two `Arc`s. - /// - /// Two `Arc`s are equal if their inner values are equal, even if they are - /// stored in different allocation. - /// - /// If `T` also implements `Eq` (implying reflexivity of equality), - /// two `Arc`s that point to the same allocation are always equal. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// assert!(five == Arc::new(5)); - /// ``` - #[inline] - fn eq(&self, other: &Arc) -> bool { - ArcEqIdent::eq(self, other) - } - - /// Inequality for two `Arc`s. - /// - /// Two `Arc`s are not equal if their inner values are not equal. - /// - /// If `T` also implements `Eq` (implying reflexivity of equality), - /// two `Arc`s that point to the same value are always equal. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// assert!(five != Arc::new(6)); - /// ``` - #[inline] - fn ne(&self, other: &Arc) -> bool { - ArcEqIdent::ne(self, other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Arc { - /// Partial comparison for two `Arc`s. - /// - /// The two are compared by calling `partial_cmp()` on their inner values. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// use std::cmp::Ordering; - /// - /// let five = Arc::new(5); - /// - /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6))); - /// ``` - fn partial_cmp(&self, other: &Arc) -> Option { - (**self).partial_cmp(&**other) - } - - /// Less-than comparison for two `Arc`s. - /// - /// The two are compared by calling `<` on their inner values. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// assert!(five < Arc::new(6)); - /// ``` - fn lt(&self, other: &Arc) -> bool { - *(*self) < *(*other) - } - - /// 'Less than or equal to' comparison for two `Arc`s. - /// - /// The two are compared by calling `<=` on their inner values. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// assert!(five <= Arc::new(5)); - /// ``` - fn le(&self, other: &Arc) -> bool { - *(*self) <= *(*other) - } - - /// Greater-than comparison for two `Arc`s. - /// - /// The two are compared by calling `>` on their inner values. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// assert!(five > Arc::new(4)); - /// ``` - fn gt(&self, other: &Arc) -> bool { - *(*self) > *(*other) - } - - /// 'Greater than or equal to' comparison for two `Arc`s. - /// - /// The two are compared by calling `>=` on their inner values. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let five = Arc::new(5); - /// - /// assert!(five >= Arc::new(5)); - /// ``` - fn ge(&self, other: &Arc) -> bool { - *(*self) >= *(*other) - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Arc { - /// Comparison for two `Arc`s. - /// - /// The two are compared by calling `cmp()` on their inner values. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// use std::cmp::Ordering; - /// - /// let five = Arc::new(5); - /// - /// assert_eq!(Ordering::Less, five.cmp(&Arc::new(6))); - /// ``` - fn cmp(&self, other: &Arc) -> Ordering { - (**self).cmp(&**other) - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl Eq for Arc {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Display for Arc { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Arc { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Pointer for Arc { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&(&raw const **self), f) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "rust1", since = "1.0.0")] -impl Default for Arc { - /// Creates a new `Arc`, with the `Default` value for `T`. - /// - /// # Examples - /// - /// ``` - /// use std::sync::Arc; - /// - /// let x: Arc = Default::default(); - /// assert_eq!(*x, 0); - /// ``` - fn default() -> Arc { - // ignore-tidy-undocumented-unsafe - unsafe { - Self::from_inner(Box::into_non_null(Box::write( - Box::new_uninit(), - ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data: T::default(), - }, - ))) - } - } -} - -/// Struct to hold the static `ArcInner` used for empty `Arc` as -/// returned by `Default::default`. -/// -/// Layout notes: -/// * `repr(align(16))` so we can use it for `[T]` with `align_of::() <= 16`. -/// * `repr(C)` so `inner` is at offset 0 (and thus guaranteed to actually be aligned to 16). -/// * `[u8; 1]` (to be initialized with 0) so it can be used for `Arc`. -#[repr(C, align(16))] -struct SliceArcInnerForStatic { - inner: ArcInner<[u8; 1]>, -} -#[cfg(not(no_global_oom_handling))] -const MAX_STATIC_INNER_SLICE_ALIGNMENT: usize = 16; - -static STATIC_INNER_SLICE: SliceArcInnerForStatic = SliceArcInnerForStatic { - inner: ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data: [0], - }, -}; - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "1.80.0")] -impl Default for Arc { - /// Creates an empty str inside an Arc - /// - /// This may or may not share an allocation with other Arcs. - #[inline] - fn default() -> Self { - let arc: Arc<[u8]> = Default::default(); - debug_assert!(core::str::from_utf8(&arc).is_ok()); - let (ptr, alloc) = Arc::into_inner_with_allocator(arc); - // ignore-tidy-undocumented-unsafe - unsafe { Arc::from_ptr_in(ptr.as_ptr() as *mut ArcInner, alloc) } - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "1.80.0")] -impl Default for Arc { - /// Creates an empty CStr inside an Arc - /// - /// This may or may not share an allocation with other Arcs. - #[inline] - fn default() -> Self { - use core::ffi::CStr; - let inner: NonNull> = NonNull::from(&STATIC_INNER_SLICE.inner); - let inner: NonNull> = - NonNull::new(inner.as_ptr() as *mut ArcInner).unwrap(); - // `this` semantically is the Arc "owned" by the static, so make sure not to drop it. - let this: mem::ManuallyDrop> = - // ignore-tidy-undocumented-unsafe - unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) }; - (*this).clone() - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "1.80.0")] -impl Default for Arc<[T]> { - /// Creates an empty `[T]` inside an Arc - /// - /// This may or may not share an allocation with other Arcs. - #[inline] - fn default() -> Self { - if align_of::() <= MAX_STATIC_INNER_SLICE_ALIGNMENT { - // We take a reference to the whole struct instead of the ArcInner<[u8; 1]> inside it so - // we don't shrink the range of bytes the ptr is allowed to access under Stacked Borrows. - // (Miri complains on 32-bit targets with Arc<[Align16]> otherwise.) - // (Note that NonNull::from(&STATIC_INNER_SLICE.inner) is fine under Tree Borrows.) - let inner: NonNull = NonNull::from(&STATIC_INNER_SLICE); - let inner: NonNull> = inner.cast(); - // `this` semantically is the Arc "owned" by the static, so make sure not to drop it. - let this: mem::ManuallyDrop> = - // ignore-tidy-undocumented-unsafe - unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) }; - return (*this).clone(); - } - - // If T's alignment is too large for the static, make a new unique allocation. - let arr: [T; 0] = []; - Arc::from(arr) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "pin_default_impls", since = "1.91.0")] -impl Default for Pin> -where - T: ?Sized, - Arc: Default, -{ - #[inline] - fn default() -> Self { - // SAFETY: We own and create the pinned pointer. - unsafe { Pin::new_unchecked(Arc::::default()) } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Hash for Arc { - fn hash(&self, state: &mut H) { - (**self).hash(state) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "from_for_ptrs", since = "1.6.0")] -impl From for Arc { - /// Converts a `T` into an `Arc` - /// - /// The conversion moves the value into a - /// newly allocated `Arc`. It is equivalent to - /// calling `Arc::new(t)`. - /// - /// # Example - /// ```rust - /// # use std::sync::Arc; - /// let x = 5; - /// let arc = Arc::new(5); - /// - /// assert_eq!(Arc::from(x), arc); - /// ``` - fn from(t: T) -> Self { - Arc::new(t) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_array", since = "1.74.0")] -impl From<[T; N]> for Arc<[T]> { - /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`. - /// - /// The conversion moves the array into a newly allocated `Arc`. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let original: [i32; 3] = [1, 2, 3]; - /// let shared: Arc<[i32]> = Arc::from(original); - /// assert_eq!(&[1, 2, 3], &shared[..]); - /// ``` - #[inline] - fn from(v: [T; N]) -> Arc<[T]> { - Arc::<[T; N]>::from(v) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_slice", since = "1.21.0")] -impl From<&[T]> for Arc<[T]> { - /// Allocates a reference-counted slice and fills it by cloning `v`'s items. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let original: &[i32] = &[1, 2, 3]; - /// let shared: Arc<[i32]> = Arc::from(original); - /// assert_eq!(&[1, 2, 3], &shared[..]); - /// ``` - #[inline] - fn from(v: &[T]) -> Arc<[T]> { - >::from_slice(v) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] -impl From<&mut [T]> for Arc<[T]> { - /// Allocates a reference-counted slice and fills it by cloning `v`'s items. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let mut original = [1, 2, 3]; - /// let original: &mut [i32] = &mut original; - /// let shared: Arc<[i32]> = Arc::from(original); - /// assert_eq!(&[1, 2, 3], &shared[..]); - /// ``` - #[inline] - fn from(v: &mut [T]) -> Arc<[T]> { - Arc::from(&*v) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_slice", since = "1.21.0")] -impl From<&str> for Arc { - /// Allocates a reference-counted `str` and copies `v` into it. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let shared: Arc = Arc::from("eggplant"); - /// assert_eq!("eggplant", &shared[..]); - /// ``` - #[inline] - fn from(v: &str) -> Arc { - let arc = Arc::<[u8]>::from(v.as_bytes()); - // ignore-tidy-undocumented-unsafe - unsafe { Arc::from_raw(Arc::into_raw(arc) as *const str) } - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] -impl From<&mut str> for Arc { - /// Allocates a reference-counted `str` and copies `v` into it. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let mut original = String::from("eggplant"); - /// let original: &mut str = &mut original; - /// let shared: Arc = Arc::from(original); - /// assert_eq!("eggplant", &shared[..]); - /// ``` - #[inline] - fn from(v: &mut str) -> Arc { - Arc::from(&*v) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_slice", since = "1.21.0")] -impl From for Arc { - /// Allocates a reference-counted `str` and copies `v` into it. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let unique: String = "eggplant".to_owned(); - /// let shared: Arc = Arc::from(unique); - /// assert_eq!("eggplant", &shared[..]); - /// ``` - #[inline] - fn from(v: String) -> Arc { - Arc::from(&v[..]) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_slice", since = "1.21.0")] -impl From> for Arc { - /// Move a boxed object to a new, reference-counted allocation. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let unique: Box = Box::from("eggplant"); - /// let shared: Arc = Arc::from(unique); - /// assert_eq!("eggplant", &shared[..]); - /// ``` - #[inline] - fn from(v: Box) -> Arc { - Arc::from_box_in(v) - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_slice", since = "1.21.0")] -impl From> for Arc<[T], A> { - /// Allocates a reference-counted slice and moves `v`'s items into it. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let unique: Vec = vec![1, 2, 3]; - /// let shared: Arc<[i32]> = Arc::from(unique); - /// assert_eq!(&[1, 2, 3], &shared[..]); - /// ``` - #[inline] - fn from(v: Vec) -> Arc<[T], A> { - // ignore-tidy-undocumented-unsafe - unsafe { - let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_allocator(); - - let rc_ptr = Self::allocate_for_slice_in(len, &alloc); - ptr::copy_nonoverlapping(vec_ptr, (&raw mut (*rc_ptr).data) as *mut T, len); - - // Create a `Vec` with length 0, to deallocate the buffer - // without dropping its contents or the allocator - let _ = Vec::from_raw_parts_in(vec_ptr, 0, cap, &alloc); - - Self::from_ptr_in(rc_ptr, alloc) - } - } -} - -#[stable(feature = "shared_from_cow", since = "1.45.0")] -impl<'a, B> From> for Arc -where - B: ToOwned + ?Sized, - Arc: From<&'a B> + From, -{ - /// Creates an atomically reference-counted pointer from a clone-on-write - /// pointer by copying its content. - /// - /// # Example - /// - /// ```rust - /// # use std::sync::Arc; - /// # use std::borrow::Cow; - /// let cow: Cow<'_, str> = Cow::Borrowed("eggplant"); - /// let shared: Arc = Arc::from(cow); - /// assert_eq!("eggplant", &shared[..]); - /// ``` - #[inline] - fn from(cow: Cow<'a, B>) -> Arc { - match cow { - Cow::Borrowed(s) => Arc::from(s), - Cow::Owned(s) => Arc::from(s), - } - } -} - -#[stable(feature = "shared_from_str", since = "1.62.0")] -impl From> for Arc<[u8]> { - /// Converts an atomically reference-counted string slice into a byte slice. - /// - /// # Example - /// - /// ``` - /// # use std::sync::Arc; - /// let string: Arc = Arc::from("eggplant"); - /// let bytes: Arc<[u8]> = Arc::from(string); - /// assert_eq!("eggplant".as_bytes(), bytes.as_ref()); - /// ``` - #[inline] - fn from(rc: Arc) -> Self { - // SAFETY: `str` has the same layout as `[u8]`. - unsafe { Arc::from_raw(Arc::into_raw(rc) as *const [u8]) } - } -} - -#[stable(feature = "boxed_slice_try_from", since = "1.43.0")] -impl TryFrom> for Arc<[T; N], A> { - type Error = Arc<[T], A>; - - fn try_from(boxed_slice: Arc<[T], A>) -> Result { - if boxed_slice.len() == N { - let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice); - // ignore-tidy-undocumented-unsafe - Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) }) - } else { - Err(boxed_slice) - } - } -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_iter", since = "1.37.0")] -impl FromIterator for Arc<[T]> { - /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`. - /// - /// # Performance characteristics - /// - /// ## The general case - /// - /// In the general case, collecting into `Arc<[T]>` is done by first - /// collecting into a `Vec`. That is, when writing the following: - /// - /// ```rust - /// # use std::sync::Arc; - /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect(); - /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); - /// ``` - /// - /// this behaves as if we wrote: - /// - /// ```rust - /// # use std::sync::Arc; - /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0) - /// .collect::>() // The first set of allocations happens here. - /// .into(); // A second allocation for `Arc<[T]>` happens here. - /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); - /// ``` - /// - /// This will allocate as many times as needed for constructing the `Vec` - /// and then it will allocate once for turning the `Vec` into the `Arc<[T]>`. - /// - /// ## Iterators of known length - /// - /// When your `Iterator` implements `TrustedLen` and is of an exact size, - /// a single allocation will be made for the `Arc<[T]>`. For example: - /// - /// ```rust - /// # use std::sync::Arc; - /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here. - /// # assert_eq!(&*evens, &*(0..10).collect::>()); - /// ``` - fn from_iter>(iter: I) -> Self { - ToArcSlice::to_arc_slice(iter.into_iter()) - } -} - -#[cfg(not(no_global_oom_handling))] -/// Specialization trait used for collecting into `Arc<[T]>`. -trait ToArcSlice: Iterator + Sized { - fn to_arc_slice(self) -> Arc<[T]>; -} - -#[cfg(not(no_global_oom_handling))] -impl> ToArcSlice for I { - default fn to_arc_slice(self) -> Arc<[T]> { - self.collect::>().into() - } -} - -#[cfg(not(no_global_oom_handling))] -impl> ToArcSlice for I { - fn to_arc_slice(self) -> Arc<[T]> { - // This is the case for a `TrustedLen` iterator. - let (low, high) = self.size_hint(); - if let Some(high) = high { - debug_assert_eq!( - low, - high, - "TrustedLen iterator's size hint is not exact: {:?}", - (low, high) - ); - - // SAFETY: We need to ensure that the iterator has an exact length and we have. - unsafe { Arc::from_iter_exact(self, low) } - } else { - // TrustedLen contract guarantees that `upper_bound == None` implies an iterator - // length exceeding `usize::MAX`. - // The default implementation would collect into a vec which would panic. - // Thus we panic here immediately without invoking `Vec` code. - panic!("capacity overflow"); - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl borrow::Borrow for Arc { - fn borrow(&self) -> &T { - self - } -} - -#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] -impl AsRef for Arc { - fn as_ref(&self) -> &T { - self - } -} - -#[stable(feature = "pin", since = "1.33.0")] -impl Unpin for Arc {} - -/// Gets the offset within an `ArcInner` for the payload behind a pointer. -/// -/// # Safety -/// -/// The pointer must point to (and have valid metadata for) a previously -/// valid instance of T, but the T is allowed to be dropped. -unsafe fn data_offset(ptr: *const T) -> usize { - // Align the unsized value to the end of the ArcInner. - // Because ArcInner is repr(C), it will always be the last field in memory. - // SAFETY: since the only unsized types possible are slices, trait objects, - // and extern types, the input safety requirement is currently enough to - // satisfy the requirements of Alignment::of_val_raw; this is an implementation - // detail of the language that must not be relied upon outside of std. - unsafe { data_offset_alignment(Alignment::of_val_raw(ptr)) } -} - -#[inline] -fn data_offset_alignment(alignment: Alignment) -> usize { - let layout = Layout::new::>(); - layout.size() + layout.padding_needed_for(alignment) -} - -/// A unique owning pointer to an [`ArcInner`] **that does not imply the contents are initialized,** -/// but will deallocate it (without dropping the value) when dropped. -/// -/// This is a helper for [`Arc::make_mut()`] to ensure correct cleanup on panic. -struct UniqueArcUninit { - ptr: NonNull>, - layout_for_value: Layout, - alloc: Option, -} - -impl UniqueArcUninit { - /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it. - #[cfg(not(no_global_oom_handling))] - fn new(for_value: &T, alloc: A) -> UniqueArcUninit { - let layout = Layout::for_value(for_value); - // ignore-tidy-undocumented-unsafe - let ptr = unsafe { - Arc::allocate_for_layout( - layout, - |layout_for_arcinner| alloc.allocate(layout_for_arcinner), - |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const ArcInner), - ) - }; - Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) } - } - - /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it, - /// returning an error if allocation fails. - fn try_new(for_value: &T, alloc: A) -> Result, AllocError> { - let layout = Layout::for_value(for_value); - // ignore-tidy-undocumented-unsafe - let ptr = unsafe { - Arc::try_allocate_for_layout( - layout, - |layout_for_arcinner| alloc.allocate(layout_for_arcinner), - |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const ArcInner), - )? - }; - Ok(Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) }) - } - - /// Returns the pointer to be written into to initialize the [`Arc`]. - fn data_ptr(&mut self) -> *mut T { - let offset = data_offset_alignment(self.layout_for_value.alignment()); - // ignore-tidy-undocumented-unsafe - unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } - } - - /// Upgrade this into a normal [`Arc`]. - /// - /// # Safety - /// - /// The data must have been initialized (by writing to [`Self::data_ptr()`]). - unsafe fn into_arc(self) -> Arc { - let mut this = ManuallyDrop::new(self); - let ptr = this.ptr.as_ptr(); - let alloc = this.alloc.take().unwrap(); - - // SAFETY: The pointer is valid as per `UniqueArcUninit::new`, and the caller is responsible - // for having initialized the data. - unsafe { Arc::from_ptr_in(ptr, alloc) } - } -} - -impl Drop for UniqueArcUninit { - fn drop(&mut self) { - // SAFETY: - // * new() produced a pointer safe to deallocate. - // * We own the pointer unless into_arc() was called, which forgets us. - unsafe { - self.alloc.take().unwrap().deallocate( - self.ptr.cast(), - arcinner_layout_for_value_layout(self.layout_for_value), - ); - } - } -} - -#[stable(feature = "arc_error", since = "1.52.0")] -impl core::error::Error for Arc { - #[allow(deprecated)] - fn cause(&self) -> Option<&dyn core::error::Error> { - core::error::Error::cause(&**self) - } - - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - core::error::Error::source(&**self) - } - - fn provide<'a>(&'a self, req: &mut core::error::Request<'a>) { - core::error::Error::provide(&**self, req); - } -} - -/// A uniquely owned [`Arc`]. -/// -/// This represents an `Arc` that is known to be uniquely owned -- that is, have exactly one strong -/// reference. Multiple weak pointers can be created, but attempts to upgrade those to strong -/// references will fail unless the `UniqueArc` they point to has been converted into a regular `Arc`. -/// -/// Because it is uniquely owned, the contents of a `UniqueArc` can be freely mutated. A common -/// use case is to have an object be mutable during its initialization phase but then have it become -/// immutable and converted to a normal `Arc`. -/// -/// This can be used as a flexible way to create cyclic data structures, as in the example below. -/// -/// ``` -/// #![feature(unique_rc_arc)] -/// use std::sync::{Arc, Weak, UniqueArc}; -/// -/// struct Gadget { -/// me: Weak, -/// } -/// -/// fn create_gadget() -> Option> { -/// let mut rc = UniqueArc::new(Gadget { -/// me: Weak::new(), -/// }); -/// rc.me = UniqueArc::downgrade(&rc); -/// Some(UniqueArc::into_arc(rc)) -/// } -/// -/// create_gadget().unwrap(); -/// ``` -/// -/// An advantage of using `UniqueArc` over [`Arc::new_cyclic`] to build cyclic data structures is that -/// [`Arc::new_cyclic`]'s `data_fn` parameter cannot be async or return a [`Result`]. As shown in the -/// previous example, `UniqueArc` allows for more flexibility in the construction of cyclic data, -/// including fallible or async constructors. -#[unstable(feature = "unique_rc_arc", issue = "112566")] -pub struct UniqueArc< - T: ?Sized, - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] A: Allocator = Global, -> { - ptr: NonNull>, - // Define the ownership of `ArcInner` for drop-check - _marker: PhantomData>, - // Invariance is necessary for soundness: once other `Weak` - // references exist, we already have a form of shared mutability! - _marker2: PhantomData<*mut T>, - alloc: A, -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -unsafe impl Send for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -unsafe impl Sync for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -// #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: ?Sized, A: Allocator> CoerceUnsized> - for UniqueArc -{ -} - -//#[unstable(feature = "unique_rc_arc", issue = "112566")] -#[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: ?Sized> DispatchFromDyn> for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl fmt::Display for UniqueArc { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl fmt::Debug for UniqueArc { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl fmt::Pointer for UniqueArc { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&(&raw const **self), f) - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl borrow::Borrow for UniqueArc { - fn borrow(&self) -> &T { - self - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl borrow::BorrowMut for UniqueArc { - fn borrow_mut(&mut self) -> &mut T { - self - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl AsRef for UniqueArc { - fn as_ref(&self) -> &T { - self - } -} - #[unstable(feature = "unique_rc_arc", issue = "112566")] -impl AsMut for UniqueArc { - fn as_mut(&mut self) -> &mut T { - self - } -} - -#[cfg(not(no_global_oom_handling))] -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl From for UniqueArc { - #[inline(always)] - fn from(value: T) -> Self { - Self::new(value) - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl Unpin for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl PartialEq for UniqueArc { - /// Equality for two `UniqueArc`s. - /// - /// Two `UniqueArc`s are equal if their inner values are equal. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// - /// let five = UniqueArc::new(5); - /// - /// assert!(five == UniqueArc::new(5)); - /// ``` - #[inline] - fn eq(&self, other: &Self) -> bool { - PartialEq::eq(&**self, &**other) - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl PartialOrd for UniqueArc { - /// Partial comparison for two `UniqueArc`s. - /// - /// The two are compared by calling `partial_cmp()` on their inner values. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// use std::cmp::Ordering; - /// - /// let five = UniqueArc::new(5); - /// - /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueArc::new(6))); - /// ``` - #[inline(always)] - fn partial_cmp(&self, other: &UniqueArc) -> Option { - (**self).partial_cmp(&**other) - } - - /// Less-than comparison for two `UniqueArc`s. - /// - /// The two are compared by calling `<` on their inner values. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// - /// let five = UniqueArc::new(5); - /// - /// assert!(five < UniqueArc::new(6)); - /// ``` - #[inline(always)] - fn lt(&self, other: &UniqueArc) -> bool { - **self < **other - } - - /// 'Less than or equal to' comparison for two `UniqueArc`s. - /// - /// The two are compared by calling `<=` on their inner values. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// - /// let five = UniqueArc::new(5); - /// - /// assert!(five <= UniqueArc::new(5)); - /// ``` - #[inline(always)] - fn le(&self, other: &UniqueArc) -> bool { - **self <= **other - } - - /// Greater-than comparison for two `UniqueArc`s. - /// - /// The two are compared by calling `>` on their inner values. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// - /// let five = UniqueArc::new(5); - /// - /// assert!(five > UniqueArc::new(4)); - /// ``` - #[inline(always)] - fn gt(&self, other: &UniqueArc) -> bool { - **self > **other - } - - /// 'Greater than or equal to' comparison for two `UniqueArc`s. - /// - /// The two are compared by calling `>=` on their inner values. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// - /// let five = UniqueArc::new(5); - /// - /// assert!(five >= UniqueArc::new(5)); - /// ``` - #[inline(always)] - fn ge(&self, other: &UniqueArc) -> bool { - **self >= **other - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl Ord for UniqueArc { - /// Comparison for two `UniqueArc`s. - /// - /// The two are compared by calling `cmp()` on their inner values. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// use std::sync::UniqueArc; - /// use std::cmp::Ordering; - /// - /// let five = UniqueArc::new(5); - /// - /// assert_eq!(Ordering::Less, five.cmp(&UniqueArc::new(6))); - /// ``` - #[inline] - fn cmp(&self, other: &UniqueArc) -> Ordering { - (**self).cmp(&**other) - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl Eq for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl Hash for UniqueArc { - fn hash(&self, state: &mut H) { - (**self).hash(state); - } -} - -impl UniqueArc { - /// Creates a new `UniqueArc`. - /// - /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading - /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`]. - /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will - /// point to the new [`Arc`]. - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "unique_rc_arc", issue = "112566")] - #[must_use] - pub fn new(value: T) -> Self { - Self::new_in(value, Global) - } - - /// Like [`new`](Self::new), but returns an error if the allocation - /// fails, instead of calling [`handle_alloc_error`]. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - pub fn try_new(value: T) -> Result { - Self::try_new_in(value, Global) - } -} - -impl UniqueArc { - /// Creates a new `UniqueArc` in the provided allocator. - /// - /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading - /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`]. - /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will - /// point to the new [`Arc`]. - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "unique_rc_arc", issue = "112566")] - // #[unstable(feature = "allocator_api", issue = "163177")] - #[must_use] - pub fn new_in(data: T, alloc: A) -> Self { - let (ptr, alloc) = Box::into_non_null_with_allocator(Box::new_in( - ArcInner { - strong: atomic::AtomicUsize::new(0), - // keep one weak reference so if all the weak pointers that are created are dropped - // the UniqueArc still stays valid. - weak: atomic::AtomicUsize::new(1), - data, - }, - alloc, - )); - Self { ptr, _marker: PhantomData, _marker2: PhantomData, alloc } - } - - /// Like [`new_in`](Self::new_in), but returns an error if the allocation - /// fails, instead of calling [`handle_alloc_error`]. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - // #[unstable(feature = "allocator_api", issue = "163177")] - pub fn try_new_in(data: T, alloc: A) -> Result { - let (ptr, alloc) = Box::into_non_null_with_allocator(Box::try_new_in( - ArcInner { - strong: atomic::AtomicUsize::new(0), - // keep one weak reference so if all the weak pointers that are created are dropped - // the UniqueArc still stays valid. - weak: atomic::AtomicUsize::new(1), - data, - }, - alloc, - )?); - Ok(Self { ptr, _marker: PhantomData, _marker2: PhantomData, alloc }) - } - - /// Consumes the `UniqueArc`, returning its wrapped value and allocator. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - // #[unstable(feature = "allocator_api", issue = "163177")] - #[must_use] - pub fn unwrap_with_allocator(this: Self) -> (T, A) { - let inner_ptr = this.ptr; - let (data_ptr, alloc) = Self::into_raw_with_allocator(this); - - // SAFETY: Conceptually moves out of the `UniqueRc`. - // We do not use the data inside ever again. - let val = unsafe { data_ptr.read() }; - - // Drop the strong-weak ref - drop(Weak { ptr: inner_ptr, alloc: &alloc }); - - (val, alloc) - } - - /// Consumes the `UniqueArc`, returning its wrapped value. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - #[must_use] - pub fn unwrap(this: Self) -> T { - Self::unwrap_with_allocator(this).0 - } - - /// Maps the value in a `UniqueArc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `UniqueArc`, and the result is returned, - /// also in a `UniqueArc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `UniqueArc::map(u, f)` instead of `u.map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(unique_rc_arc)] - /// - /// use std::sync::UniqueArc; - /// - /// let r = UniqueArc::new(7); - /// let new = UniqueArc::map(r, |i| i + 7); - /// assert_eq!(*new, 14); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "unique_rc_arc", issue = "112566")] - pub fn map(this: Self, f: impl FnOnce(T) -> U) -> UniqueArc { - if size_of::() == size_of::() - && align_of::() == align_of::() - && UniqueArc::weak_count(&this) == 0 - { - // ignore-tidy-undocumented-unsafe - unsafe { - let (ptr, alloc) = UniqueArc::into_raw_with_allocator(this); - let value = ptr.read(); - let allocation = - UniqueArc::from_raw_with_allocator(ptr.cast::>(), alloc); - - UniqueArc::write(allocation, f(value)) - } - } else { - let (val, alloc) = UniqueArc::unwrap_with_allocator(this); - UniqueArc::new_in(f(val), alloc) - } - } - - /// Attempts to map the value in a `UniqueArc`, reusing the allocation if possible. - /// - /// `f` is called on a reference to the value in the `UniqueArc`, and if the operation succeeds, - /// the result is returned, also in a `UniqueArc`. - /// - /// Note: this is an associated function, which means that you have - /// to call it as `UniqueArc::try_map(u, f)` instead of `u.try_map(f)`. This - /// is so that there is no conflict with a method on the inner type. - /// - /// # Examples - /// - /// ``` - /// #![feature(smart_pointer_try_map)] - /// #![feature(unique_rc_arc)] - /// - /// use std::sync::UniqueArc; - /// - /// let b = UniqueArc::new(7); - /// let new = UniqueArc::try_map(b, u32::try_from).unwrap(); - /// assert_eq!(*new, 7); - /// ``` - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] - pub fn try_map( - this: Self, - f: impl FnOnce(T) -> R, - ) -> >>::TryType - where - R: Try, - R::Residual: Residual>, - { - if size_of::() == size_of::() - && align_of::() == align_of::() - && UniqueArc::weak_count(&this) == 0 - { - // ignore-tidy-undocumented-unsafe - unsafe { - let (ptr, alloc) = UniqueArc::into_raw_with_allocator(this); - let value = ptr.read(); - let allocation = UniqueArc::from_raw_with_allocator( - ptr.cast::>(), - alloc, - ); - - try { UniqueArc::write(allocation, f(value)?) } - } - } else { - let (val, alloc) = UniqueArc::unwrap_with_allocator(this); - try { UniqueArc::new_in(f(val)?, alloc) } - } - } -} - -impl UniqueArc { - #[cfg(not(no_global_oom_handling))] - unsafe fn from_raw_with_allocator(ptr: *const T, alloc: A) -> Self { - // SAFETY: Upheld by caller. - let offset = unsafe { data_offset(ptr) }; - - // Reverse the offset to find the original ArcInner. - // SAFETY: Upheld by caller. - let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut ArcInner }; - - Self { - // SAFETY: Upheld by caller. - ptr: unsafe { NonNull::new_unchecked(rc_ptr) }, - _marker: PhantomData, - _marker2: PhantomData, - alloc, - } - } - - fn into_raw_with_allocator(this: Self) -> (*const T, A) { - let this = ManuallyDrop::new(this); - // SAFETY: The copy of the allocator stored in `this` is forgotten - (Self::as_ptr(&*this), unsafe { ptr::read(&this.alloc) }) - } - - /// Converts the `UniqueArc` into a regular [`Arc`]. - /// - /// This consumes the `UniqueArc` and returns a regular [`Arc`] that contains the `value` that - /// is passed to `into_arc`. - /// - /// Any weak references created before this method is called can now be upgraded to strong - /// references. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - #[must_use] - pub fn into_arc(this: Self) -> Arc { - let this = ManuallyDrop::new(this); - - // Move the allocator out. - // SAFETY: `this.alloc` will not be accessed again, nor dropped because it is in - // a `ManuallyDrop`. - let alloc: A = unsafe { ptr::read(&this.alloc) }; - - // SAFETY: This pointer was allocated at creation time so we know it is valid. - unsafe { - // Convert our weak reference into a strong reference - (*this.ptr.as_ptr()).strong.store(1, Release); - Arc::from_inner_in(this.ptr, alloc) - } - } - - #[cfg(not(no_global_oom_handling))] - fn weak_count(this: &Self) -> usize { - this.inner().weak.load(Acquire) - 1 - } - - #[cfg(not(no_global_oom_handling))] - fn inner(&self) -> &ArcInner { - // SAFETY: while this UniqueArc is alive we're guaranteed that the inner pointer is valid. - unsafe { self.ptr.as_ref() } - } - - fn as_ptr(this: &Self) -> *const T { - let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); - - // SAFETY: This cannot go through Deref::deref or UniqueArc::inner because - // this is required to retain raw/mut provenance such that e.g. `get_mut` can - // write through the pointer after the Rc is recovered through `from_raw`. - unsafe { &raw mut (*ptr).data } - } - - #[inline] - fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { - let this = mem::ManuallyDrop::new(this); - // SAFETY: Pointer is valid for reads and only read once. - (this.ptr, unsafe { ptr::read(&this.alloc) }) - } - - #[inline] - unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { - Self { ptr, _marker: PhantomData, _marker2: PhantomData, alloc } - } -} - -impl UniqueArc { - /// Creates a new weak reference to the `UniqueArc`. - /// - /// Attempting to upgrade this weak reference will fail before the `UniqueArc` has been converted - /// to a [`Arc`] using [`UniqueArc::into_arc`]. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - #[must_use] - pub fn downgrade(this: &Self) -> Weak { - // Using a relaxed ordering is alright here, as knowledge of the - // original reference prevents other threads from erroneously deleting - // the object or converting the object to a normal `Arc`. - // - // Note that we don't need to test if the weak counter is locked because there - // are no such operations like `Arc::get_mut` or `Arc::make_mut` that will lock - // the weak counter. - // - // SAFETY: This pointer was allocated at creation time so we know it is valid. - let old_size = unsafe { (*this.ptr.as_ptr()).weak.fetch_add(1, Relaxed) }; - - // See comments in Arc::clone() for why we do this (for mem::forget). - if old_size > MAX_REFCOUNT { - abort(); - } - - Weak { ptr: this.ptr, alloc: this.alloc.clone() } - } -} - -impl UniqueArc, A> { - /// Writes the value and converts to `UniqueArc`. - /// - /// This method converts similarly to [`assume_init`](Self::assume_init) but - /// writes `value` into it before conversion, thus guaranteeing safety. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - #[must_use] - pub fn write(mut this: Self, value: T) -> UniqueArc { - // SAFETY: Writing initialises the wrapped value. - unsafe { - this.write(value); - this.assume_init() - } - } - - /// Converts to `UniqueArc`. - /// - /// # Safety - /// - /// As with [`MaybeUninit::assume_init`], - /// it is up to the caller to guarantee that the value - /// really is in an initialized state. - /// Calling this when the content is not yet fully initialized - /// causes immediate undefined behavior. - /// - /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init - #[unstable(feature = "unique_rc_arc", issue = "112566")] - #[must_use] - pub unsafe fn assume_init(self) -> UniqueArc { - let (ptr, alloc) = UniqueArc::into_inner_with_allocator(self); - // SAFETY: Upheld by caller. - unsafe { UniqueArc::from_inner_in(ptr.cast(), alloc) } - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl Deref for UniqueArc { - type Target = T; - - fn deref(&self) -> &T { - // SAFETY: This pointer was allocated at creation time so we know it is valid. - unsafe { &self.ptr.as_ref().data } - } -} - -// #[unstable(feature = "unique_rc_arc", issue = "112566")] -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl PinSafePointer for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -impl DerefMut for UniqueArc { - fn deref_mut(&mut self) -> &mut T { - // SAFETY: This pointer was allocated at creation time so we know it is valid. We know we - // have unique ownership and therefore it's safe to make a mutable reference because - // `UniqueArc` owns the only strong reference to itself. - // We also need to be careful to only create a mutable reference to the `data` field, - // as a mutable reference to the entire `ArcInner` would assert uniqueness over the - // ref count fields too, invalidating any attempt by `Weak`s to access the ref count. - unsafe { &mut (*self.ptr.as_ptr()).data } - } -} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -// #[unstable(feature = "deref_pure_trait", issue = "87121")] -unsafe impl DerefPure for UniqueArc {} - -#[unstable(feature = "unique_rc_arc", issue = "112566")] -unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueArc { - fn drop(&mut self) { - // See `Arc::drop_slow` which drops an `Arc` with a strong count of 0. - // SAFETY: This pointer was allocated at creation time so we know it is valid. - let _weak = Weak { ptr: self.ptr, alloc: &self.alloc }; - - // ignore-tidy-undocumented-unsafe - unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; - } -} - -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] -unsafe impl Allocator for Arc { - #[inline] - fn allocate(&self, layout: Layout) -> Result, AllocError> { - (**self).allocate(layout) - } - - #[inline] - fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { - (**self).allocate_zeroed(layout) - } - - #[inline] - unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).deallocate(ptr, layout) } - } - - #[inline] - unsafe fn grow( - &self, - ptr: NonNull, - old_layout: Layout, - new_layout: Layout, - ) -> Result, AllocError> { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).grow(ptr, old_layout, new_layout) } - } - - #[inline] - unsafe fn grow_zeroed( - &self, - ptr: NonNull, - old_layout: Layout, - new_layout: Layout, - ) -> Result, AllocError> { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) } - } - - #[inline] - unsafe fn shrink( - &self, - ptr: NonNull, - old_layout: Layout, - new_layout: Layout, - ) -> Result, AllocError> { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).shrink(ptr, old_layout, new_layout) } - } -} - -#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] -unsafe impl AllocatorClone for Arc {} +pub use crate::rcs::arc::UniqueArc; +#[stable(feature = "rust1", since = "1.0.0")] +pub use crate::rcs::arc::{Arc, Weak}; diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis index b56f6f5800eee..c8e143b49911b 100644 --- a/src/etc/natvis/liballoc.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -72,7 +72,7 @@ it is necessary for them. --> - + {ptr.pointer->value} @@ -87,7 +87,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length @@ -102,7 +102,7 @@ - + {ptr.pointer->value} @@ -117,7 +117,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length @@ -131,7 +131,7 @@ - + {ptr.pointer->data} @@ -146,7 +146,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length @@ -160,7 +160,7 @@ - + {ptr.pointer->data} @@ -175,7 +175,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length diff --git a/src/tools/miri/tests/fail/memleak_rc.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr index a77cf55b0c317..26156050ae5d3 100644 --- a/src/tools/miri/tests/fail/memleak_rc.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -1,5 +1,5 @@ error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: - --> RUSTLIB/alloc/src/rc.rs:LL:CC + --> RUSTLIB/alloc/src/rcs/rc.rs:LL:CC | LL | Self::from_inner(Box::into_non_null(Box::new(RcInner { | _________________________________________________^ @@ -11,7 +11,7 @@ LL | | }))) | = note: stack backtrace: 0: std::rc::Rc::>>::new - at RUSTLIB/alloc/src/rc.rs:LL:CC + at RUSTLIB/alloc/src/rcs/rc.rs:LL:CC 1: main at tests/fail/memleak_rc.rs:LL:CC diff --git a/tests/codegen-llvm/debuginfo-cyclic-structure.rs b/tests/codegen-llvm/debuginfo-cyclic-structure.rs index b8cc544774158..dc7193dd08ed2 100644 --- a/tests/codegen-llvm/debuginfo-cyclic-structure.rs +++ b/tests/codegen-llvm/debuginfo-cyclic-structure.rs @@ -3,7 +3,7 @@ // Check that debug information exists for structures containing loops (cyclic references). // Previously it may incorrectly prune member information during recursive type inference check. -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Arc Arc<[u64]> { // CHECK-LABEL: @new_uninit #[no_mangle] pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> { - // CHECK: call alloc::sync::arcinner_layout_for_value_layout - // CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout + // CHECK: call alloc::rcs::arc::arcinner_layout_for_value_layout + // CHECK-NOT: call alloc::rcs::arc::arcinner_layout_for_value_layout let mut arc = Arc::new_uninit(); unsafe { Arc::get_mut_unchecked(&mut arc) }.write([x; 1000]); unsafe { arc.assume_init() } @@ -30,8 +30,8 @@ pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> { // CHECK-LABEL: @new_uninit_slice #[no_mangle] pub fn new_uninit_slice(x: u64) -> Arc<[u64]> { - // CHECK: call alloc::sync::arcinner_layout_for_value_layout - // CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout + // CHECK: call alloc::rcs::arc::arcinner_layout_for_value_layout + // CHECK-NOT: call alloc::rcs::arc::arcinner_layout_for_value_layout let mut arc = Arc::new_uninit_slice(1000); for elem in unsafe { Arc::get_mut_unchecked(&mut arc) } { elem.write(x); diff --git a/tests/debuginfo/rc_arc.rs b/tests/debuginfo/rc_arc.rs index b22b7e0d1611d..3ac8e647f2629 100644 --- a/tests/debuginfo/rc_arc.rs +++ b/tests/debuginfo/rc_arc.rs @@ -27,37 +27,37 @@ //@ cdb-command:g //@ cdb-command:dx rc,d -//@ cdb-check:rc,d : 111 [Type: alloc::rc::Rc] +//@ cdb-check:rc,d : 111 [Type: alloc::rcs::rc::Rc] //@ cdb-check: [Reference count] : 11 [Type: core::cell::Cell] //@ cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] //@ cdb-command:dx weak_rc,d -//@ cdb-check:weak_rc,d : 111 [Type: alloc::rc::Weak] +//@ cdb-check:weak_rc,d : 111 [Type: alloc::rcs::rc::Weak] //@ cdb-check: [Reference count] : 11 [Type: core::cell::Cell] //@ cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] //@ cdb-command:dx arc,d -//@ cdb-check:arc,d : 222 [Type: alloc::sync::Arc] +//@ cdb-check:arc,d : 222 [Type: alloc::rcs::arc::Arc] //@ cdb-check: [Reference count] : 21 [Type: core::sync::atomic::Atomic] //@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx weak_arc,d -//@ cdb-check:weak_arc,d : 222 [Type: alloc::sync::Weak] +//@ cdb-check:weak_arc,d : 222 [Type: alloc::rcs::arc::Weak] //@ cdb-check: [Reference count] : 21 [Type: core::sync::atomic::Atomic] //@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx dyn_rc,d -//@ cdb-check:dyn_rc,d [Type: alloc::rc::Rc,alloc::alloc::Global>] +//@ cdb-check:dyn_rc,d [Type: alloc::rcs::rc::Rc,alloc::alloc::Global>] //@ cdb-check: [Reference count] : 31 [Type: core::cell::Cell] //@ cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] //@ cdb-command:dx dyn_rc_weak,d -//@ cdb-check:dyn_rc_weak,d [Type: alloc::rc::Weak,alloc::alloc::Global>] +//@ cdb-check:dyn_rc_weak,d [Type: alloc::rcs::rc::Weak,alloc::alloc::Global>] //@ cdb-check: [Reference count] : 31 [Type: core::cell::Cell] //@ cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] //@ cdb-command:dx slice_rc,d -//@ cdb-check:slice_rc,d : { len=3 } [Type: alloc::rc::Rc,alloc::alloc::Global>] +//@ cdb-check:slice_rc,d : { len=3 } [Type: alloc::rcs::rc::Rc,alloc::alloc::Global>] //@ cdb-check: [Length] : 3 [Type: [...]] //@ cdb-check: [Reference count] : 41 [Type: core::cell::Cell] //@ cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] @@ -66,7 +66,7 @@ //@ cdb-check: [2] : 3 [Type: u32] //@ cdb-command:dx slice_rc_weak,d -//@ cdb-check:slice_rc_weak,d : { len=3 } [Type: alloc::rc::Weak,alloc::alloc::Global>] +//@ cdb-check:slice_rc_weak,d : { len=3 } [Type: alloc::rcs::rc::Weak,alloc::alloc::Global>] //@ cdb-check: [Length] : 3 [Type: [...]] //@ cdb-check: [Reference count] : 41 [Type: core::cell::Cell] //@ cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] @@ -75,17 +75,17 @@ //@ cdb-check: [2] : 3 [Type: u32] //@ cdb-command:dx dyn_arc,d -//@ cdb-check:dyn_arc,d [Type: alloc::sync::Arc,alloc::alloc::Global>] +//@ cdb-check:dyn_arc,d [Type: alloc::rcs::arc::Arc,alloc::alloc::Global>] //@ cdb-check: [Reference count] : 51 [Type: core::sync::atomic::Atomic] //@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx dyn_arc_weak,d -//@ cdb-check:dyn_arc_weak,d [Type: alloc::sync::Weak,alloc::alloc::Global>] +//@ cdb-check:dyn_arc_weak,d [Type: alloc::rcs::arc::Weak,alloc::alloc::Global>] //@ cdb-check: [Reference count] : 51 [Type: core::sync::atomic::Atomic] //@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx slice_arc,d -//@ cdb-check:slice_arc,d : { len=3 } [Type: alloc::sync::Arc,alloc::alloc::Global>] +//@ cdb-check:slice_arc,d : { len=3 } [Type: alloc::rcs::arc::Arc,alloc::alloc::Global>] //@ cdb-check: [Length] : 3 [Type: [...]] //@ cdb-check: [Reference count] : 61 [Type: core::sync::atomic::Atomic] //@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] @@ -94,7 +94,7 @@ //@ cdb-check: [2] : 6 [Type: u32] //@ cdb-command:dx slice_arc_weak,d -//@ cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak,alloc::alloc::Global>] +//@ cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::rcs::arc::Weak,alloc::alloc::Global>] //@ cdb-check: [Length] : 3 [Type: [...]] //@ cdb-check: [Reference count] : 61 [Type: core::sync::atomic::Atomic] //@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] diff --git a/tests/debuginfo/strings-and-strs.rs b/tests/debuginfo/strings-and-strs.rs index 4ad61e29d3ec0..d0c76698c789c 100644 --- a/tests/debuginfo/strings-and-strs.rs +++ b/tests/debuginfo/strings-and-strs.rs @@ -20,13 +20,13 @@ //@ gdb-check:$4 = ("Hello", "World") //@ gdb-command:print str_in_rc -//@ gdb-check:$5 = alloc::rc::Rc<&str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull> {pointer: 0x[...]}, phantom: core::marker::PhantomData>, alloc: alloc::alloc::Global} +//@ gdb-check:$5 = alloc::rcs::rc::Rc<&str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull> {pointer: 0x[...]}, phantom: core::marker::PhantomData>, alloc: alloc::alloc::Global} //@ gdb-command:print box_str //@ gdb-check:$6 = alloc::boxed::Box [87, 111, 114, 108, 100] //@ gdb-command:print rc_str -//@ gdb-check:$7 = alloc::rc::Rc {ptr: core::ptr::non_null::NonNull> {pointer: alloc::rc::RcInner {strong: core::cell::Cell {value: core::cell::UnsafeCell {value: 1}}, weak: core::cell::Cell {value: core::cell::UnsafeCell {value: 1}}, value: 0x[...]}}, phantom: core::marker::PhantomData>, alloc: alloc::alloc::Global} +//@ gdb-check:$7 = alloc::rcs::rc::Rc {ptr: core::ptr::non_null::NonNull> {pointer: alloc::rcs::rc::RcInner {strong: core::cell::Cell {value: core::cell::UnsafeCell {value: 1}}, weak: core::cell::Cell {value: core::cell::UnsafeCell {value: 1}}, value: 0x[...]}}, phantom: core::marker::PhantomData>, alloc: alloc::alloc::Global} // === LLDB TESTS ================================================================================== //@ lldb-command:run @@ -56,7 +56,7 @@ // lldb-command:v rc_str // ignore-tidy-linelength -// lldb-check:(alloc::rc::Rc) rc_str = strong=1, weak=0 { value = "World" } +// lldb-check:(alloc::rcs::rc::Rc) rc_str = strong=1, weak=0 { value = "World" } #![allow(unused_variables)] diff --git a/tests/debuginfo/thread.rs b/tests/debuginfo/thread.rs index d78dad406ac6e..ee33f921cc033 100644 --- a/tests/debuginfo/thread.rs +++ b/tests/debuginfo/thread.rs @@ -14,7 +14,7 @@ // //@ cdb-command:dx t,d //@ cdb-check:t,d : [...] [Type: std::thread::thread::Thread *] -//@ cdb-check:[...] inner [...][Type: core::pin::Pin >] +//@ cdb-check:[...] inner [...][Type: core::pin::Pin >] use std::thread; diff --git a/tests/ui/lint/runtime-symbols-unix.stderr b/tests/ui/lint/runtime-symbols-unix.stderr index a1d036b95683c..18a6f34fa11cb 100644 --- a/tests/ui/lint/runtime-symbols-unix.stderr +++ b/tests/ui/lint/runtime-symbols-unix.stderr @@ -5,7 +5,7 @@ LL | pub fn open() {} | ^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const U8, i32, ...) -> i32` (for the current target) - found `fn()` + found `fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "open")]`, or `#[link_name = "open"]` = note: `#[deny(invalid_runtime_symbol_definitions)]` on by default @@ -16,7 +16,7 @@ LL | pub fn read(); | ^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32, *mut c_void, usize) -> isize` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "read")]`, or `#[link_name = "read"]` error: invalid definition of the runtime `write` symbol used by the standard library @@ -26,7 +26,7 @@ LL | pub fn write(); | ^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32, *const c_void, usize) -> isize` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "write")]`, or `#[link_name = "write"]` error: invalid definition of the runtime `close` symbol used by the standard library @@ -36,7 +36,7 @@ LL | pub static close: () = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32) -> i32` (for the current target) - found `()` + found `()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "close")]`, or `#[link_name = "close"]` error: invalid definition of the runtime `malloc` symbol used by the standard library @@ -46,7 +46,7 @@ LL | pub fn malloc(); | ^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(usize) -> *mut c_void` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "malloc")]`, or `#[link_name = "malloc"]` error: invalid definition of the runtime `realloc` symbol used by the standard library @@ -56,7 +56,7 @@ LL | pub fn realloc(); | ^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "realloc")]`, or `#[link_name = "realloc"]` error: invalid definition of the runtime `free` symbol used by the standard library @@ -66,7 +66,7 @@ LL | pub fn free(); | ^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void)` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "free")]`, or `#[link_name = "free"]` error: invalid definition of the runtime `exit` symbol used by the standard library @@ -76,7 +76,7 @@ LL | pub fn exit(); | ^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32) -> !` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "exit")]`, or `#[link_name = "exit"]` warning: suspicious definition of the runtime `open` symbol used by the standard library @@ -86,7 +86,7 @@ LL | pub fn open(path: *const U8, oflag: usize, ...) -> c_int; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const U8, i32, ...) -> i32` (for the current target) - found `unsafe extern "C" fn(*const U8, usize, ...) -> i32` + found `unsafe extern "C" fn(*const U8, usize, ...) -> i32` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "open")]`, or `#[link_name = "open"]` = help: allow this lint if the signature is compatible = note: `#[warn(suspicious_runtime_symbol_definitions)]` on by default @@ -98,7 +98,7 @@ LL | pub fn free(ptr: *const U8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void)` (for the current target) - found `unsafe extern "C" fn(*const U8)` + found `unsafe extern "C" fn(*const U8)` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "free")]`, or `#[link_name = "free"]` = help: allow this lint if the signature is compatible @@ -109,7 +109,7 @@ LL | pub fn exit(code: f32) -> !; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32) -> !` (for the current target) - found `unsafe extern "C" fn(f32) -> !` + found `unsafe extern "C" fn(f32) -> !` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "exit")]`, or `#[link_name = "exit"]` = help: allow this lint if the signature is compatible @@ -120,7 +120,7 @@ LL | pub static exit2: Option !>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32) -> !` (for the current target) - found `unsafe extern "C" fn(f32) -> !` + found `unsafe extern "C" fn(f32) -> !` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "exit")]`, or `#[link_name = "exit"]` = help: allow this lint if the signature is compatible @@ -131,7 +131,7 @@ LL | pub fn exit3(code: i32) -> i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32) -> !` (for the current target) - found `unsafe extern "C" fn(i32) -> i32` + found `unsafe extern "C" fn(i32) -> i32` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "exit")]`, or `#[link_name = "exit"]` = help: allow this lint if the signature is compatible @@ -142,7 +142,7 @@ LL | pub fn exit4(code: i32); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(i32) -> !` (for the current target) - found `unsafe extern "C" fn(i32)` + found `unsafe extern "C" fn(i32)` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "exit")]`, or `#[link_name = "exit"]` = help: allow this lint if the signature is compatible diff --git a/tests/ui/lint/runtime-symbols.stderr b/tests/ui/lint/runtime-symbols.stderr index 0de419a684ba2..2ba5f6723797b 100644 --- a/tests/ui/lint/runtime-symbols.stderr +++ b/tests/ui/lint/runtime-symbols.stderr @@ -5,7 +5,7 @@ LL | pub fn memmove() {} | ^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, *const c_void, usize) -> *mut c_void` (for the current target) - found `fn()` + found `fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memmove")]`, or `#[link_name = "memmove"]` = note: `#[deny(invalid_runtime_symbol_definitions)]` on by default @@ -16,7 +16,7 @@ LL | pub fn memset(); | ^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, i32, usize) -> *mut c_void` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memset")]`, or `#[link_name = "memset"]` error: invalid definition of the runtime `memcmp` symbol used by the standard library @@ -26,7 +26,7 @@ LL | pub fn memcmp(); | ^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32` (for the current target) - found `unsafe extern "C" fn()` + found `unsafe extern "C" fn()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memcmp")]`, or `#[link_name = "memcmp"]` error: invalid definition of the runtime `strlen` symbol used by the standard library @@ -36,7 +36,7 @@ LL | pub static strlen: () = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const U8) -> usize` (for the current target) - found `()` + found `()` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "strlen")]`, or `#[link_name = "strlen"]` error: invalid definition of the runtime `strlen` symbol used by the standard library @@ -46,7 +46,7 @@ LL | static strlen2: Option; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const U8) -> usize` (for the current target) - found `unsafe extern "C" fn(*const U8)` + found `unsafe extern "C" fn(*const U8)` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "strlen")]`, or `#[link_name = "strlen"]` error: invalid definition of the runtime `memcpy` symbol used by the standard library @@ -56,7 +56,7 @@ LL | pub fn memcpy(dest: *mut c_void, src: *const c_void, n: usize) -> *mut | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, *const c_void, usize) -> *mut c_void` (for the current target) - found `fn(*mut c_void, *const c_void, usize) -> *mut c_void` + found `fn(*mut c_void, *const c_void, usize) -> *mut c_void` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memcpy")]`, or `#[link_name = "memcpy"]` error: invalid definition of the runtime `bcmp` symbol used by the standard library @@ -66,7 +66,7 @@ LL | pub unsafe extern "C" fn bcmp(s1: *const c_void, s2: *const c_void, n: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32` (for the current target) - found `unsafe extern "C" fn(*const c_void, *const c_void, usize, ...) -> i32` + found `unsafe extern "C" fn(*const c_void, *const c_void, usize, ...) -> i32` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "bcmp")]`, or `#[link_name = "bcmp"]` error: invalid definition of the runtime `bcmp` symbol used by the standard library @@ -76,7 +76,7 @@ LL | pub extern "C" fn bcmp_(s1: *const c_void, s2: *const c_void, n: usize) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32` (for the current target) - found `extern "C" fn(*const c_void, *const c_void, usize)` + found `extern "C" fn(*const c_void, *const c_void, usize)` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "bcmp")]`, or `#[link_name = "bcmp"]` warning: suspicious definition of the runtime `memcpy` symbol used by the standard library @@ -86,7 +86,7 @@ LL | pub extern "C" fn memcpy(dest: *mut c_void, src: *const c_void, n: i64) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, *const c_void, usize) -> *mut c_void` (for the current target) - found `extern "C" fn(*mut c_void, *const c_void, i64) -> *mut c_void` + found `extern "C" fn(*mut c_void, *const c_void, i64) -> *mut c_void` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memcpy")]`, or `#[link_name = "memcpy"]` = help: allow this lint if the signature is compatible = note: `#[warn(suspicious_runtime_symbol_definitions)]` on by default @@ -98,7 +98,7 @@ LL | pub extern "C" fn memmove(dest: *mut c_void, src: *const c_void, n: i64 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, *const c_void, usize) -> *mut c_void` (for the current target) - found `extern "C" fn(*mut c_void, *const c_void, i64) -> *mut c_void` + found `extern "C" fn(*mut c_void, *const c_void, i64) -> *mut c_void` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memmove")]`, or `#[link_name = "memmove"]` = help: allow this lint if the signature is compatible @@ -109,7 +109,7 @@ LL | fn memset(s: *mut c_void, c: c_int, n: usize) -> f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*mut c_void, i32, usize) -> *mut c_void` (for the current target) - found `unsafe extern "C" fn(*mut c_void, i32, usize) -> f64` + found `unsafe extern "C" fn(*mut c_void, i32, usize) -> f64` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memset")]`, or `#[link_name = "memset"]` = help: allow this lint if the signature is compatible @@ -120,7 +120,7 @@ LL | pub extern "C" fn bcmp_(s1: *const U8, s2: *const U8, n: usize) -> c_in | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32` (for the current target) - found `extern "C" fn(*const U8, *const U8, usize) -> i32` + found `extern "C" fn(*const U8, *const U8, usize) -> i32` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "bcmp")]`, or `#[link_name = "bcmp"]` = help: allow this lint if the signature is compatible @@ -131,7 +131,7 @@ LL | pub extern "C" fn strlen(s: *const u64) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected `unsafe extern "C" fn(*const U8) -> usize` (for the current target) - found `extern "C" fn(*const u64) -> usize` + found `extern "C" fn(*const u64) -> usize` = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "strlen")]`, or `#[link_name = "strlen"]` = help: allow this lint if the signature is compatible diff --git a/tests/ui/methods/shadowed-intrinsic-method-deref.stderr b/tests/ui/methods/shadowed-intrinsic-method-deref.stderr index 4e0c5dfc55f09..d4dccd6dc5fdb 100644 --- a/tests/ui/methods/shadowed-intrinsic-method-deref.stderr +++ b/tests/ui/methods/shadowed-intrinsic-method-deref.stderr @@ -6,7 +6,7 @@ LL | let sb : &S = &s.borrow(); | help: the trait `Borrow` is not implemented for `Rc>` but trait `Borrow>` is implemented for it - --> $SRC_DIR/alloc/src/rc.rs:LL:COL + --> $SRC_DIR/alloc/src/rcs/rc.rs:LL:COL = help: for that trait implementation, expected `RefCell`, found `S` = note: there's an inherent method on `RefCell` of the same name, which can be auto-dereferenced from `&RefCell` help: to access the inherent method on `RefCell`, use the fully-qualified path