From 459726ca08109d1aeaf6718715e0fe584d67c770 Mon Sep 17 00:00:00 2001 From: Theemathas Chirananthavat Date: Wed, 13 May 2026 19:05:41 +0700 Subject: [PATCH] Add more safety requirements for `Allocator` impls An `Allocator` implementation is now allowed to invalidate its allocations when the allocator is mutated or when a lifetime in the allocator type expires. Mutation of an `Allocator` should sensibly be allowed to invalidate its allocations. For example, the `bumpalo` crates has a `Bump::reset` method that takes `&mut self` and invalidates all past allocations. Accesses via `&` still must not invalidate past allocations since, for example, `Box` provides `&` access to the allocator. The "lifetime expiry" clause closes a hole/ambiguity on when an allocator is considered to be "dropped" if it does not have a destructor. Additionally, this clause matches what is required for `Box::into_pin` and `{Rc, Arc}::pin` to be sound. (Those methods have an `A: 'static` bound to prevent allocating via a `&MyAllocator` and then running `MyAllocator`'s destructor.) --- library/core/src/alloc/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 18310cf98918d..095477fcb6853 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -91,8 +91,12 @@ impl fmt::Display for AllocError { /// /// Memory blocks that are [*currently allocated*] by an allocator, /// must point to valid memory, and retain their validity until either: -/// - the memory block is deallocated, or -/// - the allocator is dropped. +/// - the memory block is deallocated, +/// - the allocator is mutated through public API taking `&mut` access (notably, +/// running the allocator's destructor is such a mutation), or +/// - the allocator's type becomes invalid. +/// (For example, the type `&'a T` becomes invalid when `'a` expires. +/// More generally, a type becomes invalid when any of its lifetime parameters has expired.) /// /// Copying, cloning, or moving the allocator must not invalidate memory blocks returned from it. /// A copied or cloned allocator must behave like the original allocator.