Skip to content

Update documentation for Arc::from_raw, Arc::increment_strong_count, and Arc::decrement_strong_count to clarify allocator requirement#134496

Merged
bors merged 2 commits into
rust-lang:masterfrom
DiuDiu777:fix-doc
Jan 16, 2025
Merged

Conversation

@DiuDiu777

@DiuDiu777 DiuDiu777 commented Dec 19, 2024

Copy link
Copy Markdown
Contributor

Related Issue:

This update addresses parts of the issue raised in #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:

#![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!
    }
}

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants