Use static_assertions instead of trybuild.

This commit is contained in:
Markus Reiter 2024-02-19 10:09:37 +01:00
parent 6dbefb4a5c
commit 7bb2f71b55
No known key found for this signature in database
GPG Key ID: 245293B51702655B
12 changed files with 77 additions and 195 deletions

View File

@ -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"]

View File

@ -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>>();
}

View File

@ -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`

View File

@ -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() {

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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() {

View File

@ -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() {

View File

@ -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();

View File

@ -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() {

View File

@ -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();