diff --git a/CHANGELOG.md b/CHANGELOG.md index 76553c6f50..204d35d81b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fixed a `dropping_references` warning in `LinearMap`. +- Fixed constant asserts not asserting at compile time. ### Removed diff --git a/src/deque.rs b/src/deque.rs index 1d3987080d..740cef533a 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -53,6 +53,11 @@ pub struct Deque { impl Deque { const INIT: MaybeUninit = MaybeUninit::uninit(); + /// ```compile_fail + /// use heapless::Deque; + /// let _: Deque = Deque::new(); + /// ``` + const _ASSERT: () = assert!(N > 0); /// Constructs a new, empty deque with a fixed capacity of `N` /// @@ -67,10 +72,9 @@ impl Deque { /// // allocate the deque in a static variable /// static mut X: Deque = Deque::new(); /// ``` + #[allow(path_statements)] pub const fn new() -> Self { - // Const assert N > 0 - crate::sealed::greater_than_0::(); - + Self::_ASSERT; Self { buffer: [Self::INIT; N], front: 0, diff --git a/src/histbuf.rs b/src/histbuf.rs index 4ccd83b774..ce3b5d4b34 100644 --- a/src/histbuf.rs +++ b/src/histbuf.rs @@ -42,6 +42,11 @@ pub struct HistoryBuffer { impl HistoryBuffer { const INIT: MaybeUninit = MaybeUninit::uninit(); + /// ```compile_failure + /// use heapless::HistoryBuffer; + /// let _: HistoryBuffer = HistoryBuffer::new(); + /// ``` + const _ASSERT: () = assert!(N > 0); /// Constructs a new history buffer. /// @@ -57,10 +62,9 @@ impl HistoryBuffer { /// assert_eq!(x.len(), 0); /// ``` #[inline] + #[allow(path_statements)] pub const fn new() -> Self { - // Const assert - crate::sealed::greater_than_0::(); - + Self::_ASSERT; Self { data: [Self::INIT; N], write_at: 0, diff --git a/src/indexmap.rs b/src/indexmap.rs index e8843db5e8..d937dd695d 100644 --- a/src/indexmap.rs +++ b/src/indexmap.rs @@ -535,11 +535,10 @@ pub struct IndexMap { impl IndexMap, N> { /// Creates an empty `IndexMap`. + #[allow(path_statements)] pub const fn new() -> Self { - // Const assert - crate::sealed::greater_than_1::(); - crate::sealed::power_of_two::(); - + Self::_ASSERT1; + Self::_ASSERT2; IndexMap { build_hasher: BuildHasherDefault::new(), core: CoreMap::new(), @@ -548,6 +547,27 @@ impl IndexMap, N> { } impl IndexMap { + /// ```compile_fail + /// use heapless::FnvIndexMap; + /// let _: FnvIndexMap = FnvIndexMap::new(); + /// ``` + /// + /// ```compile_fail + /// use heapless::FnvIndexMap; + /// let _: FnvIndexMap = FnvIndexMap::default(); + /// ``` + const _ASSERT1: () = assert!(N > 1); + /// ```compile_fail + /// use heapless::FnvIndexMap; + /// let _: FnvIndexMap = FnvIndexMap::new(); + /// ``` + /// + /// ```compile_fail + /// use heapless::FnvIndexMap; + /// let _: FnvIndexMap = FnvIndexMap::default(); + /// ``` + const _ASSERT2: () = assert!(N.is_power_of_two()); + /// Returns the number of elements the map can hold pub fn capacity(&self) -> usize { N @@ -1023,11 +1043,10 @@ impl Default for IndexMap where S: Default, { + #[allow(path_statements)] fn default() -> Self { - // Const assert - crate::sealed::greater_than_1::(); - crate::sealed::power_of_two::(); - + Self::_ASSERT1; + Self::_ASSERT2; IndexMap { build_hasher: <_>::default(), core: CoreMap::new(), diff --git a/src/lib.rs b/src/lib.rs index 130120908d..52517c39c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -134,5 +134,3 @@ pub mod spsc; #[cfg(feature = "ufmt")] mod ufmt; - -mod sealed; diff --git a/src/mpmc.rs b/src/mpmc.rs index db38934b66..4c1cde0120 100644 --- a/src/mpmc.rs +++ b/src/mpmc.rs @@ -138,14 +138,24 @@ impl MpMcQueue { const ASSERT: [(); 1] = [()]; + /// ```compile_fail + /// use heapless::mpmc::MpMcQueue; + /// let q: MpMcQueue = MpMcQueue::new(); + /// ``` + const _ASSERT1: () = assert!(N > 1); + /// ```compile_fail + /// use heapless::mpmc::MpMcQueue; + /// let q: MpMcQueue = MpMcQueue::new(); + /// ``` + const _ASSERT2: () = assert!(N.is_power_of_two()); + /// Creates an empty queue + #[allow(path_statements)] pub const fn new() -> Self { - // Const assert - crate::sealed::greater_than_1::(); - crate::sealed::power_of_two::(); - // Const assert on size. Self::ASSERT[!(N < (IntSize::MAX as usize)) as usize]; + Self::_ASSERT1; + Self::_ASSERT2; let mut cell_count = 0; diff --git a/src/sealed.rs b/src/sealed.rs deleted file mode 100644 index cb5ad840ad..0000000000 --- a/src/sealed.rs +++ /dev/null @@ -1,58 +0,0 @@ -#[allow(dead_code)] -#[allow(path_statements)] -pub(crate) const fn smaller_than() { - Assert::::LESS; -} - -#[allow(dead_code)] -#[allow(path_statements)] -pub(crate) const fn greater_than_eq_0() { - Assert::::GREATER_EQ; -} - -#[allow(dead_code)] -#[allow(path_statements)] -pub(crate) const fn greater_than_0() { - Assert::::GREATER; -} - -#[allow(dead_code)] -#[allow(path_statements)] -pub(crate) const fn greater_than_1() { - Assert::::GREATER; -} - -#[allow(dead_code)] -#[allow(path_statements)] -pub(crate) const fn power_of_two() { - Assert::::GREATER; - Assert::::POWER_OF_TWO; -} - -#[allow(dead_code)] -/// Const assert hack -pub struct Assert; - -#[allow(dead_code)] -impl Assert { - /// Const assert hack - pub const GREATER_EQ: usize = L - R; - - /// Const assert hack - pub const LESS_EQ: usize = R - L; - - /// Const assert hack - pub const NOT_EQ: isize = 0 / (R as isize - L as isize); - - /// Const assert hack - pub const EQ: usize = (R - L) + (L - R); - - /// Const assert hack - pub const GREATER: usize = L - R - 1; - - /// Const assert hack - pub const LESS: usize = R - L - 1; - - /// Const assert hack - pub const POWER_OF_TWO: usize = 0 - (L & (L - 1)); -} diff --git a/src/sorted_linked_list.rs b/src/sorted_linked_list.rs index 041895cd3e..135a25b844 100644 --- a/src/sorted_linked_list.rs +++ b/src/sorted_linked_list.rs @@ -147,11 +147,12 @@ macro_rules! impl_index_and_const_new { next: $name::none(), }; + const _ASSERT: () = assert!(N < $max_val); + /// Create a new linked list. + #[allow(path_statements)] pub const fn $new_name() -> Self { - // Const assert N < MAX - crate::sealed::smaller_than::(); - + Self::_ASSERT; let mut list = SortedLinkedList { list: [Self::UNINIT; N], head: $name::none(), diff --git a/src/spsc.rs b/src/spsc.rs index c8085720e7..4b180d16c7 100644 --- a/src/spsc.rs +++ b/src/spsc.rs @@ -125,10 +125,16 @@ impl Queue { (val + 1) % N } + /// ```compile_fail + /// use heapless::spsc::Queue; + /// let q: Queue = Queue::new(); + /// ``` + const _ASSERT: () = assert!(N > 1); + /// Creates an empty queue with a fixed capacity of `N - 1` + #[allow(path_statements)] pub const fn new() -> Self { - // Const assert N > 1 - crate::sealed::greater_than_1::(); + Self::_ASSERT; Queue { head: AtomicUsize::new(0), diff --git a/src/vec.rs b/src/vec.rs index f7e4ae380f..b435c5dc40 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -58,9 +58,6 @@ impl Vec { /// ``` /// `Vec` `const` constructor; wrap the returned value in [`Vec`](../struct.Vec.html) pub const fn new() -> Self { - // Const assert N >= 0 - crate::sealed::greater_than_eq_0::(); - Self { len: 0, buffer: Self::INIT,