FEAT: Switch to using MaybeUninit for everything
Use std::mem::MaybeUninit and stop using nodrop as a fallback. This means we require Rust 1.36
This commit is contained in:
+4
-4
@@ -17,7 +17,7 @@ use char::encode_utf8;
|
||||
#[cfg(feature="serde-1")]
|
||||
use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
||||
|
||||
use super::MaybeUninitCopy;
|
||||
use super::MaybeUninit as MaybeUninitCopy;
|
||||
|
||||
/// A string with a fixed capacity.
|
||||
///
|
||||
@@ -98,10 +98,10 @@ impl<A> ArrayString<A>
|
||||
/// ```
|
||||
pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> {
|
||||
let len = str::from_utf8(b.as_slice())?.len();
|
||||
debug_assert_eq!(len, A::capacity());
|
||||
debug_assert_eq!(len, A::CAPACITY);
|
||||
Ok(ArrayString {
|
||||
xs: MaybeUninitCopy::from(*b),
|
||||
len: Index::from(A::capacity()),
|
||||
len: Index::from(A::CAPACITY),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ impl<A> ArrayString<A>
|
||||
/// assert_eq!(string.capacity(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn capacity(&self) -> usize { A::capacity() }
|
||||
pub fn capacity(&self) -> usize { A::CAPACITY }
|
||||
|
||||
/// Return if the `ArrayString` is completely filled.
|
||||
///
|
||||
|
||||
+3
-17
@@ -28,9 +28,6 @@ extern crate serde;
|
||||
#[cfg(not(feature="std"))]
|
||||
extern crate core as std;
|
||||
|
||||
#[cfg(not(has_manually_drop_in_union))]
|
||||
extern crate nodrop;
|
||||
|
||||
use std::cmp;
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
@@ -50,19 +47,8 @@ use std::fmt;
|
||||
use std::io;
|
||||
|
||||
|
||||
#[cfg(has_stable_maybe_uninit)]
|
||||
#[path="maybe_uninit_stable.rs"]
|
||||
mod maybe_uninit;
|
||||
#[cfg(all(not(has_stable_maybe_uninit), has_manually_drop_in_union))]
|
||||
mod maybe_uninit;
|
||||
#[cfg(all(not(has_stable_maybe_uninit), not(has_manually_drop_in_union)))]
|
||||
#[path="maybe_uninit_nodrop.rs"]
|
||||
mod maybe_uninit;
|
||||
|
||||
mod maybe_uninit_copy;
|
||||
|
||||
use maybe_uninit::MaybeUninit;
|
||||
use maybe_uninit_copy::MaybeUninitCopy;
|
||||
|
||||
#[cfg(feature="serde-1")]
|
||||
use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
||||
@@ -223,7 +209,7 @@ impl<A: Array> ArrayVec<A> {
|
||||
/// assert!(overflow.is_err());
|
||||
/// ```
|
||||
pub fn try_push(&mut self, element: A::Item) -> Result<(), CapacityError<A::Item>> {
|
||||
if self.len() < A::capacity() {
|
||||
if self.len() < A::CAPACITY {
|
||||
unsafe {
|
||||
self.push_unchecked(element);
|
||||
}
|
||||
@@ -258,7 +244,7 @@ impl<A: Array> ArrayVec<A> {
|
||||
#[inline]
|
||||
pub unsafe fn push_unchecked(&mut self, element: A::Item) {
|
||||
let len = self.len();
|
||||
debug_assert!(len < A::capacity());
|
||||
debug_assert!(len < A::CAPACITY);
|
||||
ptr::write(self.get_unchecked_mut(len), element);
|
||||
self.set_len(len + 1);
|
||||
}
|
||||
@@ -680,7 +666,7 @@ impl<A: Array> DerefMut for ArrayVec<A> {
|
||||
/// ```
|
||||
impl<A: Array> From<A> for ArrayVec<A> {
|
||||
fn from(array: A) -> Self {
|
||||
ArrayVec { xs: MaybeUninit::from(array), len: Index::from(A::capacity()) }
|
||||
ArrayVec { xs: MaybeUninit::from(array), len: Index::from(A::CAPACITY) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-16
@@ -1,27 +1,28 @@
|
||||
|
||||
|
||||
use array::Array;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::mem::MaybeUninit as StdMaybeUninit;
|
||||
|
||||
/// A combination of ManuallyDrop and “maybe uninitialized”;
|
||||
/// this wraps a value that can be wholly or partially uninitialized;
|
||||
/// it also has no drop regardless of the type of T.
|
||||
#[repr(C)] // for cast from self ptr to value
|
||||
pub union MaybeUninit<T> {
|
||||
empty: (),
|
||||
value: ManuallyDrop<T>,
|
||||
#[derive(Copy)]
|
||||
pub struct MaybeUninit<T> {
|
||||
inner: StdMaybeUninit<T>,
|
||||
}
|
||||
|
||||
impl<T> Clone for MaybeUninit<T>
|
||||
where T: Copy
|
||||
{
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
// Why we don't use std's MaybeUninit on nightly? See the ptr method
|
||||
|
||||
impl<T> MaybeUninit<T> {
|
||||
/// Create a new MaybeUninit with uninitialized interior
|
||||
pub unsafe fn uninitialized() -> Self {
|
||||
MaybeUninit { empty: () }
|
||||
MaybeUninit { inner: StdMaybeUninit::uninit() }
|
||||
}
|
||||
|
||||
/// Create a new MaybeUninit from the value `v`.
|
||||
pub fn from(v: T) -> Self {
|
||||
MaybeUninit { value: ManuallyDrop::new(v) }
|
||||
MaybeUninit { inner: StdMaybeUninit::new(v) }
|
||||
}
|
||||
|
||||
// Raw pointer casts written so that we don't reference or access the
|
||||
@@ -31,16 +32,13 @@ impl<T> MaybeUninit<T> {
|
||||
pub fn ptr(&self) -> *const T::Item
|
||||
where T: Array
|
||||
{
|
||||
// std MaybeUninit creates a &self.value reference here which is
|
||||
// not guaranteed to be sound in our case - we will partially
|
||||
// initialize the value, not always wholly.
|
||||
self as *const _ as *const T::Item
|
||||
self.inner.as_ptr() as *const T::Item
|
||||
}
|
||||
|
||||
/// Return a mut raw pointer to the start of the interior array
|
||||
pub fn ptr_mut(&mut self) -> *mut T::Item
|
||||
where T: Array
|
||||
{
|
||||
self as *mut _ as *mut T::Item
|
||||
self.inner.as_mut_ptr() as *mut T::Item
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
use array::Array;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)] // for cast from self ptr to value
|
||||
pub union MaybeUninitCopy<T>
|
||||
where T: Copy
|
||||
{
|
||||
empty: (),
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T> MaybeUninitCopy<T>
|
||||
where T: Copy
|
||||
{
|
||||
/// Create a new MaybeUninit with uninitialized interior
|
||||
pub unsafe fn uninitialized() -> Self {
|
||||
Self { empty: () }
|
||||
}
|
||||
|
||||
/// Create a new MaybeUninit from the value `v`.
|
||||
pub fn from(value: T) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
|
||||
// Raw pointer casts written so that we don't reference or access the
|
||||
// uninitialized interior value
|
||||
|
||||
/// Return a raw pointer to the start of the interior array
|
||||
pub fn ptr(&self) -> *const T::Item
|
||||
where T: Array
|
||||
{
|
||||
self as *const _ as *const T::Item
|
||||
}
|
||||
|
||||
/// Return a mut raw pointer to the start of the interior array
|
||||
pub fn ptr_mut(&mut self) -> *mut T::Item
|
||||
where T: Array
|
||||
{
|
||||
self as *mut _ as *mut T::Item
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
|
||||
use array::Array;
|
||||
use nodrop::NoDrop;
|
||||
use std::mem::uninitialized;
|
||||
|
||||
/// A combination of NoDrop and “maybe uninitialized”;
|
||||
/// this wraps a value that can be wholly or partially uninitialized.
|
||||
///
|
||||
/// NOTE: This is known to not be a good solution, but it's the one we have kept
|
||||
/// working on stable Rust. Stable improvements are encouraged, in any form,
|
||||
/// but of course we are waiting for a real, stable, MaybeUninit.
|
||||
pub struct MaybeUninit<T>(NoDrop<T>);
|
||||
// why don't we use ManuallyDrop here: It doesn't inhibit
|
||||
// enum layout optimizations that depend on T, and we support older Rust.
|
||||
|
||||
impl<T> MaybeUninit<T> {
|
||||
/// Create a new MaybeUninit with uninitialized interior
|
||||
pub unsafe fn uninitialized() -> Self {
|
||||
Self::from(uninitialized())
|
||||
}
|
||||
|
||||
/// Create a new MaybeUninit from the value `v`.
|
||||
pub fn from(v: T) -> Self {
|
||||
MaybeUninit(NoDrop::new(v))
|
||||
}
|
||||
|
||||
/// Return a raw pointer to the start of the interior array
|
||||
pub fn ptr(&self) -> *const T::Item
|
||||
where T: Array
|
||||
{
|
||||
&*self.0 as *const T as *const _
|
||||
}
|
||||
|
||||
/// Return a mut raw pointer to the start of the interior array
|
||||
pub fn ptr_mut(&mut self) -> *mut T::Item
|
||||
where T: Array
|
||||
{
|
||||
&mut *self.0 as *mut T as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
|
||||
use array::Array;
|
||||
use std::mem::MaybeUninit as StdMaybeUninit;
|
||||
|
||||
pub struct MaybeUninit<T> {
|
||||
inner: StdMaybeUninit<T>,
|
||||
}
|
||||
|
||||
impl<T> MaybeUninit<T> {
|
||||
/// Create a new MaybeUninit with uninitialized interior
|
||||
pub unsafe fn uninitialized() -> Self {
|
||||
MaybeUninit { inner: StdMaybeUninit::uninit() }
|
||||
}
|
||||
|
||||
/// Create a new MaybeUninit from the value `v`.
|
||||
pub fn from(v: T) -> Self {
|
||||
MaybeUninit { inner: StdMaybeUninit::new(v) }
|
||||
}
|
||||
|
||||
// Raw pointer casts written so that we don't reference or access the
|
||||
// uninitialized interior value
|
||||
|
||||
/// Return a raw pointer to the start of the interior array
|
||||
pub fn ptr(&self) -> *const T::Item
|
||||
where T: Array
|
||||
{
|
||||
// std MaybeUninit creates a &self.value reference here which is
|
||||
// not guaranteed to be sound in our case - we will partially
|
||||
// initialize the value, not always wholly.
|
||||
self.inner.as_ptr() as *const T::Item
|
||||
}
|
||||
|
||||
/// Return a mut raw pointer to the start of the interior array
|
||||
pub fn ptr_mut(&mut self) -> *mut T::Item
|
||||
where T: Array
|
||||
{
|
||||
self.inner.as_mut_ptr() as *mut T::Item
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user