-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Proposal
Add an unstable, defaulted generic parameter to alloc::string::String to allow use with custom allocators under #![feature(allocator_api)], and generalize most implementations on String to be generic over the allocator.
(There's a tracking issue rust-lang/wg-allocators#7 on wg-allocators, so I wasn't sure if this needed an ACP. I made one just to be safe.)
Problem statement
Currently, Vec and Box have a second, unstable, defaulted generic parameter A: Allocator = Global, allowing them to support custom allocators. String does not currently have this, so it does not yet support custom allocators.
Motivation, use-cases
Part of the effort to expand allocator_api to support more collection types. It could be useful to allow using common container types with different allocators that are better suited to different allocation patterns.
Solution sketches
Add an #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global generic to alloc::string::String, alloc::string::FromUtf8Error, and alloc::string::Drain, and make most inherent functions and trait implementations generic over this parameter.
Also make some corresponding non-allocator-generic functions and implementations on Box<str> allocator-generic.
- removed unstable trait implementations.
StructuralEq for String:Stringpreviously usedderive(Eq), but manually implementedPartialEq. To prevent anA: Eqbound, I removed thederiveand replaced it with a manualimpl Eqwithout that bound. It should not be observable on stable, becauseStringdoes not implementStructuralPartialEq, which is also required for structural matching.- Manual
impl<A: Allocator> StructuralEq for String<A> {}, etc. can be added if necessary.
- Manual
StructuralEq/StructralPartialEq for FromUtf8Error:FromUtf8Errorpreviously usedderive(PartialEq, Eq). However, it is not possible to get a value of typeFromUtf8Errorin constant evaluation on stable, so there is no way to construct anything that could even be used as a structural match pattern, so I don't think these removals are observable.
- Added allocator-generic inherent
Stringfunctions (that already exist forVec)new_in/with_capacity_infrom_raw_parts_in/into_raw_parts_with_allocallocator
- Inherent functions which are not (currently) made allocator-generic
new/with_capacity/from_utf16/from_utf16_lossy: These could useA: (~const) Default, but seemed out of scope. Also, correspondingVecfunctions are not allocator-generic.from_utf8_lossy: This returns aCow<str>, which is not allocator-generic.from_raw_parts/into_raw_parts: These are tied to the global allocator.
- Added trait implementations that already are allocator-generic for
Vec/[T]-like.Clone for Box<str, A> where A: Clone
- Added trait implementations that are not yet allocator-generic for
Vec/[T]-likeBorrow/BorrowMut<str> for String<A>edit: These have been removed from the linked PR to make room for futureFrom<String<A>> for Rc<str>/Arc<str>From<String<A>> for Rc<str, A>-like impls.
- Trait implementations which are not (currently) made allocator-generic:
Default where A: Default: this would require makingGlobalimplementconst Default, which is probably fine, but seemed out-of-scope. Also, the correspondingVecimplementation is not allocator-generic.- Likewise for
impl const Default for Box<str>(andBox<[T]>).
- Likewise for
From<&String> for String: Unclear if it should beFrom<&String<A>> for String<A> where A: CloneorFrom<&String<A2>> for String<A1> where A1: DefaultFromStr,From<&str-like>,From<char>,FromIterator<_>: Could befor String<A> where A: Defaultbut seemed out-of-scope. Also, correspondingVecimplementations are not allocator-generic.- Likewise for
From<&str> for Box<str>andFrom<&[T]> for Box<T> where T: Clone
- Likewise for
- Other APIs which are not (currently) made allocator-generic
- APIs involving
CString, e.g.CString::into_string - APIs outside the
alloccrate, e.g.std::io::Read::read_to_string,AsRef<OsStr> for String,ToSocketAddrs for String
- APIs involving
All unmentioned inherent functions and trait implementations on String, FromUtf8Error, and Drain are made allocator-generic (with appropriate bounds, e.g. A: Allocator + Clone for String::split_off).
Several implementations involving Box<str> are also made allocator-generic
From<Box<str, A>> for Box<[u8], A>From<Box<str, A>> for String<A>
From<String<A>> for Box<str, A> is not added currently because of trait coherence rules (help?).
Links and related work
- [WIP] Add support for custom allocator for
Stringrust#101551 - Add support for custom allocator for
(C)Stringrust#79500 (closed in favor of 101551 above) - Tracking Issue for structs which needs an allocator wg-allocators#7
- Add support for custom allocators in
Vecrust#78461 - Future work to do similar for
CStringand other containers.
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.