From 4932eb27dfb987f2f540a431bb2e22f50cf358d9 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 3 May 2019 14:00:28 +0200 Subject: [PATCH 1/2] use core::mem::MaybeUninit; drop min-const-fn and smaller-atomics features --- CHANGELOG.md | 15 ++++++++ Cargo.toml | 11 +++--- ci/script.sh | 10 ++--- src/__core.rs | 54 --------------------------- src/binary_heap.rs | 29 +++++++++------ src/const_fn.rs | 33 ----------------- src/de.rs | 32 +++++++--------- src/indexmap.rs | 69 ++++++++++++---------------------- src/indexset.rs | 52 ++++++++++---------------- src/lib.rs | 29 ++++----------- src/linear_map.rs | 48 ++++++------------------ src/pool/mod.rs | 32 ++++------------ src/pool/singleton.rs | 8 ++-- src/sealed.rs | 8 +--- src/ser.rs | 16 +++----- src/spsc/mod.rs | 86 +++++++++++++++++-------------------------- src/spsc/split.rs | 24 ++++++------ src/string.rs | 20 +++------- src/vec.rs | 35 ++++++------------ 19 files changed, 199 insertions(+), 412 deletions(-) delete mode 100644 src/__core.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e18cc71..b9a09a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.5.0] - 2019-06-xx + +### Removed + +- [breaking-change] The "smaller-atomics" feature has been removed. It is now + always enabled. + +- [breaking-change] The "min-const-fn" feature has been removed. It is now + always enabled. + +- [breaking-change] The MSRV has been bumped to Rust 1.36.0. + +- [breaking-change] The version of the `generic-array` dependency has been + bumped to v0.13.0. + ## [v0.4.4] - 2019-05-02 ### Added diff --git a/Cargo.toml b/Cargo.toml index 729970f4..f74f9755 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ categories = [ ] description = "`static` friendly data structures that don't require dynamic memory allocation" documentation = "https://japaric.github.io/heapless/heapless/index.html" +edition = "2018" keywords = [ "static", "no-heap", @@ -16,19 +17,17 @@ keywords = [ license = "MIT OR Apache-2.0" name = "heapless" repository = "https://github.com/japaric/heapless" -version = "0.4.4" +version = "0.5.0-alpha.1" [features] -const-fn = ["min-const-fn"] -min-const-fn = [] -smaller-atomics = [] +const-fn = [] [dev-dependencies] scoped_threadpool = "0.1.8" [dependencies] as-slice = "0.1.0" -generic-array = "0.11.0" +generic-array = "0.13.0" hash32 = "0.1.0" [dependencies.serde] @@ -37,4 +36,4 @@ optional = true default-features = false [package.metadata.docs.rs] -features = ["const-fn", "smaller-atomics"] \ No newline at end of file +features = ["const-fn"] \ No newline at end of file diff --git a/ci/script.sh b/ci/script.sh index 495e8c09..6665d22a 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -3,7 +3,7 @@ set -euxo pipefail main() { cargo check --target $TARGET --features 'serde' if [ $TRAVIS_RUST_VERSION = nightly ]; then - cargo check --target $TARGET --features 'const-fn smaller-atomics' + cargo check --target $TARGET --features 'const-fn' fi if [ $TARGET = x86_64-unknown-linux-gnu ]; then @@ -11,17 +11,17 @@ main() { cargo test --target $TARGET --release --features 'serde' if [ $TRAVIS_RUST_VERSION = nightly ]; then - cargo test --target $TARGET --features 'const-fn smaller-atomics' - cargo test --target $TARGET --release --features 'const-fn smaller-atomics' + cargo test --target $TARGET --features 'const-fn' + cargo test --target $TARGET --release --features 'const-fn' export RUSTFLAGS="-Z sanitizer=thread" export RUST_TEST_THREADS=1 export TSAN_OPTIONS="suppressions=$(pwd)/blacklist.txt" cargo test --test tsan --target $TARGET - cargo test --test tsan --target $TARGET --features 'const-fn smaller-atomics' + cargo test --test tsan --target $TARGET --features 'const-fn' cargo test --test tsan --target $TARGET --release - cargo test --test tsan --target $TARGET --release --features 'const-fn smaller-atomics' + cargo test --test tsan --target $TARGET --release --features 'const-fn' fi fi } diff --git a/src/__core.rs b/src/__core.rs deleted file mode 100644 index 79d6c538..00000000 --- a/src/__core.rs +++ /dev/null @@ -1,54 +0,0 @@ -/// Temporary fork of some stuff in `core` that's doesn't have a `const fn` API - -pub mod mem { - #[cfg(not(feature = "const-fn"))] - pub use core::mem; - pub use core::mem::{replace, zeroed, ManuallyDrop}; - - // See RFC 1892 - #[cfg(feature = "const-fn")] - pub union MaybeUninit { - uninit: (), - value: ManuallyDrop, - } - - // workaround to get this to compile on stable ("unions with non-`Copy` fields are unstable") - #[cfg(not(feature = "const-fn"))] - pub struct MaybeUninit { - value: ManuallyDrop, - } - - impl MaybeUninit { - #[cfg(feature = "const-fn")] - pub const unsafe fn uninitialized() -> Self { - MaybeUninit { uninit: () } - } - - #[cfg(not(feature = "const-fn"))] - pub unsafe fn uninitialized() -> Self { - MaybeUninit { - value: ManuallyDrop::new(mem::uninitialized()), - } - } - - /// Get a reference to the contained value. - /// - /// # Unsafety - /// - /// It is up to the caller to guarantee that the the `MaybeUninit` really is in an - /// initialized state, otherwise this will immediately cause undefined behavior. - pub unsafe fn get_ref(&self) -> &T { - &*self.value - } - - /// Get a mutable reference to the contained value. - /// - /// # Unsafety - /// - /// It is up to the caller to guarantee that the the `MaybeUninit` really is in an - /// initialized state, otherwise this will immediately cause undefined behavior. - pub unsafe fn get_mut(&mut self) -> &mut T { - &mut *self.value - } - } -} diff --git a/src/binary_heap.rs b/src/binary_heap.rs index 7010037f..7870fed1 100644 --- a/src/binary_heap.rs +++ b/src/binary_heap.rs @@ -8,14 +8,17 @@ // heap can also be converted to a sorted vector in-place, allowing it to be used for an `O(n log // n)` in-place heapsort. -use core::cmp::Ordering; -use core::marker::PhantomData; -use core::mem::ManuallyDrop; -use core::{mem, ptr, slice, fmt}; +use core::{ + cmp::Ordering, + fmt, + marker::PhantomData, + mem::{self, ManuallyDrop}, + ptr, slice, +}; use generic_array::ArrayLength; -use Vec; +use crate::Vec; /// Min-heap pub enum Min {} @@ -206,7 +209,7 @@ where /// /// } /// ``` - pub fn iter(&self) -> slice::Iter { + pub fn iter(&self) -> slice::Iter<'_, T> { self.data.iter() } @@ -214,7 +217,7 @@ where /// /// **WARNING** Mutating the items in the binary heap can leave the heap in an inconsistent /// state. - pub fn iter_mut(&mut self) -> slice::IterMut { + pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { self.data.iter_mut() } @@ -344,7 +347,7 @@ where /// (because it was moved from or duplicated). /// In drop, `Hole` will restore the slice by filling the hole /// position with the value that was originally removed. -struct Hole<'a, T: 'a> { +struct Hole<'a, T> { data: &'a mut [T], /// `elt` is always `Some` from new until drop. elt: ManuallyDrop, @@ -441,9 +444,9 @@ impl fmt::Debug for BinaryHeap where N: ArrayLength, K: Kind, - T: Ord + fmt::Debug + T: Ord + fmt::Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } } @@ -466,8 +469,10 @@ where mod tests { use std::vec::Vec; - use binary_heap::{self, BinaryHeap, Min}; - use consts::*; + use crate::{ + binary_heap::{self, BinaryHeap, Min}, + consts::*, + }; #[cfg(feature = "const-fn")] #[test] diff --git a/src/const_fn.rs b/src/const_fn.rs index e962e74d..e4286c64 100644 --- a/src/const_fn.rs +++ b/src/const_fn.rs @@ -33,36 +33,3 @@ macro_rules! const_fn { fn $($f)* ); } - -#[cfg(not(armv6m))] -macro_rules! min_const_fn { - ($(#[$attr:meta])* pub const unsafe fn $($f:tt)*) => ( - - $(#[$attr])* - #[cfg(feature = "min-const-fn")] - pub const unsafe fn $($f)* - - $(#[$attr])* - #[cfg(not(feature = "min-const-fn"))] - pub unsafe fn $($f)* - ); - ($(#[$attr:meta])* pub const fn $($f:tt)*) => ( - - $(#[$attr])* - #[cfg(feature = "min-const-fn")] - pub const fn $($f)* - - $(#[$attr])* - #[cfg(not(feature = "min-const-fn"))] - pub fn $($f)* - ); - ($(#[$attr:meta])* const fn $($f:tt)*) => ( - $(#[$attr])* - #[cfg(feature = "min-const-fn")] - const fn $($f)* - - $(#[$attr])* - #[cfg(not(feature = "min-const-fn"))] - fn $($f)* - ); -} diff --git a/src/de.rs b/src/de.rs index 0ff6029b..9028a11d 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,18 +1,14 @@ -use core::fmt; -use core::marker::PhantomData; +use core::{fmt, marker::PhantomData}; use generic_array::{typenum::PowerOfTwo, ArrayLength}; use hash32::{BuildHasherDefault, Hash, Hasher}; use serde::de::{self, Deserialize, Deserializer, Error, MapAccess, SeqAccess}; -use super::binary_heap::Kind as BinaryHeapKind; -use super::indexmap::{Bucket, Pos}; -use BinaryHeap; -use IndexMap; -use IndexSet; -use LinearMap; -use String; -use Vec; +use crate::{ + binary_heap, + indexmap::{Bucket, Pos}, + BinaryHeap, IndexMap, IndexSet, LinearMap, String, Vec, +}; // Sequential containers @@ -20,7 +16,7 @@ impl<'de, T, N, KIND> Deserialize<'de> for BinaryHeap where T: Ord + Deserialize<'de>, N: ArrayLength, - KIND: BinaryHeapKind, + KIND: binary_heap::Kind, { fn deserialize(deserializer: D) -> Result where @@ -32,11 +28,11 @@ where where T: Ord + Deserialize<'de>, N: ArrayLength, - KIND: BinaryHeapKind, + KIND: binary_heap::Kind, { type Value = BinaryHeap; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") } @@ -79,7 +75,7 @@ where { type Value = IndexSet>; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") } @@ -120,7 +116,7 @@ where { type Value = Vec; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") } @@ -167,7 +163,7 @@ where { type Value = IndexMap>; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a map") } @@ -210,7 +206,7 @@ where { type Value = LinearMap; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a map") } @@ -251,7 +247,7 @@ where { type Value = String; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!( formatter, "a string no more than {} bytes long", diff --git a/src/indexmap.rs b/src/indexmap.rs index 05cec4cd..e86dc01e 100644 --- a/src/indexmap.rs +++ b/src/indexmap.rs @@ -1,15 +1,16 @@ -use core::borrow::Borrow; -use core::iter::FromIterator; -use core::num::NonZeroU32; -use core::{fmt, ops, slice}; - -use generic_array::typenum::PowerOfTwo; -use generic_array::{ArrayLength, GenericArray}; +use core::{ + borrow::Borrow, + fmt, + iter::FromIterator, + mem::{self, MaybeUninit}, + num::NonZeroU32, + ops, slice, +}; +use generic_array::{typenum::PowerOfTwo, ArrayLength, GenericArray}; use hash32::{BuildHasher, BuildHasherDefault, FnvHasher, Hash, Hasher}; -use Vec; -use __core::mem; +use crate::Vec; /// An `IndexMap` using the default FNV hasher pub type FnvIndexMap = IndexMap>; @@ -102,7 +103,7 @@ where fn new() -> Self { CoreMap { entries: Vec::new(), - indices: unsafe { mem::zeroed() }, + indices: unsafe { MaybeUninit::zeroed().assume_init() }, } } @@ -440,7 +441,7 @@ where /// println!("key: {} val: {}", key, val); /// } /// ``` - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, K, V> { Iter { iter: self.core.entries.iter(), } @@ -465,7 +466,7 @@ where /// println!("key: {} val: {}", key, val); /// } /// ``` - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { IterMut { iter: self.core.entries.iter_mut(), } @@ -762,7 +763,7 @@ where S: BuildHasher, N: ArrayLength> + ArrayLength>, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.iter()).finish() } } @@ -805,10 +806,8 @@ where S: BuildHasher, N: ArrayLength> + ArrayLength>, { - } - impl Extend<(K, V)> for IndexMap where K: Eq + Hash, @@ -884,19 +883,11 @@ where } } -pub struct Iter<'a, K, V> -where - K: 'a, - V: 'a, -{ +pub struct Iter<'a, K, V> { iter: slice::Iter<'a, Bucket>, } -impl<'a, K, V> Iterator for Iter<'a, K, V> -where - K: 'a, - V: 'a, -{ +impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option { @@ -904,11 +895,7 @@ where } } -impl<'a, K, V> Clone for Iter<'a, K, V> -where - K: 'a, - V: 'a, -{ +impl<'a, K, V> Clone for Iter<'a, K, V> { fn clone(&self) -> Self { Self { iter: self.iter.clone(), @@ -916,19 +903,11 @@ where } } -pub struct IterMut<'a, K, V> -where - K: 'a, - V: 'a, -{ +pub struct IterMut<'a, K, V> { iter: slice::IterMut<'a, Bucket>, } -impl<'a, K, V> Iterator for IterMut<'a, K, V> -where - K: 'a, - V: 'a, -{ +impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option { @@ -954,8 +933,7 @@ mod tests { use generic_array::typenum::Unsigned; - use consts::*; - use FnvIndexMap; + use crate::{consts::*, FnvIndexMap}; #[test] fn size() { @@ -973,14 +951,13 @@ mod tests { ) } - #[test] fn partial_eq() { { let mut a: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); a.insert("k1", "v1").unwrap(); - let mut b: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); + let mut b: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); b.insert("k1", "v1").unwrap(); assert!(a == b); @@ -991,11 +968,11 @@ mod tests { } { - let mut a: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); + let mut a: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); a.insert("k1", "v1").unwrap(); a.insert("k2", "v2").unwrap(); - let mut b: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); + let mut b: FnvIndexMap<_, _, U4> = FnvIndexMap::new(); b.insert("k2", "v2").unwrap(); b.insert("k1", "v1").unwrap(); diff --git a/src/indexset.rs b/src/indexset.rs index 395c1ca5..4c80fa17 100644 --- a/src/indexset.rs +++ b/src/indexset.rs @@ -1,12 +1,9 @@ -use core::borrow::Borrow; -use core::fmt; -use core::iter::FromIterator; +use core::{borrow::Borrow, fmt, iter::FromIterator}; -use generic_array::typenum::PowerOfTwo; -use generic_array::ArrayLength; +use generic_array::{typenum::PowerOfTwo, ArrayLength}; use hash32::{BuildHasher, BuildHasherDefault, FnvHasher, Hash, Hasher}; -use indexmap::{self, Bucket, IndexMap, Pos}; +use crate::indexmap::{self, Bucket, IndexMap, Pos}; /// An `IndexSet` using the default FNV hasher pub type FnvIndexSet = IndexSet>; @@ -104,7 +101,7 @@ where /// println!("{}", x); /// } /// ``` - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T> { Iter { iter: self.map.iter(), } @@ -473,7 +470,7 @@ where S: BuildHasher, N: ArrayLength> + ArrayLength>, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() } } @@ -562,17 +559,11 @@ where } } -pub struct Iter<'a, T> -where - T: 'a, -{ +pub struct Iter<'a, T> { iter: indexmap::Iter<'a, T, ()>, } -impl<'a, T> Iterator for Iter<'a, T> -where - T: 'a, -{ +impl<'a, T> Iterator for Iter<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { @@ -580,10 +571,7 @@ where } } -impl<'a, T> Clone for Iter<'a, T> -where - T: 'a, -{ +impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Self { Self { iter: self.iter.clone(), @@ -593,9 +581,9 @@ where pub struct Difference<'a, T, N, S> where - S: 'a + BuildHasher, - T: 'a + Eq + Hash, - N: 'a + ArrayLength> + ArrayLength>, + S: BuildHasher, + T: Eq + Hash, + N: ArrayLength> + ArrayLength>, { iter: Iter<'a, T>, other: &'a IndexSet, @@ -603,9 +591,9 @@ where impl<'a, T, N, S> Iterator for Difference<'a, T, N, S> where - S: 'a + BuildHasher, - T: 'a + Eq + Hash, - N: 'a + ArrayLength> + ArrayLength>, + S: BuildHasher, + T: Eq + Hash, + N: ArrayLength> + ArrayLength>, { type Item = &'a T; @@ -621,9 +609,9 @@ where pub struct Intersection<'a, T, N, S> where - S: 'a + BuildHasher, - T: 'a + Eq + Hash, - N: 'a + ArrayLength> + ArrayLength>, + S: BuildHasher, + T: Eq + Hash, + N: ArrayLength> + ArrayLength>, { iter: Iter<'a, T>, other: &'a IndexSet, @@ -631,9 +619,9 @@ where impl<'a, T, N, S> Iterator for Intersection<'a, T, N, S> where - S: 'a + BuildHasher, - T: 'a + Eq + Hash, - N: 'a + ArrayLength> + ArrayLength>, + S: BuildHasher, + T: Eq + Hash, + N: ArrayLength> + ArrayLength>, { type Item = &'a T; diff --git a/src/lib.rs b/src/lib.rs index 336f40cc..eeef37fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,7 +57,7 @@ //! //! # Minimum Supported Rust Version (MSRV) //! -//! This crate is guaranteed to compile on stable Rust 1.30 and up with its default set of features. +//! This crate is guaranteed to compile on stable Rust 1.36 and up with its default set of features. //! It *might* compile on older versions but that may change in any new patch release. //! //! # Cargo features @@ -79,28 +79,14 @@ //! //! - `"const-fn"` -- Enables the nightly `const_fn` and `untagged_unions` features and makes most //! `new` methods `const`. This way they can be used to initialize static memory at compile time. -//! -//! - `"min-const-fn"` -- Turns `Pool::new` into a const fn and makes the `pool!` macro available. -//! This bumps the required Rust version to 1.31.0. -//! -//! - `"smaller-atomics"` -- Lets you initialize `spsc::Queue`s with smaller head / tail indices -//! (they default to `usize`), shrinking the overall size of the queue. -#![allow(warnings)] -#![deny(missing_docs)] -#![deny(warnings)] #![cfg_attr(feature = "const-fn", feature(const_fn))] -#![cfg_attr(feature = "const-fn", feature(untagged_unions))] -#![no_std] - -extern crate as_slice; -extern crate generic_array; -extern crate hash32; -#[cfg(test)] -extern crate std; - -#[cfg(feature = "serde")] -extern crate serde; +#![cfg_attr(not(test), no_std)] +#![deny(missing_docs)] +#![deny(rust_2018_compatibility)] +#![deny(rust_2018_idioms)] +#![deny(warnings)] +#![feature(maybe_uninit)] #[macro_use] mod const_fn; @@ -131,5 +117,4 @@ pub mod binary_heap; pub mod pool; pub mod spsc; -mod __core; mod sealed; diff --git a/src/linear_map.rs b/src/linear_map.rs index 9412e490..24b9d32d 100644 --- a/src/linear_map.rs +++ b/src/linear_map.rs @@ -1,10 +1,8 @@ -use core::borrow::Borrow; -use core::{mem, ops, slice, fmt}; -use core::iter::FromIterator; +use core::{borrow::Borrow, fmt, iter::FromIterator, mem, ops, slice}; use generic_array::ArrayLength; -use Vec; +use crate::Vec; /// A fixed capacity map / dictionary that performs lookups via linear search /// @@ -232,7 +230,7 @@ where /// println!("key: {} val: {}", key, val); /// } /// ``` - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, K, V> { Iter { iter: self.buffer.iter(), } @@ -261,7 +259,7 @@ where /// println!("key: {} val: {}", key, val); /// } /// ``` - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { IterMut { iter: self.buffer.iter_mut(), } @@ -370,7 +368,6 @@ where N: ArrayLength<(K, V)>, K: Borrow + Eq, Q: Eq + ?Sized, - V: 'a, { type Output = V; @@ -384,7 +381,6 @@ where N: ArrayLength<(K, V)>, K: Borrow + Eq, Q: Eq + ?Sized, - V: 'a, { fn index_mut(&mut self, key: &Q) -> &mut V { self.get_mut(key).expect("no entry found for key") @@ -420,7 +416,7 @@ where K: Eq + fmt::Debug, V: fmt::Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.iter()).finish() } } @@ -487,19 +483,11 @@ where } } -pub struct Iter<'a, K, V> -where - K: 'a, - V: 'a, -{ +pub struct Iter<'a, K, V> { iter: slice::Iter<'a, (K, V)>, } -impl<'a, K, V> Iterator for Iter<'a, K, V> -where - K: 'a, - V: 'a, -{ +impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option { @@ -507,11 +495,7 @@ where } } -impl<'a, K, V> Clone for Iter<'a, K, V> -where - K: 'a, - V: 'a, -{ +impl<'a, K, V> Clone for Iter<'a, K, V> { fn clone(&self) -> Self { Self { iter: self.iter.clone(), @@ -519,19 +503,11 @@ where } } -pub struct IterMut<'a, K, V> -where - K: 'a, - V: 'a, -{ +pub struct IterMut<'a, K, V> { iter: slice::IterMut<'a, (K, V)>, } -impl<'a, K, V> Iterator for IterMut<'a, K, V> -where - K: 'a, - V: 'a, -{ +impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option { @@ -562,11 +538,9 @@ where { } -#[cfg(feature = "const-fn")] // Remove this if there are more tests #[cfg(test)] mod test { - use consts::*; - use LinearMap; + use crate::{consts::*, LinearMap}; #[cfg(feature = "const-fn")] #[test] diff --git a/src/pool/mod.rs b/src/pool/mod.rs index dd971694..4a8bdd66 100644 --- a/src/pool/mod.rs +++ b/src/pool/mod.rs @@ -159,7 +159,6 @@ use core::{ ptr::{self, NonNull}, sync::atomic::AtomicPtr, }; - #[cfg(not(armv6m))] use core::{any::TypeId, mem, sync::atomic::Ordering}; @@ -185,14 +184,12 @@ unsafe impl Sync for Pool {} unsafe impl Send for Pool {} impl Pool { - min_const_fn! { - /// Creates a new empty pool - pub const fn new() -> Self { - Pool { - head: AtomicPtr::new(ptr::null_mut()), + /// Creates a new empty pool + pub const fn new() -> Self { + Pool { + head: AtomicPtr::new(ptr::null_mut()), - _not_send_or_sync: PhantomData, - } + _not_send_or_sync: PhantomData, } } @@ -386,7 +383,7 @@ impl fmt::Debug for Box where T: fmt::Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::fmt(self, f) } } @@ -395,7 +392,7 @@ impl fmt::Display for Box where T: fmt::Display, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::fmt(self, f) } } @@ -454,13 +451,8 @@ mod tests { fn grow() { static mut MEMORY: [u8; 1024] = [0; 1024]; - #[cfg(feature = "min-const-fn")] static POOL: Pool<[u8; 128]> = Pool::new(); - #[allow(non_snake_case)] - #[cfg(not(feature = "min-const-fn"))] - let POOL: Pool<[u8; 128]> = Pool::new(); - unsafe { POOL.grow(&mut MEMORY); } @@ -474,13 +466,8 @@ mod tests { fn sanity() { static mut MEMORY: [u8; 31] = [0; 31]; - #[cfg(feature = "min-const-fn")] static POOL: Pool = Pool::new(); - #[allow(non_snake_case)] - #[cfg(not(feature = "min-const-fn"))] - let POOL: Pool = Pool::new(); - // empty pool assert!(POOL.alloc().is_none()); @@ -519,13 +506,8 @@ mod tests { static mut MEMORY: [u8; 31] = [0; 31]; - #[cfg(feature = "min-const-fn")] static POOL: Pool = Pool::new(); - #[allow(non_snake_case)] - #[cfg(not(feature = "min-const-fn"))] - let POOL: Pool = Pool::new(); - POOL.grow(unsafe { &mut MEMORY }); let x = POOL.alloc().unwrap().init(X::new()); diff --git a/src/pool/singleton.rs b/src/pool/singleton.rs index adb37e33..e15cf480 100644 --- a/src/pool/singleton.rs +++ b/src/pool/singleton.rs @@ -15,7 +15,7 @@ use as_slice::{AsMutSlice, AsSlice}; use super::{Init, Uninit}; /// Instantiates a pool as a global singleton -#[cfg(all(any(armv7m, test), feature = "min-const-fn"))] +#[cfg(any(armv7m, test))] #[macro_export] macro_rules! pool { ($ident:ident: $ty:ty) => { @@ -153,7 +153,7 @@ where P: Pool, P::Data: fmt::Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::fmt(self, f) } } @@ -163,7 +163,7 @@ where P: Pool, P::Data: fmt::Display, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::fmt(self, f) } } @@ -270,7 +270,7 @@ where } } -#[cfg(all(test, feature = "min-const-fn"))] +#[cfg(test)] mod tests { use core::{ mem, diff --git a/src/sealed.rs b/src/sealed.rs index fd4e38f4..8309129a 100644 --- a/src/sealed.rs +++ b/src/sealed.rs @@ -1,8 +1,6 @@ -use core::sync::atomic::{self, AtomicUsize, Ordering}; -#[cfg(feature = "smaller-atomics")] -use core::sync::atomic::{AtomicU16, AtomicU8}; +use core::sync::atomic::{self, AtomicU16, AtomicU8, AtomicUsize, Ordering}; -use spsc::{MultiCore, SingleCore}; +use crate::spsc::{MultiCore, SingleCore}; pub unsafe trait XCore { fn is_multi_core() -> bool; @@ -38,7 +36,6 @@ pub unsafe trait Uxx: Into + Send { C: XCore; } -#[cfg(feature = "smaller-atomics")] unsafe impl Uxx for u8 { fn truncate(x: usize) -> Self { let max = ::core::u8::MAX; @@ -79,7 +76,6 @@ unsafe impl Uxx for u8 { } } -#[cfg(feature = "smaller-atomics")] unsafe impl Uxx for u16 { fn truncate(x: usize) -> Self { let max = ::core::u16::MAX; diff --git a/src/ser.rs b/src/ser.rs index 085e15ef..60f1b003 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -1,16 +1,12 @@ -use hash32::{BuildHasher, Hash}; - use generic_array::{typenum::PowerOfTwo, ArrayLength}; +use hash32::{BuildHasher, Hash}; use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer}; -use super::binary_heap::Kind as BinaryHeapKind; -use super::indexmap::{Bucket, Pos}; -use BinaryHeap; -use IndexMap; -use IndexSet; -use LinearMap; -use String; -use Vec; +use crate::{ + binary_heap::Kind as BinaryHeapKind, + indexmap::{Bucket, Pos}, + BinaryHeap, IndexMap, IndexSet, LinearMap, String, Vec, +}; // Sequential containers diff --git a/src/spsc/mod.rs b/src/spsc/mod.rs index f32d4413..fb7e4278 100644 --- a/src/spsc/mod.rs +++ b/src/spsc/mod.rs @@ -1,15 +1,12 @@ //! Single producer single consumer queue -use core::cell::UnsafeCell; -use core::marker::PhantomData; -use core::{ptr, fmt, hash}; +use core::{cell::UnsafeCell, fmt, hash, marker::PhantomData, mem::MaybeUninit, ptr}; use generic_array::{ArrayLength, GenericArray}; use hash32; -pub use self::split::{Consumer, Producer}; -use __core::mem::MaybeUninit; -use sealed; +use crate::sealed; +pub use split::{Consumer, Producer}; mod split; @@ -176,7 +173,7 @@ where } /// Iterates from the front of the queue to the back - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T, N, U, C> { Iter { rb: self, index: 0, @@ -185,7 +182,7 @@ where } /// Returns an iterator that allows modifying each value. - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, T, N, U, C> { let len = self.len_usize(); IterMut { rb: self, @@ -224,7 +221,7 @@ where U: sealed::Uxx, C: sealed::XCore, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } } @@ -259,7 +256,6 @@ where } } - impl<'a, T, N, U, C> IntoIterator for &'a Queue where N: ArrayLength, @@ -298,7 +294,7 @@ macro_rules! impl_ { /// Creates an empty queue with a fixed capacity of `N` pub const fn $uxx() -> Self { Queue { - buffer: unsafe { MaybeUninit::uninitialized() }, + buffer: MaybeUninit::uninit(), head: Atomic::new(0), tail: Atomic::new(0), } @@ -314,7 +310,7 @@ macro_rules! impl_ { /// Creates an empty queue with a fixed capacity of `N` (single core variant) pub const unsafe fn $uxx_sc() -> Self { Queue { - buffer: MaybeUninit::uninitialized(), + buffer: MaybeUninit::uninit(), head: Atomic::new(0), tail: Atomic::new(0), } @@ -334,10 +330,10 @@ macro_rules! impl_ { let head = self.head.get_mut(); let tail = self.tail.get_mut(); - let buffer = unsafe { self.buffer.get_ref() }; + let p = self.buffer.as_ptr(); if *head != *tail { - let item = unsafe { ptr::read(buffer.get_unchecked(usize::from(*head % cap))) }; + let item = unsafe { (p as *const T).add(usize::from(*head % cap)).read() }; *head = head.wrapping_add(1); Some(item) } else { @@ -373,12 +369,12 @@ macro_rules! impl_ { let cap = self.capacity(); let tail = self.tail.get_mut(); - let buffer = self.buffer.get_mut(); - // NOTE(ptr::write) the memory slot that we are about to write to is // uninitialized. We use `ptr::write` to avoid running `T`'s destructor on the // uninitialized memory - ptr::write(buffer.get_unchecked_mut(usize::from(*tail % cap)), item); + (self.buffer.as_mut_ptr() as *mut T) + .add(usize::from(*tail % cap)) + .write(item); *tail = tail.wrapping_add(1); } @@ -403,7 +399,7 @@ macro_rules! impl_ { { fn clone(&self) -> Self { let mut new: Queue = Queue { - buffer: unsafe { MaybeUninit::uninitialized() }, + buffer: MaybeUninit::uninit(), head: Atomic::new(0), tail: Atomic::new(0), }; @@ -417,7 +413,6 @@ macro_rules! impl_ { new } } - }; } @@ -445,9 +440,7 @@ where } } -#[cfg(feature = "smaller-atomics")] impl_!(u8, u8_sc); -#[cfg(feature = "smaller-atomics")] impl_!(u16, u16_sc); impl_!(usize, usize_sc); @@ -463,10 +456,7 @@ where { fn eq(&self, other: &Queue) -> bool { self.len_usize() == other.len_usize() - && self - .iter() - .zip(other.iter()) - .all(|(v1, v2)| v1 == v2) + && self.iter().zip(other.iter()).all(|(v1, v2)| v1 == v2) } } @@ -477,16 +467,14 @@ where U: sealed::Uxx, C: sealed::XCore, { - } /// An iterator over the items of a queue pub struct Iter<'a, T, N, U, C> where - N: ArrayLength + 'a, - T: 'a, - U: 'a + sealed::Uxx, - C: 'a + sealed::XCore, + N: ArrayLength, + U: sealed::Uxx, + C: sealed::XCore, { rb: &'a Queue, index: usize, @@ -495,10 +483,9 @@ where impl<'a, T, N, U, C> Clone for Iter<'a, T, N, U, C> where - N: ArrayLength + 'a, - T: 'a, - U: 'a + sealed::Uxx, - C: 'a + sealed::XCore, + N: ArrayLength, + U: sealed::Uxx, + C: sealed::XCore, { fn clone(&self) -> Self { Self { @@ -512,10 +499,9 @@ where /// A mutable iterator over the items of a queue pub struct IterMut<'a, T, N, U, C> where - N: ArrayLength + 'a, - T: 'a, - U: 'a + sealed::Uxx, - C: 'a + sealed::XCore, + N: ArrayLength, + U: sealed::Uxx, + C: sealed::XCore, { rb: &'a mut Queue, index: usize, @@ -523,13 +509,12 @@ where } macro_rules! iterator { - (struct $name:ident -> $elem:ty, $ptr:ty, $asref:ident, $asptr:ident, $mkref:ident) => { + (struct $name:ident -> $elem:ty, $ptr:ty, $asptr:ident, $mkref:ident) => { impl<'a, T, N, U, C> Iterator for $name<'a, T, N, U, C> where N: ArrayLength, - T: 'a, - U: 'a + sealed::Uxx, - C: 'a + sealed::XCore, + U: sealed::Uxx, + C: sealed::XCore, { type Item = $elem; @@ -538,8 +523,7 @@ macro_rules! iterator { let head = self.rb.head.load_relaxed().into(); let cap = self.rb.capacity().into(); - let buffer = unsafe { self.rb.buffer.$asref() }; - let ptr: $ptr = buffer.$asptr(); + let ptr = self.rb.buffer.$asptr() as $ptr; let i = (head + self.index) % cap; self.index += 1; Some(unsafe { $mkref!(*ptr.offset(i as isize)) }) @@ -563,15 +547,15 @@ macro_rules! make_ref_mut { }; } -iterator!(struct Iter -> &'a T, *const T, get_ref, as_ptr, make_ref); -iterator!(struct IterMut -> &'a mut T, *mut T, get_mut, as_mut_ptr, make_ref_mut); +iterator!(struct Iter -> &'a T, *const T, as_ptr, make_ref); +iterator!(struct IterMut -> &'a mut T, *mut T, as_mut_ptr, make_ref_mut); #[cfg(test)] mod tests { - use consts::*; - use spsc::Queue; use hash32::Hasher; + use crate::{consts::*, spsc::Queue}; + #[cfg(feature = "const-fn")] #[test] fn static_new() { @@ -741,11 +725,7 @@ mod tests { let rb2 = rb1.clone(); assert_eq!(rb1.capacity(), rb2.capacity()); assert_eq!(rb1.len_usize(), rb2.len_usize()); - assert!( - rb1.iter() - .zip(rb2.iter()) - .all(|(v1, v2)| v1 == v2) - ); + assert!(rb1.iter().zip(rb2.iter()).all(|(v1, v2)| v1 == v2)); } #[test] diff --git a/src/spsc/split.rs b/src/spsc/split.rs index b8aa2404..c10b56fe 100644 --- a/src/spsc/split.rs +++ b/src/spsc/split.rs @@ -1,10 +1,11 @@ -use core::marker::PhantomData; -use core::ptr::{self, NonNull}; +use core::{marker::PhantomData, ptr::NonNull}; use generic_array::ArrayLength; -use sealed; -use spsc::{MultiCore, Queue}; +use crate::{ + sealed, + spsc::{MultiCore, Queue}, +}; impl Queue where @@ -110,9 +111,10 @@ macro_rules! impl_ { let rb = self.rb.as_ref(); let cap = rb.capacity(); - let buffer = rb.buffer.get_ref(); - let item = ptr::read(buffer.get_unchecked(usize::from(head % cap))); + let item = (rb.buffer.as_ptr() as *const T) + .add(usize::from(head % cap)) + .read(); rb.head.store_release(head.wrapping_add(1)); // ▲ item } @@ -177,28 +179,26 @@ macro_rules! impl_ { let rb = self.rb.as_mut(); let cap = rb.capacity(); - let buffer = rb.buffer.get_mut(); // NOTE(ptr::write) the memory slot that we are about to write to is // uninitialized. We use `ptr::write` to avoid running `T`'s destructor on the // uninitialized memory - ptr::write(buffer.get_unchecked_mut(usize::from(tail % cap)), item); + (rb.buffer.as_mut_ptr() as *mut T) + .add(usize::from(tail % cap)) + .write(item); rb.tail.store_release(tail.wrapping_add(1)); // ▲ } } }; } -#[cfg(feature = "smaller-atomics")] impl_!(u8); -#[cfg(feature = "smaller-atomics")] impl_!(u16); impl_!(usize); #[cfg(test)] mod tests { - use consts::*; - use spsc::Queue; + use crate::{consts::*, spsc::Queue}; #[test] fn sanity() { diff --git a/src/string.rs b/src/string.rs index b68b0288..83a3d857 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,15 +1,12 @@ -use core::fmt::Write; -use core::str::Utf8Error; -use core::{fmt, hash, ops, str}; - -use hash32; +use core::{fmt, fmt::Write, hash, ops, str, str::Utf8Error}; use generic_array::{ typenum::{consts::*, IsGreaterOrEqual}, ArrayLength, }; +use hash32; -use Vec; +use crate::Vec; /// A fixed capacity [`String`](https://doc.rust-lang.org/std/string/struct.String.html) pub struct String @@ -444,7 +441,7 @@ impl fmt::Debug for String where N: ArrayLength, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let slice: &str = &**self; fmt::Debug::fmt(slice, f) } @@ -454,7 +451,7 @@ impl fmt::Display for String where N: ArrayLength, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let slice: &str = &**self; fmt::Display::fmt(slice, f) } @@ -611,8 +608,7 @@ impl_from_num!(u64, U20); #[cfg(test)] mod tests { - use consts::*; - use {String, Vec}; + use crate::{consts::*, String, Vec}; #[cfg(feature = "const-fn")] #[test] @@ -632,8 +628,6 @@ mod tests { #[test] fn debug() { - extern crate std; - use core::fmt::Write; let s: String = String::from("abcd"); @@ -644,8 +638,6 @@ mod tests { #[test] fn display() { - extern crate std; - use core::fmt::Write; let s: String = String::from("abcd"); diff --git a/src/vec.rs b/src/vec.rs index 7f89bcf9..6855982b 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -1,13 +1,8 @@ -use core::{fmt, ops, ptr, slice}; +use core::{fmt, hash, iter::FromIterator, mem::MaybeUninit, ops, ptr, slice}; use generic_array::{ArrayLength, GenericArray}; use hash32; -use __core::mem::MaybeUninit; - -use core::hash; -use core::iter::FromIterator; - /// A fixed capacity [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html) /// /// # Examples @@ -66,7 +61,7 @@ where /// Constructs a new, empty vector with a fixed capacity of `N` pub const fn new() -> Self { Vec { - buffer: unsafe { MaybeUninit::uninitialized() }, + buffer: MaybeUninit::uninit(), len: 0, } } @@ -126,11 +121,8 @@ where pub(crate) unsafe fn pop_unchecked(&mut self) -> T { debug_assert!(!self.is_empty()); - let buffer = self.buffer.get_ref(); - self.len -= 1; - let item = ptr::read(buffer.get_unchecked(self.len)); - item + (self.buffer.as_ptr() as *const T).add(self.len).read() } /// Appends an `item` to the back of the collection @@ -146,11 +138,12 @@ where } pub(crate) unsafe fn push_unchecked(&mut self, item: T) { - let buffer = self.buffer.get_mut(); - // NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We // use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory - ptr::write(buffer.get_unchecked_mut(self.len), item); + (self.buffer.as_mut_ptr() as *mut T) + .add(self.len) + .write(item); + self.len += 1; } @@ -271,7 +264,7 @@ where T: fmt::Debug, N: ArrayLength, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let slice: &[T] = &**self; slice.fmt(f) } @@ -394,8 +387,7 @@ where type Item = T; fn next(&mut self) -> Option { if self.next < self.vec.len() { - let buffer = unsafe { self.vec.buffer.get_ref() }; - let item = unsafe { ptr::read(buffer.get_unchecked(self.next)) }; + let item = unsafe { (self.vec.buffer.as_ptr() as *const T).add(self.next).read() }; self.next += 1; Some(item) } else { @@ -500,10 +492,9 @@ where type Target = [T]; fn deref(&self) -> &[T] { - let buffer = unsafe { self.buffer.get_ref() }; // NOTE(unsafe) avoid bound checks in the slicing operation // &buffer[..self.len] - unsafe { slice::from_raw_parts(buffer.as_ptr(), self.len) } + unsafe { slice::from_raw_parts(self.buffer.as_ptr() as *const T, self.len) } } } @@ -513,11 +504,10 @@ where { fn deref_mut(&mut self) -> &mut [T] { let len = self.len(); - let buffer = unsafe { self.buffer.get_mut() }; // NOTE(unsafe) avoid bound checks in the slicing operation // &mut buffer[..len] - unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr(), len) } + unsafe { slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as *mut T, len) } } } @@ -563,8 +553,7 @@ where #[cfg(test)] mod tests { - use consts::*; - use Vec; + use crate::{consts::*, Vec}; #[cfg(feature = "const-fn")] #[test] From 2a34835f6a8b08e4eb1b1d2bb91a42778bb4540a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 3 May 2019 15:56:38 +0200 Subject: [PATCH 2/2] ci: remove non-nightly channels --- .travis.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index fceab721..1d74bfac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,22 +2,10 @@ language: rust matrix: include: - # MSRV - - env: TARGET=x86_64-unknown-linux-gnu - rust: 1.30.0 - if: branch != master - - - env: TARGET=x86_64-unknown-linux-gnu - rust: stable - if: branch != master - - - env: TARGET=thumbv6m-none-eabi - rust: beta - if: branch != master - - - env: TARGET=thumbv7m-none-eabi - rust: stable - if: branch != master + # TODO MSRV + # - env: TARGET=x86_64-unknown-linux-gnu + # rust: 1.36.0 + # if: branch != master - env: TARGET=x86_64-unknown-linux-gnu rust: nightly