Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 69d0474

Browse files
committedSep 24, 2021
feat: servo#263 added feature const_new
1 parent 2691f34 commit 69d0474

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed
 

‎Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ documentation = "https://docs.rs/smallvec/"
1313

1414
[features]
1515
const_generics = []
16+
const_new = []
1617
write = []
1718
union = []
1819
specialization = []

‎src/lib.rs

+49
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,22 @@
6767
//! [Rustonomicon](https://doc.rust-lang.org/1.42.0/nomicon/dropck.html#an-escape-hatch).
6868
//!
6969
//! Tracking issue: [rust-lang/rust#34761](https://github.com/rust-lang/rust/issues/34761)
70+
//!
71+
//! ### `const_new`
72+
//!
73+
//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
74+
//!
75+
//! This feature exposes the function [`SmallVec::const_new`] which is a `const fn` so the `SmallVec` may be used from a const context.
76+
//! For details, see the
77+
//! [Rust Reference](https://doc.rust-lang.org/reference/const_eval.html#const-functions).
78+
//!
79+
//! Tracking issue: [rust-lang/rust#57563](https://github.com/rust-lang/rust/issues/57563)
7080
7181
#![no_std]
7282
#![cfg_attr(feature = "specialization", allow(incomplete_features))]
7383
#![cfg_attr(feature = "specialization", feature(specialization))]
7484
#![cfg_attr(feature = "may_dangle", feature(dropck_eyepatch))]
85+
#![cfg_attr(feature = "const_new", feature(const_fn_trait_bound))]
7586
#![deny(missing_docs)]
7687

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

367+
#[cfg(all(feature = "union", feature = "const_new"))]
368+
impl<A: Array> SmallVecData<A> {
369+
#[inline]
370+
const fn from_const(inline: MaybeUninit<A>) -> SmallVecData<A> {
371+
SmallVecData {
372+
inline: core::mem::ManuallyDrop::new(inline),
373+
}
374+
}
375+
}
376+
356377
#[cfg(feature = "union")]
357378
impl<A: Array> SmallVecData<A> {
358379
#[inline]
@@ -393,6 +414,14 @@ enum SmallVecData<A: Array> {
393414
Heap((*mut A::Item, usize)),
394415
}
395416

417+
#[cfg(all(not(feature = "union"), feature = "const_new"))]
418+
impl<A: Array> SmallVecData<A> {
419+
#[inline]
420+
const fn from_const(inline: MaybeUninit<A>) -> SmallVecData<A> {
421+
SmallVecData::Inline(inline)
422+
}
423+
}
424+
396425
#[cfg(not(feature = "union"))]
397426
impl<A: Array> SmallVecData<A> {
398427
#[inline]
@@ -1329,6 +1358,26 @@ impl<A: Array> SmallVec<A> {
13291358
}
13301359
}
13311360

1361+
#[cfg(feature = "const_new")]
1362+
impl<A: Array> SmallVec<A> {
1363+
/// Construct an empty vector.
1364+
///
1365+
/// # Safety
1366+
/// No size validation is attempted for this function.
1367+
/// Invalid custom implementations of [`Array`] normally panics during [`new`].
1368+
/// `new_const` will still initialize which may cause undefined behavior (such as segmentation errors) when used with invalid implementations.
1369+
///
1370+
/// [`Array`]: crate::Array
1371+
/// [`new`]: crate::SmallVec::new
1372+
#[inline]
1373+
pub const unsafe fn new_const() -> SmallVec<A> {
1374+
SmallVec {
1375+
capacity: 0,
1376+
data: SmallVecData::from_const(MaybeUninit::uninit()),
1377+
}
1378+
}
1379+
}
1380+
13321381
impl<A: Array> SmallVec<A>
13331382
where
13341383
A::Item: Copy,

‎src/tests.rs

+10
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,16 @@ fn const_generics() {
903903
let _v = SmallVec::<[i32; 987]>::default();
904904
}
905905

906+
#[cfg(feature = "const_new")]
907+
#[test]
908+
fn const_new() {
909+
let _v = const_new_inner();
910+
}
911+
#[cfg(feature = "const_new")]
912+
const fn const_new_inner() -> SmallVec<[i32; 4]> {
913+
unsafe { SmallVec::<[i32; 4]>::new_const() }
914+
}
915+
906916
#[test]
907917
fn empty_macro() {
908918
let _v: SmallVec<[u8; 1]> = smallvec![];

0 commit comments

Comments
 (0)
Please sign in to comment.