/// let five = Arc::clone(&five);
///
/// thread::spawn(move || {
-/// println!("{:?}", five);
+/// println!("{five:?}");
/// });
/// }
/// ```
///
/// thread::spawn(move || {
/// let v = val.fetch_add(1, Ordering::SeqCst);
-/// println!("{:?}", v);
+/// println!("{v:?}");
/// });
/// }
/// ```
unsafe { Self::from_inner(Box::leak(x).into()) }
}
- /// Constructs a new `Arc<T>` using a closure `data_fn` that has access to
- /// a weak reference to the constructing `Arc<T>`.
+ /// Constructs a new `Arc<T>` while giving you a `Weak<T>` 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 prevent a memory leak.
- /// In `data_fn`, initialization of `T` can make use of the weak reference
- /// by cloning and storing it inside `T` for use at a later time.
+ /// 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<T>` is created, such that you can
+ /// clone and store it inside the `T`.
///
- /// Since the new `Arc<T>` is not fully-constructed until
- /// `Arc<T>::new_cyclic` returns, calling [`upgrade`] on the weak
- /// reference inside `data_fn` will fail and result in a `None` value.
+ /// `new_cyclic` first allocates the managed allocation for the `Arc<T>`,
+ /// then calls your closure, giving it a `Weak<T>` to this allocation,
+ /// and only afterwards completes the construction of the `Arc<T>` by placing
+ /// the `T` returned from your closure into the allocation.
+ ///
+ /// Since the new `Arc<T>` is not fully-constructed until `Arc<T>::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<T>`] is dropped normally.
///
/// # Example
+ ///
/// ```
- /// #![allow(dead_code)]
+ /// # #![allow(dead_code)]
/// use std::sync::{Arc, Weak};
///
/// struct Gadget {
/// impl Gadget {
/// /// Construct a reference counted Gadget.
/// fn new() -> Arc<Self> {
- /// Arc::new_cyclic(|me| Gadget { me: me.clone() })
+ /// // `me` is a `Weak<Gadget>` pointing at the new allocation of the
+ /// // `Arc` we're constructing.
+ /// Arc::new_cyclic(|me| {
+ /// // Create the actual struct here.
+ /// Gadget { me: me.clone() }
+ /// })
/// }
///
/// /// Return a reference counted pointer to Self.
let offset = data_offset(ptr);
// Reverse the offset to find the original ArcInner.
- let arc_ptr = (ptr as *mut ArcInner<T>).set_ptr_value((ptr as *mut u8).offset(-offset));
+ let arc_ptr =
+ (ptr as *mut u8).offset(-offset).with_metadata_of(ptr as *mut ArcInner<T>);
Self::from_ptr(arc_ptr)
}
Self::allocate_for_layout(
Layout::for_value(&*ptr),
|layout| Global.allocate(layout),
- |mem| (ptr as *mut ArcInner<T>).set_ptr_value(mem) as *mut ArcInner<T>,
+ |mem| mem.with_metadata_of(ptr as *mut ArcInner<T>),
)
}
}
/// assert!(empty.upgrade().is_none());
/// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")]
+ #[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")]
#[must_use]
- pub fn new() -> Weak<T> {
- Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner<T>).expect("MAX is not 0") }
+ pub const fn new() -> Weak<T> {
+ Weak { ptr: unsafe { NonNull::new_unchecked(ptr::invalid_mut::<ArcInner<T>>(usize::MAX)) } }
}
}
let offset = unsafe { data_offset(ptr) };
// Thus, we reverse the offset to get the whole RcBox.
// SAFETY: the pointer originated from a Weak, so this offset is safe.
- unsafe { (ptr as *mut ArcInner<T>).set_ptr_value((ptr as *mut u8).offset(-offset)) }
+ unsafe { (ptr as *mut u8).offset(-offset).with_metadata_of(ptr as *mut ArcInner<T>) }
};
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
}
}
+#[stable(feature = "shared_from_str", since = "1.62.0")]
+impl From<Arc<str>> for Arc<[u8]> {
+ /// Converts an atomically reference-counted string slice into a byte slice.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use std::sync::Arc;
+ /// let string: Arc<str> = Arc::from("eggplant");
+ /// let bytes: Arc<[u8]> = Arc::from(string);
+ /// assert_eq!("eggplant".as_bytes(), bytes.as_ref());
+ /// ```
+ #[inline]
+ fn from(rc: Arc<str>) -> 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<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]> {
type Error = Arc<[T]>;