Skip to content

Commit de450e6

Browse files
Rollup merge of rust-lang#149328 - shua:stralloc, r=Amanieu
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
2 parents 9a664b9 + ff51650 commit de450e6

178 files changed

Lines changed: 1122 additions & 690 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

RELEASES.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ Stabilized APIs
303303
- [`impl PartialEq<String> for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3CString%3E-for-PathBuf)
304304
- [`impl PartialEq<str> for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3Cstr%3E-for-Path)
305305
- [`impl PartialEq<String> for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3CString%3E-for-Path)
306-
- [`impl PartialEq<PathBuf> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPathBuf%3E-for-String)
307-
- [`impl PartialEq<Path> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPath%3E-for-String)
306+
- [`impl PartialEq<PathBuf> for String`](https://doc.rust-lang.org/stable/std/string/type.String.html#impl-PartialEq%3CPathBuf%3E-for-String)
307+
- [`impl PartialEq<Path> for String`](https://doc.rust-lang.org/stable/std/string/type.String.html#impl-PartialEq%3CPath%3E-for-String)
308308
- [`impl PartialEq<PathBuf> for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPathBuf%3E-for-str)
309309
- [`impl PartialEq<Path> for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPath%3E-for-str)
310310
- [`Ipv4Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.from_octets)
@@ -854,7 +854,7 @@ Stabilized APIs
854854
- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first_mut)
855855
- [`<[T]>::split_off_last`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last)
856856
- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last_mut)
857-
- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
857+
- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/type.String.html#method.extend_from_within)
858858
- [`os_str::Display`](https://doc.rust-lang.org/stable/std/ffi/os_str/struct.Display.html)
859859
- [`OsString::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.display)
860860
- [`OsStr::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.display)
@@ -868,7 +868,7 @@ Stabilized APIs
868868
- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
869869
- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
870870
- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.write)
871-
- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
871+
- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/stable/std/string/type.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
872872
- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned)
873873
- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned)
874874
- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned-1)
@@ -906,14 +906,14 @@ These previously stable APIs are now stable in const contexts:
906906
- [`char::is_whitespace`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_whitespace)
907907
- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened)
908908
- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened_mut)
909-
- [`String::into_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_bytes)
910-
- [`String::as_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_str)
911-
- [`String::capacity`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.capacity)
912-
- [`String::as_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_bytes)
913-
- [`String::len`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.len)
914-
- [`String::is_empty`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.is_empty)
915-
- [`String::as_mut_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_str)
916-
- [`String::as_mut_vec`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_vec)
909+
- [`String::into_bytes`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.into_bytes)
910+
- [`String::as_str`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.as_str)
911+
- [`String::capacity`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.capacity)
912+
- [`String::as_bytes`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.as_bytes)
913+
- [`String::len`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.len)
914+
- [`String::is_empty`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.is_empty)
915+
- [`String::as_mut_str`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.as_mut_str)
916+
- [`String::as_mut_vec`](https://doc.rust-lang.org/stable/std/string/type.String.html#method.as_mut_vec)
917917
- [`Vec::as_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_ptr)
918918
- [`Vec::as_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_slice)
919919
- [`Vec::capacity`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.capacity)
@@ -2965,7 +2965,7 @@ Stabilized APIs
29652965

29662966
- [`impl<T: Send> Sync for mpsc::Sender<T>`](https://doc.rust-lang.org/stable/std/sync/mpsc/struct.Sender.html#impl-Sync-for-Sender%3CT%3E)
29672967
- [`impl TryFrom<&OsStr> for &str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-TryFrom%3C%26'a+OsStr%3E-for-%26'a+str)
2968-
- [`String::leak`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.leak)
2968+
- [`String::leak`](https://doc.rust-lang.org/stable/alloc/string/type.String.html#method.leak)
29692969

29702970
These APIs are now stable in const contexts:
29712971

@@ -5024,8 +5024,8 @@ and related tools.
50245024
[`collections::TryReserveError`]: https://doc.rust-lang.org/std/collections/struct.TryReserveError.html
50255025
[`HashMap::try_reserve`]: https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.try_reserve
50265026
[`HashSet::try_reserve`]: https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.try_reserve
5027-
[`String::try_reserve`]: https://doc.rust-lang.org/alloc/string/struct.String.html#method.try_reserve
5028-
[`String::try_reserve_exact`]: https://doc.rust-lang.org/alloc/string/struct.String.html#method.try_reserve_exact
5027+
[`String::try_reserve`]: https://doc.rust-lang.org/alloc/string/type.String.html#method.try_reserve
5028+
[`String::try_reserve_exact`]: https://doc.rust-lang.org/alloc/string/type.String.html#method.try_reserve_exact
50295029
[`Vec::try_reserve`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve
50305030
[`Vec::try_reserve_exact`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve_exact
50315031
[`VecDeque::try_reserve`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.try_reserve
@@ -5166,7 +5166,7 @@ and related tools.
51665166
[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
51675167
[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662
51685168
[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to
5169-
[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to
5169+
[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/type.String.html#method.shrink_to
51705170
[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to
51715171
[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to
51725172
[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to
@@ -9361,7 +9361,7 @@ Compatibility Notes
93619361
[`Iterator::try_for_each`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_for_each
93629362
[`NonNull::cast`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.cast
93639363
[`Option::filter`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.filter
9364-
[`String::replace_range`]: https://doc.rust-lang.org/std/string/struct.String.html#method.replace_range
9364+
[`String::replace_range`]: https://doc.rust-lang.org/std/string/type.String.html#method.replace_range
93659365
[`Take::set_limit`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.set_limit
93669366
[`hint::unreachable_unchecked`]: https://doc.rust-lang.org/std/hint/fn.unreachable_unchecked.html
93679367
[`os::unix::process::parent_id`]: https://doc.rust-lang.org/std/os/unix/process/fn.parent_id.html
@@ -9606,7 +9606,7 @@ Compatibility Notes
96069606
[`process::id`]: https://doc.rust-lang.org/std/process/fn.id.html
96079607
[`slice::rotate_left`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_left
96089608
[`slice::rotate_right`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_right
9609-
[`String::retain`]: https://doc.rust-lang.org/std/string/struct.String.html#method.retain
9609+
[`String::retain`]: https://doc.rust-lang.org/std/string/type.String.html#method.retain
96109610
[cargo/5041]: https://github.com/rust-lang/cargo/pull/5041
96119611
[cargo/5083]: https://github.com/rust-lang/cargo/pull/5083
96129612

@@ -11057,8 +11057,8 @@ Compatibility Notes
1105711057
[`Result::unwrap_or_default`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default
1105811058
[`SocketAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv4
1105911059
[`SocketAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv6
11060-
[`String::insert_str`]: https://doc.rust-lang.org/std/string/struct.String.html#method.insert_str
11061-
[`String::split_off`]: https://doc.rust-lang.org/std/string/struct.String.html#method.split_off
11060+
[`String::insert_str`]: https://doc.rust-lang.org/std/string/type.String.html#method.insert_str
11061+
[`String::split_off`]: https://doc.rust-lang.org/std/string/type.String.html#method.split_off
1106211062
[`Vec::dedup_by_key`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by_key
1106311063
[`Vec::dedup_by`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by
1106411064
[`VecDeque::resize`]: https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.resize
@@ -12972,8 +12972,8 @@ Compatibility Notes
1297212972
[`Ipv6Addr::is_unspecified`]: http://doc.rust-lang.org/nightly/std/net/struct.Ipv6Addr.html#method.is_unspecified
1297312973
[`Path::strip_prefix`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.strip_prefix
1297412974
[`RandomState::new`]: http://doc.rust-lang.org/nightly/std/collections/hash_map/struct.RandomState.html#method.new
12975-
[`String::as_mut_str`]: http://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_str
12976-
[`String::as_str`]: http://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_str
12975+
[`String::as_mut_str`]: http://doc.rust-lang.org/nightly/std/string/type.String.html#method.as_mut_str
12976+
[`String::as_str`]: http://doc.rust-lang.org/nightly/std/string/type.String.html#method.as_str
1297712977
[`Vec::as_mut_slice`]: http://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_slice
1297812978
[`Vec::as_slice`]: http://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_slice
1297912979
[`clone_from_slice`]: http://doc.rust-lang.org/nightly/std/primitive.slice.html#method.clone_from_slice
@@ -13159,7 +13159,7 @@ Compatibility Notes
1315913159
[`os::unix::fs::DirBuilderExt::mode`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.DirBuilderExt.html#tymethod.mode
1316013160
[`os::unix::fs::DirBuilderExt`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.DirBuilderExt.html
1316113161
[`string::Drain`]: http://doc.rust-lang.org/nightly/std/string/struct.Drain.html
13162-
[`string::String::drain`]: http://doc.rust-lang.org/nightly/std/string/struct.String.html#method.drain
13162+
[`string::String::drain`]: http://doc.rust-lang.org/nightly/std/string/type.String.html#method.drain
1316313163
[`vec::Drain`]: http://doc.rust-lang.org/nightly/std/vec/struct.Drain.html
1316413164
[`vec::Vec::drain`]: http://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.drain
1316513165
[`vec_deque::Drain`]: http://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.Drain.html
@@ -13508,7 +13508,7 @@ Miscellaneous
1350813508
[`Rc::make_mut`]: http://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.make_mut
1350913509
[`Rc::try_unwrap`]: http://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.try_unwrap
1351013510
[`Result::expect`]: http://doc.rust-lang.org/nightly/core/result/enum.Result.html#method.expect
13511-
[`String::into_boxed_str`]: http://doc.rust-lang.org/nightly/collections/string/struct.String.html#method.into_boxed_str
13511+
[`String::into_boxed_str`]: http://doc.rust-lang.org/nightly/collections/string/type.String.html#method.into_boxed_str
1351213512
[`TcpStream::read_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.read_timeout
1351313513
[`TcpStream::set_read_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.set_read_timeout
1351413514
[`TcpStream::write_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.write_timeout

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,6 +1972,7 @@ symbols! {
19721972
str_inherent_from_utf8_unchecked_mut,
19731973
strict_provenance_lints,
19741974
string_deref_patterns,
1975+
string_in_global,
19751976
stringify,
19761977
struct_field_attributes,
19771978
struct_inherit,

library/alloc/src/boxed.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ use crate::alloc::{AllocError, Allocator, Global, Layout};
210210
use crate::raw_vec::RawVec;
211211
#[cfg(not(no_global_oom_handling))]
212212
use crate::str::from_boxed_utf8_unchecked;
213+
#[cfg(not(no_global_oom_handling))]
214+
use crate::vec::Vec;
213215

214216
/// Conversion related impls for `Box<_>` (`From`, `downcast`, etc)
215217
mod convert;
@@ -2072,11 +2074,13 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
20722074

20732075
#[cfg(not(no_global_oom_handling))]
20742076
#[stable(feature = "box_slice_clone", since = "1.3.0")]
2075-
impl Clone for Box<str> {
2077+
impl<A: Allocator + Clone> Clone for Box<str, A> {
20762078
fn clone(&self) -> Self {
2077-
// this makes a copy of the data
2078-
let buf: Box<[u8]> = self.as_bytes().into();
2079-
unsafe { from_boxed_utf8_unchecked(buf) }
2079+
let alloc = Box::allocator(self).clone();
2080+
let len = self.len();
2081+
let mut vec: Vec<u8, A> = Vec::with_capacity_in(len, alloc);
2082+
vec.extend_from_slice(self.as_bytes());
2083+
unsafe { from_boxed_utf8_unchecked(vec.into_boxed_slice()) }
20802084
}
20812085
}
20822086

library/alloc/src/str.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// It's cleaner to just turn off the unused_imports warning than to fix them.
88
#![allow(unused_imports)]
99

10+
use core::alloc::Allocator;
1011
use core::borrow::{Borrow, BorrowMut};
1112
use core::iter::FusedIterator;
1213
use core::mem::MaybeUninit;
@@ -52,7 +53,7 @@ use core::{mem, ptr};
5253
use crate::borrow::ToOwned;
5354
use crate::boxed::Box;
5455
use crate::slice::{Concat, Join, SliceIndex};
55-
use crate::string::String;
56+
use crate::string::generic::String;
5657
use crate::vec::Vec;
5758

5859
/// Note: `str` in `Concat<str>` is not meaningful here.
@@ -186,15 +187,15 @@ where
186187
}
187188

188189
#[stable(feature = "rust1", since = "1.0.0")]
189-
impl Borrow<str> for String {
190+
impl<A: Allocator> Borrow<str> for String<A> {
190191
#[inline]
191192
fn borrow(&self) -> &str {
192193
&self[..]
193194
}
194195
}
195196

196197
#[stable(feature = "string_borrow_mut", since = "1.36.0")]
197-
impl BorrowMut<str> for String {
198+
impl<A: Allocator> BorrowMut<str> for String<A> {
198199
#[inline]
199200
fn borrow_mut(&mut self) -> &mut str {
200201
&mut self[..]
@@ -234,7 +235,7 @@ impl str {
234235
#[stable(feature = "str_box_extras", since = "1.20.0")]
235236
#[must_use = "`self` will be dropped if the result is not used"]
236237
#[inline]
237-
pub fn into_boxed_bytes(self: Box<Self>) -> Box<[u8]> {
238+
pub fn into_boxed_bytes<A: Allocator>(self: Box<Self, A>) -> Box<[u8], A> {
238239
self.into()
239240
}
240241

@@ -496,8 +497,8 @@ impl str {
496497
#[rustc_allow_incoherent_impl]
497498
#[must_use = "`self` will be dropped if the result is not used"]
498499
#[inline]
499-
pub fn into_string(self: Box<Self>) -> String {
500-
let slice = Box::<[u8]>::from(self);
500+
pub fn into_string<A: Allocator>(self: Box<Self, A>) -> String<A> {
501+
let slice = Box::<[u8], A>::from(self);
501502
unsafe { String::from_utf8_unchecked(slice.into_vec()) }
502503
}
503504

@@ -613,8 +614,9 @@ impl str {
613614
#[stable(feature = "str_box_extras", since = "1.20.0")]
614615
#[must_use]
615616
#[inline]
616-
pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
617-
unsafe { Box::from_raw(Box::into_raw(v) as *mut str) }
617+
pub unsafe fn from_boxed_utf8_unchecked<A: Allocator>(v: Box<[u8], A>) -> Box<str, A> {
618+
let (ptr, alloc) = Box::into_raw_with_allocator(v);
619+
unsafe { Box::from_raw_in(ptr as *mut str, alloc) }
618620
}
619621

620622
/// Converts leading ascii bytes in `s` by calling the `convert` function.

0 commit comments

Comments
 (0)