Skip to content

Commit 87b3671

Browse files
authored
Rollup merge of #134496 - DiuDiu777:fix-doc, r=ibraheemdev
Update documentation for Arc::from_raw, Arc::increment_strong_count, and Arc::decrement_strong_count to clarify allocator requirement ### Related Issue: This update addresses parts of the issue raised in [#134242](#134242), where Arc's documentation lacks `Global Allocator` safety descriptions for three APIs. And this was confirmed by ```@workingjubilee``` : > Wait, nevermind. I apparently forgot the `increment_strong_count` is implicitly A = Global. Ugh. Another reason these things are hard to track, unfortunately. ### PR Description This PR updates the document for the following APIs: - `Arc::from_raw` - `Arc::increment_strong_count` - `Arc::decrement_strong_count` These APIs currently lack an important piece of documentation: **the raw pointer must point to a block of memory allocated by the global allocator**. This crucial detail is specified in the source code but is not reflected in the documentation, which could lead to confusion or incorrect usage by users. ### Problem: The following example demonstrates the potential confusion caused by the lack of documentation: ```rust #![feature(allocator_api)] use std::alloc::{Allocator,AllocError, Layout}; use std::ptr::NonNull; use std::sync::Arc; struct LocalAllocator { memory: NonNull<u8>, size: usize, } impl LocalAllocator { fn new(size: usize) -> Self { Self { memory: unsafe { NonNull::new_unchecked(&mut 0u8 as *mut u8) }, size, } } } unsafe impl Allocator for LocalAllocator { fn allocate(&self, _layout: Layout) -> Result<NonNull<[u8]>, AllocError> { Ok(NonNull::slice_from_raw_parts(self.memory, self.size)) } unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) { } } fn main() { let allocator = LocalAllocator::new(64); let arc = Arc::new_in(5, &allocator); // Here, allocator could be any non-global allocator let ptr = Arc::into_raw(arc); unsafe { Arc::increment_strong_count(ptr); let arc = Arc::from_raw(ptr); assert_eq!(2, Arc::strong_count(&arc)); // Failed here! } } ```
2 parents fca1481 + 48e671e commit 87b3671

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

library/alloc/src/sync.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,8 @@ impl<T: ?Sized> Arc<T> {
13971397
/// different types. See [`mem::transmute`][transmute] for more information
13981398
/// on what restrictions apply in this case.
13991399
///
1400+
/// The raw pointer must point to a block of memory allocated by the global allocator.
1401+
///
14001402
/// The user of `from_raw` has to make sure a specific value of `T` is only
14011403
/// dropped once.
14021404
///
@@ -1452,7 +1454,8 @@ impl<T: ?Sized> Arc<T> {
14521454
///
14531455
/// The pointer must have been obtained through `Arc::into_raw`, and the
14541456
/// associated `Arc` instance must be valid (i.e. the strong count must be at
1455-
/// least 1) for the duration of this method.
1457+
/// least 1) for the duration of this method, and `ptr` must point to a block of memory
1458+
/// allocated by the global allocator.
14561459
///
14571460
/// # Examples
14581461
///
@@ -1486,7 +1489,8 @@ impl<T: ?Sized> Arc<T> {
14861489
///
14871490
/// The pointer must have been obtained through `Arc::into_raw`, and the
14881491
/// associated `Arc` instance must be valid (i.e. the strong count must be at
1489-
/// least 1) when invoking this method. This method can be used to release the final
1492+
/// least 1) when invoking this method, and `ptr` must point to a block of memory
1493+
/// allocated by the global allocator. This method can be used to release the final
14901494
/// `Arc` and backing storage, but **should not** be called after the final `Arc` has been
14911495
/// released.
14921496
///

0 commit comments

Comments
 (0)