Arc::increment_strong_count design question (cross-post)

⚓ Rust    📅 2026-04-22    👤 surdeus    👁️ 2      

surdeus

Cross-post: This is a cross-post from internals forum. Since it got no replies for a week I think it is safe to cross-post it here, as there will be no discussion overlap.


I was reading docs of Arc::increment_strong_count and in the safety section I found requirement that raw pointer passed to the function must point to valid allocation created by global allocator.

The pointer must have been obtained through Arc::into_raw and must satisfy the same layout requirements specified in Arc::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.

This requirement surprised me, so I looked into implementation and after going though Arc::increment_strong_count_in layer I found that the implementation basically just creates Arc from raw pointer and clones it:

// Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
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();

Why does the implementation of Arc::increment_strong_count simply not walk pointers and increment strong count directly? Requiring alloc to be passed into Arc::increment_strong_count seams overly constraining, since at no point the allocator is used at all.

I understand why Arc::decrement_strong_count needs access to the allocator, as it needs to drop inner T and ArcInner when strong and weak counters go to 0. Was Arc::increment_strong_count designed in such way to keep symmetry with decrementing part? Or is there some safety invariant that I do not see, that would be violated if Arc::increment_strong_count would call fetch_add on the strong counter directly?

2 posts - 2 participants

Read full topic

🏷️ Rust_feed