From 5ad4687b1be20707dc281fd383486c1128700a41 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Sun, 28 Mar 2021 14:48:27 -0300 Subject: [PATCH 1/4] Made ArrayVec::new and ArrayString::new const fns Added utils module with a `MaybeUninit` helper type to construct `[MaybeUninit; N]` Removed all uses of the "unstable-const-fn" feature, and documented it as being deprecated. Changed `assert_capacity_limit` macro to work in const contexts. --- src/array_string.rs | 14 ++------------ src/arrayvec.rs | 14 ++------------ src/lib.rs | 12 +++++------- src/utils.rs | 11 +++++++++++ 4 files changed, 20 insertions(+), 31 deletions(-) create mode 100644 src/utils.rs diff --git a/src/array_string.rs b/src/array_string.rs index 076544f..392ff4e 100644 --- a/src/array_string.rs +++ b/src/array_string.rs @@ -14,6 +14,7 @@ use std::str::Utf8Error; use crate::CapacityError; use crate::LenUint; use crate::char::encode_utf8; +use crate::utils::MakeMaybeUninit; #[cfg(feature="serde")] use serde::{Serialize, Deserialize, Serializer, Deserializer}; @@ -58,20 +59,9 @@ impl ArrayString /// assert_eq!(&string[..], "foo"); /// assert_eq!(string.capacity(), 16); /// ``` - #[cfg(not(feature="unstable-const-fn"))] - pub fn new() -> ArrayString { - assert_capacity_limit!(CAP); - unsafe { - ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } - } - - #[cfg(feature="unstable-const-fn")] pub const fn new() -> ArrayString { assert_capacity_limit!(CAP); - unsafe { - ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } + ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 } } /// Return the length of the string. diff --git a/src/arrayvec.rs b/src/arrayvec.rs index d46eddf..f00efeb 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -23,6 +23,7 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer}; use crate::LenUint; use crate::errors::CapacityError; use crate::arrayvec_impl::ArrayVecImpl; +use crate::utils::MakeMaybeUninit; /// A vector with a fixed capacity. /// @@ -76,20 +77,9 @@ impl ArrayVec { /// assert_eq!(&array[..], &[1, 2]); /// assert_eq!(array.capacity(), 16); /// ``` - #[cfg(not(feature="unstable-const-fn"))] - pub fn new() -> ArrayVec { - assert_capacity_limit!(CAP); - unsafe { - ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } - } - - #[cfg(feature="unstable-const-fn")] pub const fn new() -> ArrayVec { assert_capacity_limit!(CAP); - unsafe { - ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } + ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 } } /// Return the number of elements in the `ArrayVec`. diff --git a/src/lib.rs b/src/lib.rs index e6d2ea3..c186386 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,11 +11,9 @@ //! - Optional //! - Enable serialization for ArrayVec and ArrayString using serde 1.x //! -//! - `unstable-const-fn` -//! - Optional -//! - Makes [`ArrayVec::new`] and [`ArrayString::new`] `const fn`s, -//! using the nightly `const_fn` feature. -//! - Unstable and requires nightly. +//! - `unstable-const-fn`: **deprecated**, +//! used to be needed to make [`ArrayVec::new`] and [`ArrayString::new`] `const fn`s, +//! now they are always `const fn`s. //! //! ## Rust Version //! @@ -23,7 +21,6 @@ //! #![doc(html_root_url="https://docs.rs/arrayvec/0.6/")] #![cfg_attr(not(feature="std"), no_std)] -#![cfg_attr(feature="unstable-const-fn", feature(const_fn, const_maybe_uninit_assume_init, const_panic))] #[cfg(feature="serde")] extern crate serde; @@ -37,7 +34,7 @@ macro_rules! assert_capacity_limit { ($cap:expr) => { if std::mem::size_of::() > std::mem::size_of::() { if $cap > LenUint::MAX as usize { - panic!("ArrayVec: largest supported capacity is u32::MAX") + [/*ArrayVec: largest supported capacity is u32::MAX*/][$cap] } } } @@ -48,6 +45,7 @@ mod arrayvec; mod array_string; mod char; mod errors; +mod utils; pub use crate::array_string::ArrayString; pub use crate::errors::CapacityError; diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..b8e5ddb --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,11 @@ +use std::marker::PhantomData; +use std::mem::MaybeUninit; + +pub(crate) struct MakeMaybeUninit(PhantomData T>); + +impl MakeMaybeUninit { + pub(crate) const VALUE: MaybeUninit = MaybeUninit::uninit(); + + pub(crate) const ARRAY: [MaybeUninit; N] = [Self::VALUE; N]; +} + From 165414e0d9709bbf282ee3083198e4c42459d77e Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Sun, 28 Mar 2021 14:49:45 -0300 Subject: [PATCH 2/4] Added tests for construction in const context Updated the capacity panic test --- tests/tests.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index f4698e0..662f5e4 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -718,12 +718,37 @@ fn allow_max_capacity_arrayvec_type() { let _v: ArrayVec<(), {usize::MAX}>; } -#[should_panic(expected="ArrayVec: largest supported")] +#[should_panic(expected="index out of bounds")] #[test] fn deny_max_capacity_arrayvec_value() { if mem::size_of::() <= mem::size_of::() { - panic!("This test does not work on this platform. 'ArrayVec: largest supported'"); + panic!("This test does not work on this platform. 'index out of bounds'"); } // this type is allowed to be used (but can't be constructed) let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new(); } + +#[test] +fn test_arrayvec_const_constructible() { + const OF_U8: ArrayVec, 10> = ArrayVec::new(); + + let mut var = OF_U8; + assert!(var.is_empty()); + assert_eq!(var, ArrayVec::new()); + var.push(vec![3, 5, 8]); + assert_eq!(var[..], [vec![3, 5, 8]]); +} + + +#[test] +fn test_arraystring_const_constructible() { + const AS: ArrayString<10> = ArrayString::new(); + + let mut var = AS; + assert!(var.is_empty()); + assert_eq!(var, ArrayString::new()); + var.push_str("hello"); + assert_eq!(var, *"hello"); +} + + From b24baf1b5d7deaebdafe04b8cfea3e30d83b778d Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 28 Mar 2021 22:47:22 +0200 Subject: [PATCH 3/4] DOC: Tweak formatting and wording of unstable-const-fn feature --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c186386..af11a95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,9 +11,9 @@ //! - Optional //! - Enable serialization for ArrayVec and ArrayString using serde 1.x //! -//! - `unstable-const-fn`: **deprecated**, -//! used to be needed to make [`ArrayVec::new`] and [`ArrayString::new`] `const fn`s, -//! now they are always `const fn`s. +//! - `unstable-const-fn` +//! - **deprecated** (has no effect) +//! - Not needed, [`ArrayVec::new`] and [`ArrayString::new`] are always `const fn` now //! //! ## Rust Version //! From 5303f6911b945cd8679e638d01bbe61c8dbbef02 Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 28 Mar 2021 22:51:01 +0200 Subject: [PATCH 4/4] MAINT: remove unstable-const-fn testing from ci --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d73c4eb..65b6c53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,9 +29,6 @@ jobs: - rust: nightly features: serde experimental: false - - rust: nightly - features: serde unstable-const-fn - experimental: true steps: - uses: actions/checkout@v2