mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 14:54:30 +00:00
parent
06431e7397
commit
906b0679ca
@ -4,7 +4,7 @@ matrix:
|
||||
include:
|
||||
|
||||
# MSRV: Minimum Supported Rust Version
|
||||
- env: TARGET=x86_64-unknown-linux-gnu
|
||||
- env: TARGET=x86_64-unknown-linux-gnu MSRV=1
|
||||
rust: 1.36.0
|
||||
if: branch != master
|
||||
|
||||
|
@ -19,8 +19,13 @@ name = "heapless"
|
||||
repository = "https://github.com/japaric/heapless"
|
||||
version = "0.5.1"
|
||||
|
||||
[[test]]
|
||||
name = "cfail"
|
||||
required-features = ["__trybuild"]
|
||||
|
||||
[dev-dependencies]
|
||||
scoped_threadpool = "0.1.8"
|
||||
trybuild = "1.0.18"
|
||||
|
||||
[dependencies]
|
||||
as-slice = "0.1.0"
|
||||
@ -31,3 +36,7 @@ hash32 = "0.1.0"
|
||||
version = "1"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
# only for tests
|
||||
__trybuild = []
|
@ -8,6 +8,11 @@ main() {
|
||||
cargo test --target $TARGET --features 'serde'
|
||||
cargo test --target $TARGET --release --features 'serde'
|
||||
|
||||
if [ $MSRV = 1 ]; then
|
||||
cargo test --features __trybuild --test cfail
|
||||
fi
|
||||
|
||||
|
||||
if [ $TRAVIS_RUST_VERSION = nightly ]; then
|
||||
export RUSTFLAGS="-Z sanitizer=thread"
|
||||
export RUST_TEST_THREADS=1
|
||||
@ -46,6 +51,10 @@ if [ -z ${TARGET-} ]; then
|
||||
TARGET=$(rustc -Vv | grep host | cut -d ' ' -f2)
|
||||
fi
|
||||
|
||||
if [ -z ${MSRV-} ]; then
|
||||
MSRV=1
|
||||
fi
|
||||
|
||||
if [ $TRAVIS_BRANCH != master ]; then
|
||||
main
|
||||
fi
|
||||
|
83
src/cfail.rs
83
src/cfail.rs
@ -1,83 +0,0 @@
|
||||
//! Compile fail tests
|
||||
//!
|
||||
//! # `Send`-ness
|
||||
//!
|
||||
//! Collections of `Send`-able things are `Send`
|
||||
//!
|
||||
//! ```
|
||||
//! use heapless::Vec;
|
||||
//! use heapless::spsc::{Consumer, Queue, Producer};
|
||||
//! use heapless::consts::*;
|
||||
//!
|
||||
//! struct IsSend;
|
||||
//!
|
||||
//! unsafe impl Send for IsSend {}
|
||||
//!
|
||||
//! fn is_send<T>() where T: Send {}
|
||||
//!
|
||||
//! is_send::<Consumer<IsSend, U4>>();
|
||||
//! is_send::<Producer<IsSend, U4>>();
|
||||
//! is_send::<Queue<IsSend, U4>>();
|
||||
//! is_send::<Vec<IsSend, U4>>();
|
||||
//! ```
|
||||
//!
|
||||
//! Collections of non-`Send`-able things are *not* `Send`
|
||||
//!
|
||||
//! ``` compile_fail
|
||||
//! use std::marker::PhantomData;
|
||||
//! use heapless::ring_buffer::Consumer;
|
||||
//! use heapless::consts::*;
|
||||
//!
|
||||
//! type NotSend = PhantomData<*const ()>;
|
||||
//!
|
||||
//! fn is_send<T>() where T: Send {}
|
||||
//!
|
||||
//! is_send::<Consumer<NotSend, U4>>();
|
||||
//! ```
|
||||
//!
|
||||
//! ``` compile_fail
|
||||
//! use std::marker::PhantomData;
|
||||
//! use heapless::ring_buffer::Producer;
|
||||
//! use heapless::consts::*;
|
||||
//!
|
||||
//! type NotSend = PhantomData<*const ()>;
|
||||
//!
|
||||
//! fn is_send<T>() where T: Send {}
|
||||
//!
|
||||
//! is_send::<Producer<NotSend, U4>>();
|
||||
//! ```
|
||||
//!
|
||||
//! ``` compile_fail
|
||||
//! use std::marker::PhantomData;
|
||||
//! use heapless::spsc::Queue;
|
||||
//!
|
||||
//! type NotSend = PhantomData<*const ()>;
|
||||
//!
|
||||
//! fn is_send<T>() where T: Send {}
|
||||
//!
|
||||
//! is_send::<Queue<NotSend, [NotSend; 4]>>();
|
||||
//! ```
|
||||
//!
|
||||
//! ``` compile_fail
|
||||
//! use std::marker::PhantomData;
|
||||
//! use heapless::Vec;
|
||||
//!
|
||||
//! type NotSend = PhantomData<*const ()>;
|
||||
//!
|
||||
//! fn is_send<T>() where T: Send {}
|
||||
//!
|
||||
//! is_send::<Vec<NotSend, [NotSend; 4]>>();
|
||||
//! ```
|
||||
//!
|
||||
//! # Freeze
|
||||
//!
|
||||
//! Splitting a `Queue` should invalidate the original reference.
|
||||
//!
|
||||
//! ``` compile_fail
|
||||
//! use heapless::spsc::Queue;
|
||||
//!
|
||||
//! let mut rb: Queue<u8, [u8; 4]> = Queue::new();
|
||||
//!
|
||||
//! let (p, c) = rb.split();
|
||||
//! rb.enqueue(0).unwrap();
|
||||
//! ```
|
7
tests/cfail.rs
Normal file
7
tests/cfail.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use trybuild::TestCases;
|
||||
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = TestCases::new();
|
||||
t.compile_fail("ui/*.rs");
|
||||
}
|
25
tests/cpass.rs
Normal file
25
tests/cpass.rs
Normal file
@ -0,0 +1,25 @@
|
||||
//! Collections of `Send`-able things are `Send`
|
||||
|
||||
use heapless::{
|
||||
consts,
|
||||
spsc::{Consumer, Producer, Queue},
|
||||
Vec,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn send() {
|
||||
struct IsSend;
|
||||
|
||||
unsafe impl Send for IsSend {}
|
||||
|
||||
fn is_send<T>()
|
||||
where
|
||||
T: Send,
|
||||
{
|
||||
}
|
||||
|
||||
is_send::<Consumer<IsSend, consts::U4>>();
|
||||
is_send::<Producer<IsSend, consts::U4>>();
|
||||
is_send::<Queue<IsSend, consts::U4>>();
|
||||
is_send::<Vec<IsSend, consts::U4>>();
|
||||
}
|
9
ui/freeze.rs
Normal file
9
ui/freeze.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use heapless::{consts, spsc::Queue};
|
||||
|
||||
fn main() {
|
||||
let mut q: Queue<u8, consts::U4> = Queue::new();
|
||||
|
||||
let (_p, mut _c) = q.split();
|
||||
q.enqueue(0).unwrap();
|
||||
_c.dequeue();
|
||||
}
|
9
ui/freeze.stderr
Normal file
9
ui/freeze.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0499]: cannot borrow `q` as mutable more than once at a time
|
||||
--> $DIR/freeze.rs:7:5
|
||||
|
|
||||
6 | let (_p, mut _c) = q.split();
|
||||
| - first mutable borrow occurs here
|
||||
7 | q.enqueue(0).unwrap();
|
||||
| ^ second mutable borrow occurs here
|
||||
8 | _c.dequeue();
|
||||
| -- first borrow later used here
|
23
ui/not-send.rs
Normal file
23
ui/not-send.rs
Normal file
@ -0,0 +1,23 @@
|
||||
//! Collections of non-`Send`-able things are *not* `Send`
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use heapless::{
|
||||
consts,
|
||||
spsc::{Consumer, Producer, Queue},
|
||||
};
|
||||
|
||||
type NotSend = PhantomData<*const ()>;
|
||||
|
||||
fn is_send<T>()
|
||||
where
|
||||
T: Send,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {
|
||||
is_send::<Consumer<NotSend, consts::U4>>();
|
||||
is_send::<Producer<NotSend, consts::U4>>();
|
||||
is_send::<Queue<NotSend, consts::U4>>();
|
||||
is_send::<Vec<NotSend, consts::U4>>();
|
||||
}
|
75
ui/not-send.stderr
Normal file
75
ui/not-send.stderr
Normal file
@ -0,0 +1,75 @@
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:19:5
|
||||
|
|
||||
12 | fn is_send<T>()
|
||||
| -------
|
||||
13 | where
|
||||
14 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
19 | is_send::<Consumer<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 `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>>`
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:20:5
|
||||
|
|
||||
12 | fn is_send<T>()
|
||||
| -------
|
||||
13 | where
|
||||
14 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
20 | is_send::<Producer<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 `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>>`
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:21:5
|
||||
|
|
||||
12 | fn is_send<T>()
|
||||
| -------
|
||||
13 | where
|
||||
14 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
21 | is_send::<Queue<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::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>>`
|
||||
|
||||
error[E0107]: wrong number of type arguments: expected 1, found 2
|
||||
--> $DIR/not-send.rs:22:28
|
||||
|
|
||||
22 | is_send::<Vec<NotSend, consts::U4>>();
|
||||
| ^^^^^^^^^^ unexpected type argument
|
||||
|
||||
error[E0277]: `*const ()` cannot be sent between threads safely
|
||||
--> $DIR/not-send.rs:22:5
|
||||
|
|
||||
12 | fn is_send<T>()
|
||||
| -------
|
||||
13 | where
|
||||
14 | T: Send,
|
||||
| ---- required by this bound in `is_send`
|
||||
...
|
||||
22 | is_send::<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 `std::ptr::Unique<std::marker::PhantomData<*const ()>>`
|
||||
= note: required because it appears within the type `alloc::raw_vec::RawVec<std::marker::PhantomData<*const ()>>`
|
||||
= note: required because it appears within the type `std::vec::Vec<std::marker::PhantomData<*const ()>>`
|
Loading…
x
Reference in New Issue
Block a user