Skip to content

Add String<A> type with custom allocator parameter#149328

Open
shua wants to merge 8 commits intorust-lang:mainfrom
shua:stralloc
Open

Add String<A> type with custom allocator parameter#149328
shua wants to merge 8 commits intorust-lang:mainfrom
shua:stralloc

Conversation

@shua
Copy link

@shua shua commented Nov 25, 2025

View all comments

This change is part of the allocator_api feature set #32838 (also see wg-allocators roadmap or libs-team ACP).
The previous attempts at adding an allocator parameter to string are at rust-lang/rust#101551, and rust-lang/rust#79500 (I think those authors should get much of the credit here, I am re-writing what they worked out in those threads).

workaround

There is a type inference ambiguity introduced when adding a generic parameter to a type which previously had none, even when that parameter has a default value (more details in rust-lang/rust#98931). I've done the same workaround as rust-lang/rust#101551, which is to make alloc::string::String a type alias to String<Global>, but I've arranged the modules a bit differently to make rebase/merges a bit easier.

This workaround unfortunately changes the type name of the String language item, and that would be user-facing in error or diagnostic output. I understand from this comment that this change is acceptable.

changes to existing API

Most of the methods on the original String have been implemented for the generic version instead. I don't foresee anything more moving from String<Global> to String<A>, as the remaining methods are all constructors which implicitly use the Global allocator.

There are three general types of changes:

  1. methods which don't allocate: here we just change impl Foo for String to impl<A: Allocator> Foo for String<A>
  2. converting to/from other allocator generic types like Vec<u8, A> and Box<str, A>: here we can use the existing allocator from those types.
  3. methods which clone from some other type with an allocator: here it's ambiguous whether the end result should be String<A>, String<Global>, or String<impl Allocator + Default>, etc; in general I try to leave these out of this change, but where some analogous change was made to Vec<T, A> I follow that.

new methods

Some methods have been added to String<A> which are not strictly necessary to land this change, but are considered helpful enough to users, and close enough to existing precedent in Vec<T, A>. Specifically, 4 new constructors (new_in, with_capacity_in, try_with_capacity_in, from_raw_parts_in), 1 destructor (into_raw_parts_with_alloc), and 1 getter (allocator). Technically, the updated from_utf8_unchecked should be sufficient for constructing, but we can add some safe constructors so users don't have to sully themselves.

not implemented

Variants of from_utf{8,16}* which internally allocate or use Cow have been punted on this PR, maybe a followup would make sense to either rewrite them, or add some *_in variant.

@rustbot
Copy link
Collaborator

rustbot commented Nov 25, 2025

The rustc-dev-guide subtree was changed. If this PR only touches the dev guide consider submitting a PR directly to rust-lang/rustc-dev-guide otherwise thank you for updating the dev guide with your changes.

cc @BoxyUwU, @jieyouxu, @Kobzol, @tshepang

This PR modifies tests/ui/issues/. If this PR is adding new tests to tests/ui/issues/,
please refrain from doing so, and instead add it to more descriptive subdirectories.

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead.

cc @rust-lang/rust-analyzer

@rustbot rustbot added A-rustc-dev-guide Area: rustc-dev-guide A-rustdoc-search Area: Rustdoc's search feature labels Nov 25, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 25, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. 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. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Nov 25, 2025
@shua
Copy link
Author

shua commented Nov 25, 2025

maybe r? @Amanieu as the reviewer of the previous PR has more context

edit: whoops saw previous reviewer actually was Mark-Simulcrum, Amanieu was just last to leave a review. If it makes sense to swap it back, please do!

@rustbot rustbot assigned Amanieu and unassigned Mark-Simulacrum Nov 25, 2025
@cyrgani cyrgani added the A-allocators Area: Custom and system allocators label Nov 25, 2025
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the T-release Relevant to the release subteam, which will review and decide on the PR/issue. label Nov 26, 2025
@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Collaborator

bors commented Nov 26, 2025

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

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@craterbot
Copy link
Collaborator

👌 Experiment pr-149328 created and queued.
🤖 Automatically detected try build 579169d
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 26, 2026
@craterbot
Copy link
Collaborator

🚧 Experiment pr-149328 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-149328 is completed!
📊 5 regressed and 0 fixed (829643 total)
📊 2533 spurious results on the retry-regressed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-149328/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Mar 1, 2026
@shua
Copy link
Author

shua commented Mar 1, 2026

Only interesting failure I see, is a package that has a negative impl on String:

impl !NotString for String {}

as I understand, negative impls are still unstable, so maybe this is okay?

All the other failures look related to infra issues (docker, fs is read-only, etc)

@Amanieu
Copy link
Member

Amanieu commented Mar 2, 2026

That seems fine since it's nightly-only.

Also note that we may remove the type alias in a future edition. We're planning to add a way to make certain paths (like std::string::String) resolve to different items depending on the edition.

@bors r+

@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 2, 2026

📌 Commit ff51650 has been approved by Amanieu

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 2, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 2, 2026
Add `String<A>` type with custom allocator parameter

This change is part of the `allocator_api` feature set [rust-lang#32838](rust-lang#32838) (also see [wg-allocators roadmap] or [libs-team ACP]).
The previous attempts at adding an allocator parameter to string are at [rust-lang#101551], and [rust-lang#79500] (I think those authors should get much of the credit here, I am re-writing what they worked out in those threads).

## workaround

There is a type inference ambiguity introduced when adding a generic parameter to a type which previously had none, even when that parameter has a default value (more details in [rust-lang#98931]). I've done the same [workaround] as [rust-lang#101551], which is to make `alloc::string::String` a type alias to `String<Global>`, but I've arranged the modules a bit differently to make rebase/merges a bit easier.

This workaround unfortunately changes the type name of the `String` language item, and that would be user-facing in error or diagnostic output. I understand from [this comment](rust-lang#101551 (comment)) that this change is acceptable.

## changes to existing API

Most of the methods on the original `String` have been implemented for the generic version instead. I don't foresee anything more moving from `String<Global>` to `String<A>`, as the remaining methods are all constructors which implicitly use the `Global` allocator.

There are three general types of changes:
1. methods which don't allocate: here we just change `impl Foo for String` to `impl<A: Allocator> Foo for String<A>`
2. converting to/from other allocator generic types like `Vec<u8, A>` and `Box<str, A>`: here we can use the existing allocator from those types.
3. methods which clone from some other type with an allocator: here it's ambiguous whether the end result should be `String<A>`, `String<Global>`, or `String<impl Allocator + Default>`, etc; in general I try to leave these out of this change, but where some analogous change was made to `Vec<T, A>` I follow that.

## new methods

Some methods have been added to `String<A>` which are not strictly necessary to land this change, but are considered helpful enough to users, and close enough to existing precedent in `Vec<T, A>`. Specifically, 4 new constructors (`new_in`, `with_capacity_in`, `try_with_capacity_in`, `from_raw_parts_in`), 1 destructor (`into_raw_parts_with_alloc`), and 1 getter (`allocator`). Technically, the updated `from_utf8_unchecked` should be sufficient for constructing, but we can add some safe constructors so users don't have to sully themselves.

## not implemented

Variants of `from_utf{8,16}*` which internally allocate or use `Cow` have been punted on this PR, maybe a followup would make sense to either rewrite them, or add some `*_in` variant.

[wg-allocators roadmap]: rust-lang/wg-allocators#7
[libs-team ACP]: rust-lang/libs-team#101
[workaround]: rust-lang#79499 (comment)
[rust-lang#101551]: rust-lang#101551
[rust-lang#79500]: rust-lang#79500
[rust-lang#98931]: rust-lang#98931
rust-bors bot pushed a commit that referenced this pull request Mar 2, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #153153 (add tests for thumb interworking)
 - #149328 (Add `String<A>` type with custom allocator parameter)
 - #151780 (Updated slice tests to pass for big endian hosts for `multiple-option-or-permutations.rs`)
 - #153015 (core: make atomic primitives type aliases of `Atomic<T>`)
 - #153292 (tests: codegen-llvm: vec-calloc: do not require the uwtable attribute)

Failed merges:

 - #151864 (Implement AST -> HIR generics propagation in delegation)
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 2, 2026
Add `String<A>` type with custom allocator parameter

This change is part of the `allocator_api` feature set [rust-lang#32838](rust-lang#32838) (also see [wg-allocators roadmap] or [libs-team ACP]).
The previous attempts at adding an allocator parameter to string are at [rust-lang#101551], and [rust-lang#79500] (I think those authors should get much of the credit here, I am re-writing what they worked out in those threads).

## workaround

There is a type inference ambiguity introduced when adding a generic parameter to a type which previously had none, even when that parameter has a default value (more details in [rust-lang#98931]). I've done the same [workaround] as [rust-lang#101551], which is to make `alloc::string::String` a type alias to `String<Global>`, but I've arranged the modules a bit differently to make rebase/merges a bit easier.

This workaround unfortunately changes the type name of the `String` language item, and that would be user-facing in error or diagnostic output. I understand from [this comment](rust-lang#101551 (comment)) that this change is acceptable.

## changes to existing API

Most of the methods on the original `String` have been implemented for the generic version instead. I don't foresee anything more moving from `String<Global>` to `String<A>`, as the remaining methods are all constructors which implicitly use the `Global` allocator.

There are three general types of changes:
1. methods which don't allocate: here we just change `impl Foo for String` to `impl<A: Allocator> Foo for String<A>`
2. converting to/from other allocator generic types like `Vec<u8, A>` and `Box<str, A>`: here we can use the existing allocator from those types.
3. methods which clone from some other type with an allocator: here it's ambiguous whether the end result should be `String<A>`, `String<Global>`, or `String<impl Allocator + Default>`, etc; in general I try to leave these out of this change, but where some analogous change was made to `Vec<T, A>` I follow that.

## new methods

Some methods have been added to `String<A>` which are not strictly necessary to land this change, but are considered helpful enough to users, and close enough to existing precedent in `Vec<T, A>`. Specifically, 4 new constructors (`new_in`, `with_capacity_in`, `try_with_capacity_in`, `from_raw_parts_in`), 1 destructor (`into_raw_parts_with_alloc`), and 1 getter (`allocator`). Technically, the updated `from_utf8_unchecked` should be sufficient for constructing, but we can add some safe constructors so users don't have to sully themselves.

## not implemented

Variants of `from_utf{8,16}*` which internally allocate or use `Cow` have been punted on this PR, maybe a followup would make sense to either rewrite them, or add some `*_in` variant.

[wg-allocators roadmap]: rust-lang/wg-allocators#7
[libs-team ACP]: rust-lang/libs-team#101
[workaround]: rust-lang#79499 (comment)
[rust-lang#101551]: rust-lang#101551
[rust-lang#79500]: rust-lang#79500
[rust-lang#98931]: rust-lang#98931
rust-bors bot pushed a commit that referenced this pull request Mar 2, 2026
…uwer

Rollup of 9 pull requests

Successful merges:

 - #153153 (add tests for thumb interworking)
 - #149328 (Add `String<A>` type with custom allocator parameter)
 - #151780 (Updated slice tests to pass for big endian hosts for `multiple-option-or-permutations.rs`)
 - #151962 (Fix next-solver ICE on PointeeSized goals)
 - #153015 (core: make atomic primitives type aliases of `Atomic<T>`)
 - #153161 (Rejig `rustc_with_all_queries!`)
 - #153191 (  don't emit `unused_results` lint for tuples of "trivial" types )
 - #153273 (vec/mod.rs: add missing period in "ie." in docs)
 - #153292 (tests: codegen-llvm: vec-calloc: do not require the uwtable attribute)
@JonathanBrouwer
Copy link
Contributor

@bors r-
#153299 (comment)

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 2, 2026
Add `String<A>` type with custom allocator parameter

This change is part of the `allocator_api` feature set [rust-lang#32838](rust-lang#32838) (also see [wg-allocators roadmap] or [libs-team ACP]).
The previous attempts at adding an allocator parameter to string are at [rust-lang#101551], and [rust-lang#79500] (I think those authors should get much of the credit here, I am re-writing what they worked out in those threads).

## workaround

There is a type inference ambiguity introduced when adding a generic parameter to a type which previously had none, even when that parameter has a default value (more details in [rust-lang#98931]). I've done the same [workaround] as [rust-lang#101551], which is to make `alloc::string::String` a type alias to `String<Global>`, but I've arranged the modules a bit differently to make rebase/merges a bit easier.

This workaround unfortunately changes the type name of the `String` language item, and that would be user-facing in error or diagnostic output. I understand from [this comment](rust-lang#101551 (comment)) that this change is acceptable.

## changes to existing API

Most of the methods on the original `String` have been implemented for the generic version instead. I don't foresee anything more moving from `String<Global>` to `String<A>`, as the remaining methods are all constructors which implicitly use the `Global` allocator.

There are three general types of changes:
1. methods which don't allocate: here we just change `impl Foo for String` to `impl<A: Allocator> Foo for String<A>`
2. converting to/from other allocator generic types like `Vec<u8, A>` and `Box<str, A>`: here we can use the existing allocator from those types.
3. methods which clone from some other type with an allocator: here it's ambiguous whether the end result should be `String<A>`, `String<Global>`, or `String<impl Allocator + Default>`, etc; in general I try to leave these out of this change, but where some analogous change was made to `Vec<T, A>` I follow that.

## new methods

Some methods have been added to `String<A>` which are not strictly necessary to land this change, but are considered helpful enough to users, and close enough to existing precedent in `Vec<T, A>`. Specifically, 4 new constructors (`new_in`, `with_capacity_in`, `try_with_capacity_in`, `from_raw_parts_in`), 1 destructor (`into_raw_parts_with_alloc`), and 1 getter (`allocator`). Technically, the updated `from_utf8_unchecked` should be sufficient for constructing, but we can add some safe constructors so users don't have to sully themselves.

## not implemented

Variants of `from_utf{8,16}*` which internally allocate or use `Cow` have been punted on this PR, maybe a followup would make sense to either rewrite them, or add some `*_in` variant.

[wg-allocators roadmap]: rust-lang/wg-allocators#7
[libs-team ACP]: rust-lang/libs-team#101
[workaround]: rust-lang#79499 (comment)
[rust-lang#101551]: rust-lang#101551
[rust-lang#79500]: rust-lang#79500
[rust-lang#98931]: rust-lang#98931
rust-bors bot pushed a commit that referenced this pull request Mar 2, 2026
…uwer

Rollup of 11 pull requests

Successful merges:

 - #153153 (add tests for thumb interworking)
 - #149328 (Add `String<A>` type with custom allocator parameter)
 - #151780 (Updated slice tests to pass for big endian hosts for `multiple-option-or-permutations.rs`)
 - #151962 (Fix next-solver ICE on PointeeSized goals)
 - #153015 (core: make atomic primitives type aliases of `Atomic<T>`)
 - #153161 (Rejig `rustc_with_all_queries!`)
 - #153191 (  don't emit `unused_results` lint for tuples of "trivial" types )
 - #153273 (vec/mod.rs: add missing period in "ie." in docs)
 - #153292 (tests: codegen-llvm: vec-calloc: do not require the uwtable attribute)
 - #153293 (library: std: process: skip tests on Hermit)
 - #153301 (Do not ping kobzol on rustc-dev-guide changes)
@rust-bors rust-bors bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 2, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 2, 2026

Commit ff51650 has been unapproved.

This PR was contained in a rollup (#153303), which was also unapproved.

@shua
Copy link
Author

shua commented Mar 2, 2026

for some reason, when rustdoc is building the reference docs, it thinks alloc::string::String is a struct, and so makes and [`String`] links into a link to alloc/string/struct.String.html. The correct file should be type.String.html, but I am not able to change the reference documentation because it's a git subtree. Should I add some exception to linkchecker, even if it is correctly flagging a bad link and followup with a PR to the reference docs, or should I spend more time trying to figure out what rustdoc is doing?

@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 3, 2026

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

@Amanieu
Copy link
Member

Amanieu commented Mar 3, 2026

for some reason, when rustdoc is building the reference docs, it thinks alloc::string::String is a struct, and so makes and [`String`] links into a link to alloc/string/struct.String.html. The correct file should be type.String.html, but I am not able to change the reference documentation because it's a git subtree. Should I add some exception to linkchecker, even if it is correctly flagging a bad link and followup with a PR to the reference docs, or should I spend more time trying to figure out what rustdoc is doing?

cc @rust-lang/lang-docs

@ehuss
Copy link
Contributor

ehuss commented Mar 3, 2026

The links are generated directly by rustdoc. If rustdoc is generating the wrong link for something like [`String`], then it seems like it would be good to first investigate that?

And if the link for https://doc.rust-lang.org/std/string/struct.String.html is going away, that seems especially concerning since that very common type probably has links to it from all over the internet.

@shua
Copy link
Author

shua commented Mar 4, 2026

It's strange that rustdoc seems to do this correctly everywhere else, eg when building doc comments, it's only when generating the mdbook for src/doc/reference that the links are wrong. Either rustdoc or this mdbook-spec tool inside the src/doc/reference. I'll have to dig in a little more when I have time.

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-rustc-dev-guide Area: rustc-dev-guide A-rustdoc-js Area: Rustdoc's JS front-end A-rustdoc-search Area: Rustdoc's search feature 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-release Relevant to the release subteam, 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. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.