Skip to content

alloc: stabilise Allocator#156882

Draft
nia-e wants to merge 2 commits into
rust-lang:mainfrom
nia-e:stable-allocator
Draft

alloc: stabilise Allocator#156882
nia-e wants to merge 2 commits into
rust-lang:mainfrom
nia-e:stable-allocator

Conversation

@nia-e

@nia-e nia-e commented May 24, 2026

Copy link
Copy Markdown
Member

View all comments

Stabilise a bare-minimum (dyn-incompatible, but could be in the future) Allocator trait, alongside Box::new_in(), Vec::new_in(), the System & Global Allocators, and a blanket impl of Allocator for T: GlobalAlloc. For now, we should take care not to make it possible to instantiate anything other than a Vec or Box with custom allocators; it's Probably Fine, but worth a proper look before we rush in.

The soundness requirements for implementors were tightened to the most restrictive ones we could reasonably want per a conversation with @RalfJung.

This was discussed extensively at the all-hands with an apparent tentative consensus from libs and participating ecosystem stakeholders that the current design can be extended backwards-compatibly to address almost all usecases.

cc @rust-lang/libs @rust-lang/libs-api @rust-lang/opsem

r? libs


Edit, following more points being discovered: see the new stabilisation report

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 24, 2026
@nia-e nia-e added A-allocators Area: Custom and system allocators relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. labels May 24, 2026
@nia-e nia-e added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. and removed S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. labels May 24, 2026
@nia-e

nia-e commented May 24, 2026

Copy link
Copy Markdown
Member Author

r? @Amanieu

@rustbot rustbot assigned Amanieu and unassigned Mark-Simulacrum May 24, 2026
@rust-log-analyzer

This comment has been minimized.

Comment thread library/core/src/alloc/mod.rs Outdated
@nia-e
nia-e force-pushed the stable-allocator branch from ecf76bf to ed24b36 Compare May 24, 2026 17:42
Comment thread library/alloc/src/collections/binary_heap/mod.rs Outdated
Comment thread library/core/src/alloc/mod.rs Outdated
Comment thread library/core/src/alloc/global.rs Outdated
Comment thread tests/ui/allocator/not-an-allocator.u.stderr Outdated
Comment thread library/core/src/alloc/global.rs Outdated
Comment thread library/core/src/alloc/mod.rs Outdated
@theemathas

Copy link
Copy Markdown
Contributor

I believe the safety requirements are not yet correct. See #156544

@jmillikin

This comment has been minimized.

@bushrat011899

This comment has been minimized.

@jmillikin

This comment has been minimized.

@bushrat011899

This comment has been minimized.

@jmillikin

This comment has been minimized.

@bushrat011899

This comment has been minimized.

@joshtriplett

This comment was marked as outdated.

@rust-rfcbot

This comment was marked as outdated.

@nia-e

nia-e commented Jun 1, 2026

Copy link
Copy Markdown
Member Author

Given the feedback here & on Zulip, the new design for allocator_api probably needs some time to bake & iron out soundness bugs. I'll be keeping the previous document up-to-date w/ any changes or updates, but it likely makes sense to first land these changes unstably and then see if it holds up to scrutiny. I do think something could be stabilised soon-ish, but there won't be any harm in waiting a bit ^^

edit: the conversation will mainly continue on zulip and on the issues filed in response to this PR; if you have concerns not yet addressed, please ping me there and i'll happily look into seeing if the design can be adapted

@rustbot author

@nia-e nia-e removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jun 1, 2026
@nia-e
nia-e marked this pull request as draft June 1, 2026 10:51
@maxdexh

This comment was marked as off-topic.

@nia-e

This comment was marked as off-topic.

@rust-bors

rust-bors Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #157303) made this pull request unmergeable. Please resolve the merge conflicts.

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 8, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 8, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 8, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 8, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 9, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 9, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 9, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 10, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 10, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 10, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 11, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097 (rust-lang#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request Jul 12, 2026
allow `Allocator`s to be used as `#[global_allocator]`s

The (hopefully) immanent stabilisation of the `Allocator` trait raises the question of what is to be done about the older, already-stable `GlobalAlloc` trait. In my opinion, having two nearly-identical traits for the same purpose is needlessly confusing. Going forward, `Allocator` as the more modern interface should be _the_ allocator trait.

With `Allocator` being currently unstable, there is the possibility of implementing `GlobalAlloc` for all `Allocator`s, thereby allowing them to be used as `#[global_allocator]` and allowing crates to seamlessly (and semver-compatibly) switch to `Allocator`. However, unconditionally implementing `GlobalAlloc` presents a footgun to users, as e.g. using `Global` as `#[global_allocator]` will lead to infinite recursion. @nia-e initially tried to resolve this in e1b7097a8e36f9f3256f6a7972e2da8f1f2ca6d5 (rust-lang/rust#156882) by using weird trait trickery to implement `GlobalAlloc` for every allocator except `Global`. But this does not go far enough, e.g. a bump allocator that itself allocates from `Global` is similarly unsuitable as global allocator.

Thus, with this PR, I'd like to propose adding a new marker trait for allocators that can be used as `#[global_allocator]`:
```rust
// in core::alloc

trait GlobalAllocator: Allocator {}
```
`GlobalAlloc` can then be implemented for all `GlobalAllocator`s:
```rust
impl<A> GlobalAlloc for A
where
    A: GlobalAllocator
{
    /* ... */
}
```

This provides a backwards-compatible way for allocator libraries to switch to the new interface and allows deprecating `GlobalAlloc` (not done here). Over time, I expect that `GlobalAlloc` will become more and more of an implementation detail of the `#[global_allocator]` macro (for instance, one might add perma-unstable, hidden methods for things like `grow_zeroed` that are customised only by the blanket implementation).

With regards to naming, I chose `GlobalAllocator` to mirror `Allocator`. `GlobalAlloc` should probably be deprecated quickly after stabilising `GlobalAllocator` to avoid confusion. For the same reason, I think it'd be better to add `GlobalAllocator` before stabilising `Allocator` – but that is not a necessity.

r? @nia-e
@rustbot label +I-libs-api-nominated
@safinaskar

This comment was marked as off-topic.

@RalfJung

This comment was marked as off-topic.

@maxdexh

This comment was marked as off-topic.

@nia-e

This comment was marked as off-topic.

@safinaskar

This comment was marked as off-topic.

@nia-e

This comment was marked as off-topic.

@bushrat011899

This comment was marked as off-topic.

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

Labels

A-allocators Area: Custom and system allocators A-run-make Area: port run-make Makefiles to rmake.rs needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dyn Allocator together with Allocator + Clone requirements is unsound, leading to UB with Arc