Skip to content

Commit 77a3134

Browse files
committed
Add allocator param to String
This is a third attempt at implementing adding Allocator support to the std lib's `String`. Still stuck on the same issue with type inference failing on the newly generic `String<A>`, but I opted to do even less than the previous WIP work, and have added no new functions (`String<A>` can be constructed via `Vec<u8, A>` or `Box<str, A>`), and have moved only the struct definition to its own mod to make rebasing a bit easier if/when main changes underneath me.
1 parent cf8a955 commit 77a3134

File tree

5 files changed

+282
-187
lines changed

5 files changed

+282
-187
lines changed

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;
@@ -2038,11 +2040,13 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
20382040

20392041
#[cfg(not(no_global_oom_handling))]
20402042
#[stable(feature = "box_slice_clone", since = "1.3.0")]
2041-
impl Clone for Box<str> {
2043+
impl<A: Allocator + Clone> Clone for Box<str, A> {
20422044
fn clone(&self) -> Self {
2043-
// this makes a copy of the data
2044-
let buf: Box<[u8]> = self.as_bytes().into();
2045-
unsafe { from_boxed_utf8_unchecked(buf) }
2045+
let alloc = Box::allocator(self).clone();
2046+
let len = self.len();
2047+
let mut vec: Vec<u8, A> = Vec::with_capacity_in(len, alloc);
2048+
vec.extend_from_slice(self.as_bytes());
2049+
unsafe { from_boxed_utf8_unchecked(vec.into_boxed_slice()) }
20462050
}
20472051
}
20482052

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

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

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

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

0 commit comments

Comments
 (0)