mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-09-28 21:10:28 +00:00
Merge pull request #199 from kpp/const_generics
Fix several issues in const generics
This commit is contained in:
commit
aee0817491
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -105,7 +105,7 @@ jobs:
|
||||
toolchain:
|
||||
- stable
|
||||
- nightly
|
||||
- 1.36.0
|
||||
- 1.51.0
|
||||
features:
|
||||
- serde
|
||||
buildtype:
|
||||
@ -242,7 +242,7 @@ jobs:
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.36.0
|
||||
toolchain: 1.51.0
|
||||
target: x86_64-unknown-linux-gnu
|
||||
override: true
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use heapless::{consts, spsc::Queue};
|
||||
use heapless::{spsc::Queue};
|
||||
|
||||
fn main() {
|
||||
let mut q: Queue<u8, consts::U4> = Queue::new();
|
||||
let mut q: Queue<u8, _, _, 4> = Queue::new();
|
||||
|
||||
let (_p, mut _c) = q.split();
|
||||
q.enqueue(0).unwrap();
|
||||
|
@ -3,7 +3,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use heapless::{
|
||||
consts,
|
||||
spsc::{Consumer, Producer, Queue},
|
||||
};
|
||||
|
||||
@ -16,8 +15,8 @@ where
|
||||
}
|
||||
|
||||
fn main() {
|
||||
is_send::<Consumer<NotSend, consts::U4>>();
|
||||
is_send::<Producer<NotSend, consts::U4>>();
|
||||
is_send::<Queue<NotSend, consts::U4>>();
|
||||
is_send::<heapless::Vec<NotSend, consts::U4>>();
|
||||
is_send::<Consumer<NotSend, _, _, 4>>();
|
||||
is_send::<Producer<NotSend, _, _, 4>>();
|
||||
is_send::<Queue<NotSend, _, _, 4>>();
|
||||
is_send::<heapless::Vec<NotSend, 4>>();
|
||||
}
|
||||
|
@ -1,83 +1,69 @@
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:18:5
|
||||
|
|
||||
11 | fn is_send<T>()
|
||||
| ------- required by a bound in this
|
||||
12 | where
|
||||
13 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
18 | 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 ()>`
|
||||
= note: required because of the requirements on the impl of `Send` for `Consumer<'_, PhantomData<*const ()>, _, _, 4_usize>`
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:19:5
|
||||
|
|
||||
19 | is_send::<Consumer<NotSend, consts::U4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
11 | fn is_send<T>()
|
||||
| ------- required by a bound in this
|
||||
12 | where
|
||||
13 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
19 | is_send::<Producer<NotSend, _, _, 4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
|
|
||||
= help: within `std::marker::PhantomData<*const ()>`, the trait `std::marker::Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `std::marker::PhantomData<*const ()>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `heapless::spsc::split::Consumer<'_, std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
|
||||
note: required by `is_send`
|
||||
--> $DIR/not-send.rs:12:1
|
||||
|
|
||||
12 | / fn is_send<T>()
|
||||
13 | | where
|
||||
14 | | T: Send,
|
||||
15 | | {
|
||||
16 | | }
|
||||
| |_^
|
||||
= help: within `PhantomData<*const ()>`, the trait `Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `PhantomData<*const ()>`
|
||||
= note: required because of the requirements on the impl of `Send` for `Producer<'_, PhantomData<*const ()>, _, _, 4_usize>`
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:20:5
|
||||
|
|
||||
20 | is_send::<Producer<NotSend, consts::U4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
11 | fn is_send<T>()
|
||||
| ------- required by a bound in this
|
||||
12 | where
|
||||
13 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
20 | is_send::<Queue<NotSend, _, _, 4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
|
|
||||
= help: within `std::marker::PhantomData<*const ()>`, the trait `std::marker::Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `std::marker::PhantomData<*const ()>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `heapless::spsc::split::Producer<'_, std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
|
||||
note: required by `is_send`
|
||||
--> $DIR/not-send.rs:12:1
|
||||
|
|
||||
12 | / fn is_send<T>()
|
||||
13 | | where
|
||||
14 | | T: Send,
|
||||
15 | | {
|
||||
16 | | }
|
||||
| |_^
|
||||
= help: within `Queue<PhantomData<*const ()>, _, _, 4_usize>`, the trait `Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `PhantomData<*const ()>`
|
||||
= note: required because it appears within the type `[PhantomData<*const ()>; 4]`
|
||||
= note: required because it appears within the type `ManuallyDrop<[PhantomData<*const ()>; 4]>`
|
||||
= note: required because it appears within the type `MaybeUninit<[PhantomData<*const ()>; 4]>`
|
||||
= note: required because it appears within the type `Queue<PhantomData<*const ()>, _, _, 4_usize>`
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:21:5
|
||||
|
|
||||
21 | is_send::<Queue<NotSend, consts::U4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
11 | fn is_send<T>()
|
||||
| ------- required by a bound in this
|
||||
12 | where
|
||||
13 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
21 | is_send::<heapless::Vec<NotSend, 4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
|
|
||||
= help: within `std::marker::PhantomData<*const ()>`, the trait `std::marker::Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `std::marker::PhantomData<*const ()>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
|
||||
= note: required because it appears within the type `std::mem::ManuallyDrop<generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>>`
|
||||
= note: required because it appears within the type `std::mem::MaybeUninit<generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>>`
|
||||
= note: required because it appears within the type `heapless::i::Queue<generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>>`
|
||||
= note: required because it appears within the type `heapless::spsc::Queue<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
|
||||
note: required by `is_send`
|
||||
--> $DIR/not-send.rs:12:1
|
||||
|
|
||||
12 | / fn is_send<T>()
|
||||
13 | | where
|
||||
14 | | T: Send,
|
||||
15 | | {
|
||||
16 | | }
|
||||
| |_^
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:22:5
|
||||
|
|
||||
22 | is_send::<heapless::Vec<NotSend, consts::U4>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
|
||||
|
|
||||
= help: within `std::marker::PhantomData<*const ()>`, the trait `std::marker::Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `std::marker::PhantomData<*const ()>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
|
||||
= note: required because it appears within the type `std::mem::ManuallyDrop<generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>>`
|
||||
= note: required because it appears within the type `std::mem::MaybeUninit<generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>>`
|
||||
= note: required because it appears within the type `heapless::i::Vec<generic_array::GenericArray<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>>`
|
||||
= note: required because it appears within the type `heapless::vec::Vec<std::marker::PhantomData<*const ()>, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
|
||||
note: required by `is_send`
|
||||
--> $DIR/not-send.rs:12:1
|
||||
|
|
||||
12 | / fn is_send<T>()
|
||||
13 | | where
|
||||
14 | | T: Send,
|
||||
15 | | {
|
||||
16 | | }
|
||||
| |_^
|
||||
= help: within `heapless::Vec<PhantomData<*const ()>, 4_usize>`, the trait `Send` is not implemented for `*const ()`
|
||||
= note: required because it appears within the type `PhantomData<*const ()>`
|
||||
= note: required because it appears within the type `[PhantomData<*const ()>; 4]`
|
||||
= note: required because it appears within the type `ManuallyDrop<[PhantomData<*const ()>; 4]>`
|
||||
= note: required because it appears within the type `MaybeUninit<[PhantomData<*const ()>; 4]>`
|
||||
= note: required because it appears within the type `heapless::Vec<PhantomData<*const ()>, 4_usize>`
|
||||
|
32
src/de.rs
32
src/de.rs
@ -1,10 +1,10 @@
|
||||
use crate::{
|
||||
sealed::binary_heap::Kind as BinaryHeapKind, BinaryHeap, IndexMap, IndexSet, LinearMap, String,
|
||||
Vec,
|
||||
};
|
||||
use core::{fmt, marker::PhantomData};
|
||||
use hash32::{BuildHasherDefault, Hash, Hasher};
|
||||
use serde::de::{self, Deserialize, Deserializer, Error, MapAccess, SeqAccess};
|
||||
use crate::{
|
||||
sealed::binary_heap::Kind as BinaryHeapKind,
|
||||
BinaryHeap, IndexMap, IndexSet, LinearMap, String, Vec,
|
||||
};
|
||||
|
||||
// Sequential containers
|
||||
|
||||
@ -142,9 +142,9 @@ where
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ValueVisitor<'de, K, V, S, const N:usize>(PhantomData<(&'de (), K, V, S)>);
|
||||
struct ValueVisitor<'de, K, V, S, const N: usize>(PhantomData<(&'de (), K, V, S)>);
|
||||
|
||||
impl<'de, K, V, S, const N:usize> de::Visitor<'de> for ValueVisitor<'de, K, V, S, N>
|
||||
impl<'de, K, V, S, const N: usize> de::Visitor<'de> for ValueVisitor<'de, K, V, S, N>
|
||||
where
|
||||
K: Eq + Hash + Deserialize<'de>,
|
||||
V: Deserialize<'de>,
|
||||
@ -175,7 +175,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, K, V, const N:usize> Deserialize<'de> for LinearMap<K, V, N>
|
||||
impl<'de, K, V, const N: usize> Deserialize<'de> for LinearMap<K, V, N>
|
||||
where
|
||||
K: Eq + Deserialize<'de>,
|
||||
V: Deserialize<'de>,
|
||||
@ -184,9 +184,9 @@ where
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ValueVisitor<'de, K, V, const N:usize>(PhantomData<(&'de (), K, V)>);
|
||||
struct ValueVisitor<'de, K, V, const N: usize>(PhantomData<(&'de (), K, V)>);
|
||||
|
||||
impl<'de, K, V, const N:usize> de::Visitor<'de> for ValueVisitor<'de, K, V, N>
|
||||
impl<'de, K, V, const N: usize> de::Visitor<'de> for ValueVisitor<'de, K, V, N>
|
||||
where
|
||||
K: Eq + Deserialize<'de>,
|
||||
V: Deserialize<'de>,
|
||||
@ -218,24 +218,18 @@ where
|
||||
|
||||
// String containers
|
||||
|
||||
impl<'de, const N:usize> Deserialize<'de> for String<N>
|
||||
{
|
||||
impl<'de, const N: usize> Deserialize<'de> for String<N> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ValueVisitor<'de, const N:usize>(PhantomData<&'de ()>);
|
||||
struct ValueVisitor<'de, const N: usize>(PhantomData<&'de ()>);
|
||||
|
||||
impl<'de, const N:usize > de::Visitor<'de> for ValueVisitor<'de, N>
|
||||
{
|
||||
impl<'de, const N: usize> de::Visitor<'de> for ValueVisitor<'de, N> {
|
||||
type Value = String<N>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
formatter,
|
||||
"a string no more than {} bytes long",
|
||||
N as u64
|
||||
)
|
||||
write!(formatter, "a string no more than {} bytes long", N as u64)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
|
@ -1,11 +1,4 @@
|
||||
use core::{
|
||||
borrow::Borrow,
|
||||
fmt,
|
||||
iter::FromIterator,
|
||||
mem::{self, MaybeUninit},
|
||||
num::NonZeroU32,
|
||||
ops, slice,
|
||||
};
|
||||
use core::{borrow::Borrow, fmt, iter::FromIterator, mem, num::NonZeroU32, ops, slice};
|
||||
|
||||
use hash32::{BuildHasher, BuildHasherDefault, FnvHasher, Hash, Hasher};
|
||||
|
||||
@ -126,14 +119,12 @@ macro_rules! probe_loop {
|
||||
}
|
||||
}
|
||||
|
||||
struct CoreMap<K, V, const N: usize>
|
||||
{
|
||||
struct CoreMap<K, V, const N: usize> {
|
||||
entries: Vec<Bucket<K, V>, N>,
|
||||
indices: [Option<Pos>; N],
|
||||
}
|
||||
|
||||
impl<K, V, const N: usize> CoreMap<K, V, N>
|
||||
{
|
||||
impl<K, V, const N: usize> CoreMap<K, V, N> {
|
||||
const fn new() -> Self {
|
||||
const INIT: Option<Pos> = None;
|
||||
|
||||
|
@ -15,12 +15,14 @@ use as_slice::{AsMutSlice, AsSlice};
|
||||
use super::{Init, Node, Uninit};
|
||||
|
||||
/// Instantiates a pool as a global singleton
|
||||
// NOTE(any(test)) makes testing easier (no need to enable Cargo features for testing)
|
||||
#[cfg(any(
|
||||
armv7a,
|
||||
armv7r,
|
||||
armv7m,
|
||||
armv8m_main,
|
||||
all(target_arch = "x86_64", feature = "x86-sync-pool"),
|
||||
test
|
||||
))]
|
||||
#[macro_export]
|
||||
macro_rules! pool {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use ufmt_write::uWrite;
|
||||
use crate::{string::String, vec::Vec};
|
||||
use ufmt_write::uWrite;
|
||||
|
||||
impl<const N: usize> uWrite for String<N> {
|
||||
type Error = ();
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Collections of `Send`-able things are `Send`
|
||||
|
||||
use heapless::{
|
||||
spsc::{Consumer, Producer, Queue, MultiCore},
|
||||
spsc::{Consumer, MultiCore, Producer, Queue},
|
||||
HistoryBuffer, Vec,
|
||||
};
|
||||
|
||||
|
@ -188,7 +188,7 @@ fn unchecked() {
|
||||
scope.execute(move || {
|
||||
let mut sum: usize = 0;
|
||||
|
||||
for _ in 0..N/ 2 {
|
||||
for _ in 0..N / 2 {
|
||||
sum = sum.wrapping_add(usize::from(unsafe { c.dequeue_unchecked() }));
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ fn unchecked() {
|
||||
});
|
||||
}
|
||||
|
||||
assert_eq!(rb.len(), N/ 2);
|
||||
assert_eq!(rb.len(), N / 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -235,6 +235,7 @@ fn iterator_properly_wraps() {
|
||||
assert_eq!(expected, actual)
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", feature = "x86-sync-pool"))]
|
||||
#[test]
|
||||
fn pool() {
|
||||
use heapless::pool::singleton::Pool as _;
|
||||
|
Loading…
x
Reference in New Issue
Block a user