mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-09-26 20:10:24 +00:00
Use static_assertions
instead of trybuild
.
This commit is contained in:
parent
6dbefb4a5c
commit
7bb2f71b55
@ -52,6 +52,7 @@ stable_deref_trait = { version = "1", default-features = false }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ufmt = "0.2"
|
ufmt = "0.2"
|
||||||
|
static_assertions = "1.1.0"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["ufmt", "serde", "defmt-03", "mpmc_large", "portable-atomic-critical-section"]
|
features = ["ufmt", "serde", "defmt-03", "mpmc_large", "portable-atomic-critical-section"]
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
//! Collections of non-`Send`-able things are *not* `Send`
|
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use heapless::{
|
|
||||||
spsc::{Consumer, Producer, Queue},
|
|
||||||
HistoryBuffer, Vec,
|
|
||||||
};
|
|
||||||
|
|
||||||
type NotSend = PhantomData<*const ()>;
|
|
||||||
|
|
||||||
fn is_send<T>()
|
|
||||||
where
|
|
||||||
T: Send,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
is_send::<Consumer<NotSend, 4>>();
|
|
||||||
is_send::<Producer<NotSend, 4>>();
|
|
||||||
is_send::<Queue<NotSend, 4>>();
|
|
||||||
is_send::<Vec<NotSend, 4>>();
|
|
||||||
is_send::<HistoryBuffer<NotSend, 4>>();
|
|
||||||
}
|
|
@ -1,159 +0,0 @@
|
|||||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
|
||||||
--> ui/not-send.rs:19:15
|
|
||||||
|
|
|
||||||
19 | is_send::<Consumer<NotSend, 4>>();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: within `PhantomData<*const ()>`, the trait `Send` is not implemented for `*const ()`
|
|
||||||
note: required because it appears within the type `PhantomData<*const ()>`
|
|
||||||
--> $RUST/core/src/marker.rs
|
|
||||||
|
|
|
||||||
| pub struct PhantomData<T: ?Sized>;
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
= note: required for `Consumer<'_, PhantomData<*const ()>, 4>` to implement `Send`
|
|
||||||
note: required by a bound in `is_send`
|
|
||||||
--> ui/not-send.rs:14:8
|
|
||||||
|
|
|
||||||
12 | fn is_send<T>()
|
|
||||||
| ------- required by a bound in this function
|
|
||||||
13 | where
|
|
||||||
14 | T: Send,
|
|
||||||
| ^^^^ required by this bound in `is_send`
|
|
||||||
|
|
||||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
|
||||||
--> ui/not-send.rs:20:15
|
|
||||||
|
|
|
||||||
20 | is_send::<Producer<NotSend, 4>>();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: within `PhantomData<*const ()>`, the trait `Send` is not implemented for `*const ()`
|
|
||||||
note: required because it appears within the type `PhantomData<*const ()>`
|
|
||||||
--> $RUST/core/src/marker.rs
|
|
||||||
|
|
|
||||||
| pub struct PhantomData<T: ?Sized>;
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
= note: required for `Producer<'_, PhantomData<*const ()>, 4>` to implement `Send`
|
|
||||||
note: required by a bound in `is_send`
|
|
||||||
--> ui/not-send.rs:14:8
|
|
||||||
|
|
|
||||||
12 | fn is_send<T>()
|
|
||||||
| ------- required by a bound in this function
|
|
||||||
13 | where
|
|
||||||
14 | T: Send,
|
|
||||||
| ^^^^ required by this bound in `is_send`
|
|
||||||
|
|
||||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
|
||||||
--> ui/not-send.rs:21:15
|
|
||||||
|
|
|
||||||
21 | is_send::<Queue<NotSend, 4>>();
|
|
||||||
| ^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: within `Queue<PhantomData<*const ()>, 4>`, the trait `Send` is not implemented for `*const ()`
|
|
||||||
note: required because it appears within the type `PhantomData<*const ()>`
|
|
||||||
--> $RUST/core/src/marker.rs
|
|
||||||
|
|
|
||||||
| pub struct PhantomData<T: ?Sized>;
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `ManuallyDrop<PhantomData<*const ()>>`
|
|
||||||
--> $RUST/core/src/mem/manually_drop.rs
|
|
||||||
|
|
|
||||||
| pub struct ManuallyDrop<T: ?Sized> {
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `MaybeUninit<PhantomData<*const ()>>`
|
|
||||||
--> $RUST/core/src/mem/maybe_uninit.rs
|
|
||||||
|
|
|
||||||
| pub union MaybeUninit<T> {
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `UnsafeCell<MaybeUninit<PhantomData<*const ()>>>`
|
|
||||||
--> $RUST/core/src/cell.rs
|
|
||||||
|
|
|
||||||
| pub struct UnsafeCell<T: ?Sized> {
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
= note: required because it appears within the type `[UnsafeCell<MaybeUninit<PhantomData<*const ()>>>; 4]`
|
|
||||||
note: required because it appears within the type `Queue<PhantomData<*const ()>, 4>`
|
|
||||||
--> $HEAPLESS/src/spsc.rs
|
|
||||||
|
|
|
||||||
| pub struct Queue<T, const N: usize> {
|
|
||||||
| ^^^^^
|
|
||||||
note: required by a bound in `is_send`
|
|
||||||
--> ui/not-send.rs:14:8
|
|
||||||
|
|
|
||||||
12 | fn is_send<T>()
|
|
||||||
| ------- required by a bound in this function
|
|
||||||
13 | where
|
|
||||||
14 | T: Send,
|
|
||||||
| ^^^^ required by this bound in `is_send`
|
|
||||||
|
|
||||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
|
||||||
--> ui/not-send.rs:22:15
|
|
||||||
|
|
|
||||||
22 | is_send::<Vec<NotSend, 4>>();
|
|
||||||
| ^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: within `heapless::vec::VecInner<[MaybeUninit<PhantomData<*const ()>>; 4]>`, the trait `Send` is not implemented for `*const ()`
|
|
||||||
note: required because it appears within the type `PhantomData<*const ()>`
|
|
||||||
--> $RUST/core/src/marker.rs
|
|
||||||
|
|
|
||||||
| pub struct PhantomData<T: ?Sized>;
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `ManuallyDrop<PhantomData<*const ()>>`
|
|
||||||
--> $RUST/core/src/mem/manually_drop.rs
|
|
||||||
|
|
|
||||||
| pub struct ManuallyDrop<T: ?Sized> {
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `MaybeUninit<PhantomData<*const ()>>`
|
|
||||||
--> $RUST/core/src/mem/maybe_uninit.rs
|
|
||||||
|
|
|
||||||
| pub union MaybeUninit<T> {
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
= note: required because it appears within the type `[MaybeUninit<PhantomData<*const ()>>; 4]`
|
|
||||||
note: required because it appears within the type `heapless::vec::VecInner<[MaybeUninit<PhantomData<*const ()>>; 4]>`
|
|
||||||
--> $HEAPLESS/src/vec.rs
|
|
||||||
|
|
|
||||||
| pub struct VecInner<B: ?Sized + VecDrop> {
|
|
||||||
| ^^^^^^^^
|
|
||||||
note: required by a bound in `is_send`
|
|
||||||
--> ui/not-send.rs:14:8
|
|
||||||
|
|
|
||||||
12 | fn is_send<T>()
|
|
||||||
| ------- required by a bound in this function
|
|
||||||
13 | where
|
|
||||||
14 | T: Send,
|
|
||||||
| ^^^^ required by this bound in `is_send`
|
|
||||||
|
|
||||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
|
||||||
--> ui/not-send.rs:23:15
|
|
||||||
|
|
|
||||||
23 | is_send::<HistoryBuffer<NotSend, 4>>();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: within `HistoryBuffer<PhantomData<*const ()>, 4>`, the trait `Send` is not implemented for `*const ()`
|
|
||||||
note: required because it appears within the type `PhantomData<*const ()>`
|
|
||||||
--> $RUST/core/src/marker.rs
|
|
||||||
|
|
|
||||||
| pub struct PhantomData<T: ?Sized>;
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `ManuallyDrop<PhantomData<*const ()>>`
|
|
||||||
--> $RUST/core/src/mem/manually_drop.rs
|
|
||||||
|
|
|
||||||
| pub struct ManuallyDrop<T: ?Sized> {
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
note: required because it appears within the type `MaybeUninit<PhantomData<*const ()>>`
|
|
||||||
--> $RUST/core/src/mem/maybe_uninit.rs
|
|
||||||
|
|
|
||||||
| pub union MaybeUninit<T> {
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
= note: required because it appears within the type `[MaybeUninit<PhantomData<*const ()>>; 4]`
|
|
||||||
note: required because it appears within the type `HistoryBuffer<PhantomData<*const ()>, 4>`
|
|
||||||
--> $HEAPLESS/src/histbuf.rs
|
|
||||||
|
|
|
||||||
| pub struct HistoryBuffer<T, const N: usize> {
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `is_send`
|
|
||||||
--> ui/not-send.rs:14:8
|
|
||||||
|
|
|
||||||
12 | fn is_send<T>()
|
|
||||||
| ------- required by a bound in this function
|
|
||||||
13 | where
|
|
||||||
14 | T: Send,
|
|
||||||
| ^^^^ required by this bound in `is_send`
|
|
@ -745,7 +745,12 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::Deque;
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use super::Deque;
|
||||||
|
|
||||||
|
// Ensure a `Deque` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(Deque<*const (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn static_new() {
|
fn static_new() {
|
||||||
|
@ -433,10 +433,16 @@ impl<'a, T, const N: usize> Iterator for OldestOrdered<'a, T, N> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::HistoryBuffer;
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use super::HistoryBuffer;
|
||||||
|
|
||||||
|
// Ensure a `HistoryBuffer` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(HistoryBuffer<*const (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn new() {
|
fn new() {
|
||||||
let x: HistoryBuffer<u8, 4> = HistoryBuffer::new_with(1);
|
let x: HistoryBuffer<u8, 4> = HistoryBuffer::new_with(1);
|
||||||
|
@ -1262,10 +1262,17 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{indexmap::Entry, FnvIndexMap};
|
|
||||||
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use super::{BuildHasherDefault, Entry, FnvIndexMap, IndexMap};
|
||||||
|
|
||||||
|
// Ensure a `IndexMap` containing `!Send` keys stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(IndexMap<*const (), (), BuildHasherDefault<()>, 4>: Send);
|
||||||
|
// Ensure a `IndexMap` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(IndexMap<(), *const (), BuildHasherDefault<()>, 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn size() {
|
fn size() {
|
||||||
const CAP: usize = 4;
|
const CAP: usize = 4;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use crate::indexmap::{self, IndexMap};
|
|
||||||
use core::{
|
use core::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
fmt,
|
fmt,
|
||||||
hash::{BuildHasher, Hash},
|
hash::{BuildHasher, Hash},
|
||||||
};
|
};
|
||||||
|
|
||||||
use hash32::{BuildHasherDefault, FnvHasher};
|
use hash32::{BuildHasherDefault, FnvHasher};
|
||||||
|
|
||||||
|
use crate::indexmap::{self, IndexMap};
|
||||||
|
|
||||||
/// An [`IndexSet`] using the default FNV hasher.
|
/// An [`IndexSet`] using the default FNV hasher.
|
||||||
///
|
///
|
||||||
/// A list of all Methods and Traits available for `FnvIndexSet` can be found in
|
/// A list of all Methods and Traits available for `FnvIndexSet` can be found in
|
||||||
@ -659,3 +661,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use super::{BuildHasherDefault, IndexSet};
|
||||||
|
|
||||||
|
// Ensure a `IndexSet` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(IndexSet<*const (), BuildHasherDefault<()>, 4>: Send);
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::Vec;
|
|
||||||
use core::{borrow::Borrow, fmt, mem, ops, slice};
|
use core::{borrow::Borrow, fmt, mem, ops, slice};
|
||||||
|
|
||||||
|
use crate::Vec;
|
||||||
|
|
||||||
/// A fixed capacity map/dictionary that performs lookups via linear search.
|
/// A fixed capacity map/dictionary that performs lookups via linear search.
|
||||||
///
|
///
|
||||||
/// Note that as this map doesn't use hashing so most operations are *O*(n) instead of *O*(1).
|
/// Note that as this map doesn't use hashing so most operations are *O*(n) instead of *O*(1).
|
||||||
@ -492,7 +493,14 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::LinearMap;
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use super::LinearMap;
|
||||||
|
|
||||||
|
// Ensure a `LinearMap` containing `!Send` keys stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(LinearMap<*const (), (), 4>: Send);
|
||||||
|
// Ensure a `LinearMap` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(LinearMap<(), *const (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn static_new() {
|
fn static_new() {
|
||||||
|
@ -294,7 +294,12 @@ unsafe fn enqueue<T>(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Q2;
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use super::{MpMcQueue, Q2};
|
||||||
|
|
||||||
|
// Ensure a `MpMcQueue` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(MpMcQueue<*const (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity() {
|
fn sanity() {
|
||||||
|
@ -743,8 +743,13 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
// Ensure a `SortedLinkedList` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(SortedLinkedList<*const (), LinkedIndexU8, (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn const_new() {
|
fn const_new() {
|
||||||
static mut _V1: SortedLinkedList<u32, LinkedIndexU8, Max, 100> = SortedLinkedList::new_u8();
|
static mut _V1: SortedLinkedList<u32, LinkedIndexU8, Max, 100> = SortedLinkedList::new_u8();
|
||||||
|
13
src/spsc.rs
13
src/spsc.rs
@ -632,7 +632,18 @@ impl<'a, T, const N: usize> Producer<'a, T, N> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
use crate::spsc::Queue;
|
use super::{Consumer, Producer, Queue};
|
||||||
|
|
||||||
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
// Ensure a `Queue` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(Queue<*const (), 4>: Send);
|
||||||
|
|
||||||
|
// Ensure a `Producer` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(Producer<*const (), 4>: Send);
|
||||||
|
|
||||||
|
// Ensure a `Consumer` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(Consumer<*const (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn full() {
|
fn full() {
|
||||||
|
11
src/vec.rs
11
src/vec.rs
@ -1,7 +1,6 @@
|
|||||||
use core::{
|
use core::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
fmt, hash,
|
fmt, hash, mem,
|
||||||
mem,
|
|
||||||
mem::{ManuallyDrop, MaybeUninit},
|
mem::{ManuallyDrop, MaybeUninit},
|
||||||
ops, ptr, slice,
|
ops, ptr, slice,
|
||||||
};
|
};
|
||||||
@ -2079,9 +2078,15 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::Vec;
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
|
use crate::Vec;
|
||||||
|
|
||||||
|
// Ensure a `Vec` containing `!Send` values stays `!Send` itself.
|
||||||
|
assert_not_impl_any!(Vec<*const (), 4>: Send);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn static_new() {
|
fn static_new() {
|
||||||
static mut _V: Vec<i32, 4> = Vec::new();
|
static mut _V: Vec<i32, 4> = Vec::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user