Rollup merge of #137641 - kpreid:dealloc, r=Amanieu

More precisely document `Global::deallocate()`'s safety.

There is a subtlety which "other conditions must be upheld by the caller" does not capture: `GlobalAlloc`/`alloc::dealloc()` require that the provided layout will be *equal*, not just that it "fits", the layout used to allocate. This is always true here due to how `allocate()`, `grow()`, and `shrink()` are implemented (they never return a larger allocation than requested), but that is a non-local property of the implementation, so it should be documented explicitly.

r? libs

`@rustbot` label A-allocators
This commit is contained in:
Matthias Krüger 2025-03-02 22:44:24 +01:00 committed by GitHub
commit e8134a3380
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -264,8 +264,14 @@ unsafe impl Allocator for Global {
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
if layout.size() != 0 {
// SAFETY: `layout` is non-zero in size,
// other conditions must be upheld by the caller
// SAFETY:
// * We have checked that `layout` is non-zero in size.
// * The caller is obligated to provide a layout that "fits", and in this case,
// "fit" always means a layout that is equal to the original, because our
// `allocate()`, `grow()`, and `shrink()` implementations never returns a larger
// allocation than requested.
// * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s
// safety documentation.
unsafe { dealloc(ptr.as_ptr(), layout) }
}
}