Skip to content

Commit

Permalink
feat: servo#263 added feature const_new
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLuq committed Sep 24, 2021
1 parent 2691f34 commit 7bf1291
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ documentation = "https://docs.rs/smallvec/"

[features]
const_generics = []
const_new = []
write = []
union = []
specialization = []
Expand Down
49 changes: 49 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,22 @@
//! [Rustonomicon](https://doc.rust-lang.org/1.42.0/nomicon/dropck.html#an-escape-hatch).
//!
//! Tracking issue: [rust-lang/rust#34761](https://github.com/rust-lang/rust/issues/34761)
//!
//! ### `const_new`
//!
//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
//!
//! This feature exposes the function [`SmallVec::new_const`] which is a `const fn` so the `SmallVec` may be used from a const context.
//! For details, see the
//! [Rust Reference](https://doc.rust-lang.org/reference/const_eval.html#const-functions).
//!
//! Tracking issue: [rust-lang/rust#57563](https://github.com/rust-lang/rust/issues/57563)
#![no_std]
#![cfg_attr(feature = "specialization", allow(incomplete_features))]
#![cfg_attr(feature = "specialization", feature(specialization))]
#![cfg_attr(feature = "may_dangle", feature(dropck_eyepatch))]
#![cfg_attr(feature = "const_new", feature(const_fn_trait_bound))]
#![deny(missing_docs)]

#[doc(hidden)]
Expand Down Expand Up @@ -353,6 +364,16 @@ union SmallVecData<A: Array> {
heap: (*mut A::Item, usize),
}

#[cfg(all(feature = "union", feature = "const_new"))]
impl<A: Array> SmallVecData<A> {
#[inline]
const fn from_const(inline: MaybeUninit<A>) -> SmallVecData<A> {
SmallVecData {
inline: core::mem::ManuallyDrop::new(inline),
}
}
}

#[cfg(feature = "union")]
impl<A: Array> SmallVecData<A> {
#[inline]
Expand Down Expand Up @@ -393,6 +414,14 @@ enum SmallVecData<A: Array> {
Heap((*mut A::Item, usize)),
}

#[cfg(all(not(feature = "union"), feature = "const_new"))]
impl<A: Array> SmallVecData<A> {
#[inline]
const fn from_const(inline: MaybeUninit<A>) -> SmallVecData<A> {
SmallVecData::Inline(inline)
}
}

#[cfg(not(feature = "union"))]
impl<A: Array> SmallVecData<A> {
#[inline]
Expand Down Expand Up @@ -1329,6 +1358,26 @@ impl<A: Array> SmallVec<A> {
}
}

#[cfg(feature = "const_new")]
impl<A: Array> SmallVec<A> {
/// Construct an empty vector.
///
/// # Safety
/// No size validation is attempted for this function.
/// Invalid custom implementations of [`Array`] normally panics during [`new`].
/// `new_const` will still initialize which may cause undefined behavior (such as segmentation errors) when used with invalid implementations.
///
/// [`Array`]: crate::Array
/// [`new`]: crate::SmallVec::new
#[inline]
pub const unsafe fn new_const() -> SmallVec<A> {
SmallVec {
capacity: 0,
data: SmallVecData::from_const(MaybeUninit::uninit()),
}
}
}

impl<A: Array> SmallVec<A>
where
A::Item: Copy,
Expand Down
10 changes: 10 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,16 @@ fn const_generics() {
let _v = SmallVec::<[i32; 987]>::default();
}

#[cfg(feature = "const_new")]
#[test]
fn const_new() {
let _v = const_new_inner();
}
#[cfg(feature = "const_new")]
const fn const_new_inner() -> SmallVec<[i32; 4]> {
unsafe { SmallVec::<[i32; 4]>::new_const() }
}

#[test]
fn empty_macro() {
let _v: SmallVec<[u8; 1]> = smallvec![];
Expand Down

0 comments on commit 7bf1291

Please sign in to comment.