Skip to content

Commit 89ab5b9

Browse files
committed
FEAT: Use MaybeUninit in ArrayString too
This way to encapsulate and consolidate all the uninitialized usage in one place in the crate. This requires MaybeUninit to implement Copy.
1 parent 96019bc commit 89ab5b9

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

src/array_string.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use char::encode_utf8;
1616
#[cfg(feature="serde-1")]
1717
use serde::{Serialize, Deserialize, Serializer, Deserializer};
1818

19+
use super::MaybeUninit;
20+
1921
/// A string with a fixed capacity.
2022
///
2123
/// The `ArrayString` is a string backed by a fixed size array. It keeps track
@@ -25,7 +27,7 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer};
2527
/// if needed.
2628
#[derive(Copy)]
2729
pub struct ArrayString<A: Array<Item=u8>> {
28-
xs: A,
30+
xs: MaybeUninit<A>,
2931
len: A::Index,
3032
}
3133

@@ -52,7 +54,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
5254
pub fn new() -> ArrayString<A> {
5355
unsafe {
5456
ArrayString {
55-
xs: ::new_array(),
57+
xs: MaybeUninit::uninitialized(),
5658
len: Index::from(0),
5759
}
5860
}
@@ -210,7 +212,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
210212
return Err(CapacityError::new(s));
211213
}
212214
unsafe {
213-
let dst = self.xs.as_mut_ptr().offset(self.len() as isize);
215+
let dst = self.xs.ptr_mut().offset(self.len() as isize);
214216
let src = s.as_ptr();
215217
ptr::copy_nonoverlapping(src, dst, s.len());
216218
let newl = self.len() + s.len();
@@ -304,8 +306,8 @@ impl<A: Array<Item=u8>> ArrayString<A> {
304306
let next = idx + ch.len_utf8();
305307
let len = self.len();
306308
unsafe {
307-
ptr::copy(self.xs.as_ptr().offset(next as isize),
308-
self.xs.as_mut_ptr().offset(idx as isize),
309+
ptr::copy(self.xs.ptr().offset(next as isize),
310+
self.xs.ptr_mut().offset(idx as isize),
309311
len - next);
310312
self.set_len(len - (next - idx));
311313
}
@@ -339,7 +341,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
339341

340342
/// Return a mutable slice of the whole string’s buffer
341343
unsafe fn raw_mut_bytes(&mut self) -> &mut [u8] {
342-
slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.capacity())
344+
slice::from_raw_parts_mut(self.xs.ptr_mut(), self.capacity())
343345
}
344346
}
345347

@@ -348,7 +350,7 @@ impl<A: Array<Item=u8>> Deref for ArrayString<A> {
348350
#[inline]
349351
fn deref(&self) -> &str {
350352
unsafe {
351-
let sl = slice::from_raw_parts(self.xs.as_ptr(), self.len.to_usize());
353+
let sl = slice::from_raw_parts(self.xs.ptr(), self.len.to_usize());
352354
str::from_utf8_unchecked(sl)
353355
}
354356
}
@@ -358,7 +360,7 @@ impl<A: Array<Item=u8>> DerefMut for ArrayString<A> {
358360
#[inline]
359361
fn deref_mut(&mut self) -> &mut str {
360362
unsafe {
361-
let sl = slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.len.to_usize());
363+
let sl = slice::from_raw_parts_mut(self.xs.ptr_mut(), self.len.to_usize());
362364
str::from_utf8_unchecked_mut(sl)
363365
}
364366
}

src/lib.rs

-8
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,6 @@ pub use array_string::ArrayString;
6565
pub use errors::CapacityError;
6666

6767

68-
unsafe fn new_array<A: Array>() -> A {
69-
// Note: Returning an uninitialized value here only works
70-
// if we can be sure the data is never used. The nullable pointer
71-
// inside enum optimization conflicts with this this for example,
72-
// so we need to be extra careful. See `NoDrop` enum.
73-
mem::uninitialized()
74-
}
75-
7668
/// A vector with a fixed capacity.
7769
///
7870
/// The `ArrayVec` is a vector backed by a fixed size array. It keeps track of

src/maybe_uninit.rs

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::mem::uninitialized;
1010
///
1111
/// This is a stop-gap solution until MaybeUninit is stable in Rust's std.
1212
#[repr(C)]
13+
#[derive(Copy)]
1314
pub struct MaybeUninit<T>(ManuallyDrop<T>);
1415

1516
impl<T> MaybeUninit<T> {
@@ -42,6 +43,10 @@ impl<T> MaybeUninit<T> {
4243
}
4344

4445

46+
impl<T> Clone for MaybeUninit<T> where T: Copy {
47+
fn clone(&self) -> Self { *self }
48+
}
49+
4550

4651
#[test]
4752
fn test_offset() {

0 commit comments

Comments
 (0)