diff options
| author | benjaminschlegel87 <[email protected]> | 2025-07-25 20:39:40 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-25 20:39:40 +0200 |
| commit | dbc1818acd69e2e15ac574356c9b07cb717df441 (patch) | |
| tree | 05e6360c1946183b524a1ce82268547fe4bbcfd0 /embassy-sync | |
| parent | adb728009ceba095d2190038ff698aaee08907a9 (diff) | |
| parent | 996974e313fa5ec2c7c2d9dd0998fab244c0a180 (diff) | |
Merge branch 'embassy-rs:main' into stm32_adc_v3_hw_oversampling_support
Diffstat (limited to 'embassy-sync')
| -rw-r--r-- | embassy-sync/Cargo.toml | 3 | ||||
| -rw-r--r-- | embassy-sync/src/channel.rs | 29 | ||||
| -rw-r--r-- | embassy-sync/src/lazy_lock.rs | 7 | ||||
| -rw-r--r-- | embassy-sync/src/mutex.rs | 2 | ||||
| -rw-r--r-- | embassy-sync/src/once_lock.rs | 2 | ||||
| -rw-r--r-- | embassy-sync/src/pipe.rs | 8 | ||||
| -rw-r--r-- | embassy-sync/src/priority_channel.rs | 4 | ||||
| -rw-r--r-- | embassy-sync/src/pubsub/mod.rs | 8 | ||||
| -rw-r--r-- | embassy-sync/src/pubsub/publisher.rs | 2 | ||||
| -rw-r--r-- | embassy-sync/src/pubsub/subscriber.rs | 2 | ||||
| -rw-r--r-- | embassy-sync/tests/ui.rs | 13 | ||||
| -rw-r--r-- | embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs | 11 | ||||
| -rw-r--r-- | embassy-sync/tests/ui/sync_impl/lazy_lock_function.stderr | 24 | ||||
| -rw-r--r-- | embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs | 6 | ||||
| -rw-r--r-- | embassy-sync/tests/ui/sync_impl/lazy_lock_type.stderr | 9 | ||||
| -rw-r--r-- | embassy-sync/tests/ui/sync_impl/once_lock.rs | 6 | ||||
| -rw-r--r-- | embassy-sync/tests/ui/sync_impl/once_lock.stderr | 9 |
17 files changed, 127 insertions, 18 deletions
diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 99962f9f6..9e5c39f5e 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml | |||
| @@ -28,7 +28,7 @@ defmt = { version = "1.0.1", optional = true } | |||
| 28 | log = { version = "0.4.14", optional = true } | 28 | log = { version = "0.4.14", optional = true } |
| 29 | 29 | ||
| 30 | futures-sink = { version = "0.3", default-features = false, features = [] } | 30 | futures-sink = { version = "0.3", default-features = false, features = [] } |
| 31 | futures-util = { version = "0.3.17", default-features = false } | 31 | futures-core = { version = "0.3.31", default-features = false } |
| 32 | critical-section = "1.1" | 32 | critical-section = "1.1" |
| 33 | heapless = "0.8" | 33 | heapless = "0.8" |
| 34 | cfg-if = "1.0.0" | 34 | cfg-if = "1.0.0" |
| @@ -43,3 +43,4 @@ futures-util = { version = "0.3.17", features = [ "channel", "sink" ] } | |||
| 43 | # Enable critical-section implementation for std, for tests | 43 | # Enable critical-section implementation for std, for tests |
| 44 | critical-section = { version = "1.1", features = ["std"] } | 44 | critical-section = { version = "1.1", features = ["std"] } |
| 45 | static_cell = { version = "2" } | 45 | static_cell = { version = "2" } |
| 46 | trybuild = "1.0.105" | ||
diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs index 856551417..a0e39fcb5 100644 --- a/embassy-sync/src/channel.rs +++ b/embassy-sync/src/channel.rs | |||
| @@ -17,6 +17,31 @@ | |||
| 17 | //! messages that it can store, and if this limit is reached, trying to send | 17 | //! messages that it can store, and if this limit is reached, trying to send |
| 18 | //! another message will result in an error being returned. | 18 | //! another message will result in an error being returned. |
| 19 | //! | 19 | //! |
| 20 | //! # Example: Message passing between task and interrupt handler | ||
| 21 | //! | ||
| 22 | //! ```rust | ||
| 23 | //! use embassy_sync::channel::Channel; | ||
| 24 | //! use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 25 | //! | ||
| 26 | //! static SHARED_CHANNEL: Channel<CriticalSectionRawMutex, u32, 8> = Channel::new(); | ||
| 27 | //! | ||
| 28 | //! fn my_interrupt_handler() { | ||
| 29 | //! // Do some work.. | ||
| 30 | //! // ... | ||
| 31 | //! if let Err(e) = SHARED_CHANNEL.sender().try_send(42) { | ||
| 32 | //! // Channel is full.. | ||
| 33 | //! } | ||
| 34 | //! } | ||
| 35 | //! | ||
| 36 | //! async fn my_async_task() { | ||
| 37 | //! // ... | ||
| 38 | //! let receiver = SHARED_CHANNEL.receiver(); | ||
| 39 | //! loop { | ||
| 40 | //! let data_from_interrupt = receiver.receive().await; | ||
| 41 | //! // Do something with the data. | ||
| 42 | //! } | ||
| 43 | //! } | ||
| 44 | //! ``` | ||
| 20 | 45 | ||
| 21 | use core::cell::RefCell; | 46 | use core::cell::RefCell; |
| 22 | use core::future::Future; | 47 | use core::future::Future; |
| @@ -443,7 +468,7 @@ where | |||
| 443 | } | 468 | } |
| 444 | } | 469 | } |
| 445 | 470 | ||
| 446 | impl<'ch, M, T, const N: usize> futures_util::Stream for Receiver<'ch, M, T, N> | 471 | impl<'ch, M, T, const N: usize> futures_core::Stream for Receiver<'ch, M, T, N> |
| 447 | where | 472 | where |
| 448 | M: RawMutex, | 473 | M: RawMutex, |
| 449 | { | 474 | { |
| @@ -962,7 +987,7 @@ where | |||
| 962 | } | 987 | } |
| 963 | } | 988 | } |
| 964 | 989 | ||
| 965 | impl<M, T, const N: usize> futures_util::Stream for Channel<M, T, N> | 990 | impl<M, T, const N: usize> futures_core::Stream for Channel<M, T, N> |
| 966 | where | 991 | where |
| 967 | M: RawMutex, | 992 | M: RawMutex, |
| 968 | { | 993 | { |
diff --git a/embassy-sync/src/lazy_lock.rs b/embassy-sync/src/lazy_lock.rs index 18e3c2019..f1bd88b61 100644 --- a/embassy-sync/src/lazy_lock.rs +++ b/embassy-sync/src/lazy_lock.rs | |||
| @@ -31,7 +31,12 @@ union Data<T, F> { | |||
| 31 | f: ManuallyDrop<F>, | 31 | f: ManuallyDrop<F>, |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | unsafe impl<T, F> Sync for LazyLock<T, F> {} | 34 | unsafe impl<T, F> Sync for LazyLock<T, F> |
| 35 | where | ||
| 36 | T: Sync, | ||
| 37 | F: Sync, | ||
| 38 | { | ||
| 39 | } | ||
| 35 | 40 | ||
| 36 | impl<T, F: FnOnce() -> T> LazyLock<T, F> { | 41 | impl<T, F: FnOnce() -> T> LazyLock<T, F> { |
| 37 | /// Create a new uninitialized `StaticLock`. | 42 | /// Create a new uninitialized `StaticLock`. |
diff --git a/embassy-sync/src/mutex.rs b/embassy-sync/src/mutex.rs index 7528a9f68..8496f34bf 100644 --- a/embassy-sync/src/mutex.rs +++ b/embassy-sync/src/mutex.rs | |||
| @@ -23,7 +23,7 @@ struct State { | |||
| 23 | 23 | ||
| 24 | /// Async mutex. | 24 | /// Async mutex. |
| 25 | /// | 25 | /// |
| 26 | /// The mutex is generic over a blocking [`RawMutex`](crate::blocking_mutex::raw::RawMutex). | 26 | /// The mutex is generic over a blocking [`RawMutex`]. |
| 27 | /// The raw mutex is used to guard access to the internal "is locked" flag. It | 27 | /// The raw mutex is used to guard access to the internal "is locked" flag. It |
| 28 | /// is held for very short periods only, while locking and unlocking. It is *not* held | 28 | /// is held for very short periods only, while locking and unlocking. It is *not* held |
| 29 | /// for the entire time the async Mutex is locked. | 29 | /// for the entire time the async Mutex is locked. |
diff --git a/embassy-sync/src/once_lock.rs b/embassy-sync/src/once_lock.rs index cd05b986d..1e848685a 100644 --- a/embassy-sync/src/once_lock.rs +++ b/embassy-sync/src/once_lock.rs | |||
| @@ -42,7 +42,7 @@ pub struct OnceLock<T> { | |||
| 42 | data: Cell<MaybeUninit<T>>, | 42 | data: Cell<MaybeUninit<T>>, |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | unsafe impl<T> Sync for OnceLock<T> {} | 45 | unsafe impl<T> Sync for OnceLock<T> where T: Sync {} |
| 46 | 46 | ||
| 47 | impl<T> OnceLock<T> { | 47 | impl<T> OnceLock<T> { |
| 48 | /// Create a new uninitialized `OnceLock`. | 48 | /// Create a new uninitialized `OnceLock`. |
diff --git a/embassy-sync/src/pipe.rs b/embassy-sync/src/pipe.rs index 2598652d2..df3b28b45 100644 --- a/embassy-sync/src/pipe.rs +++ b/embassy-sync/src/pipe.rs | |||
| @@ -152,7 +152,7 @@ where | |||
| 152 | 152 | ||
| 153 | impl<'p, M, const N: usize> Unpin for ReadFuture<'p, M, N> where M: RawMutex {} | 153 | impl<'p, M, const N: usize> Unpin for ReadFuture<'p, M, N> where M: RawMutex {} |
| 154 | 154 | ||
| 155 | /// Future returned by [`Pipe::fill_buf`] and [`Reader::fill_buf`]. | 155 | /// Future returned by [`Reader::fill_buf`]. |
| 156 | #[must_use = "futures do nothing unless you `.await` or poll them"] | 156 | #[must_use = "futures do nothing unless you `.await` or poll them"] |
| 157 | pub struct FillBufFuture<'p, M, const N: usize> | 157 | pub struct FillBufFuture<'p, M, const N: usize> |
| 158 | where | 158 | where |
| @@ -587,7 +587,7 @@ where | |||
| 587 | } | 587 | } |
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | /// Write-only access to a [`DynamicPipe`]. | 590 | /// Write-only access to the dynamic pipe. |
| 591 | pub struct DynamicWriter<'p> { | 591 | pub struct DynamicWriter<'p> { |
| 592 | pipe: &'p dyn DynamicPipe, | 592 | pipe: &'p dyn DynamicPipe, |
| 593 | } | 593 | } |
| @@ -657,7 +657,7 @@ where | |||
| 657 | } | 657 | } |
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | /// Read-only access to a [`DynamicPipe`]. | 660 | /// Read-only access to a dynamic pipe. |
| 661 | pub struct DynamicReader<'p> { | 661 | pub struct DynamicReader<'p> { |
| 662 | pipe: &'p dyn DynamicPipe, | 662 | pipe: &'p dyn DynamicPipe, |
| 663 | } | 663 | } |
| @@ -742,7 +742,7 @@ where | |||
| 742 | } | 742 | } |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | /// Future returned by [`DynamicPipe::fill_buf`] and [`DynamicReader::fill_buf`]. | 745 | /// Future returned by [`DynamicReader::fill_buf`]. |
| 746 | #[must_use = "futures do nothing unless you `.await` or poll them"] | 746 | #[must_use = "futures do nothing unless you `.await` or poll them"] |
| 747 | pub struct DynamicFillBufFuture<'p> { | 747 | pub struct DynamicFillBufFuture<'p> { |
| 748 | pipe: Option<&'p dyn DynamicPipe>, | 748 | pipe: Option<&'p dyn DynamicPipe>, |
diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/priority_channel.rs index 623c52993..715a20e86 100644 --- a/embassy-sync/src/priority_channel.rs +++ b/embassy-sync/src/priority_channel.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | //! A queue for sending values between asynchronous tasks. | 1 | //! A queue for sending values between asynchronous tasks. |
| 2 | //! | 2 | //! |
| 3 | //! Similar to a [`Channel`](crate::channel::Channel), however [`PriorityChannel`] sifts higher priority items to the front of the queue. | 3 | //! Similar to a [`Channel`](crate::channel::Channel), however [`PriorityChannel`] sifts higher priority items to the front of the queue. |
| 4 | //! Priority is determined by the `Ord` trait. Priority behavior is determined by the [`Kind`](heapless::binary_heap::Kind) parameter of the channel. | 4 | //! Priority is determined by the `Ord` trait. Priority behavior is determined by the [`Kind`] parameter of the channel. |
| 5 | 5 | ||
| 6 | use core::cell::RefCell; | 6 | use core::cell::RefCell; |
| 7 | use core::future::Future; | 7 | use core::future::Future; |
| @@ -473,7 +473,7 @@ where | |||
| 473 | /// received from the channel. | 473 | /// received from the channel. |
| 474 | /// | 474 | /// |
| 475 | /// Sent data may be reordered based on their priority within the channel. | 475 | /// Sent data may be reordered based on their priority within the channel. |
| 476 | /// For example, in a [`Max`](heapless::binary_heap::Max) [`PriorityChannel`] | 476 | /// For example, in a [`Max`] [`PriorityChannel`] |
| 477 | /// containing `u32`'s, data sent in the following order `[1, 2, 3]` will be received as `[3, 2, 1]`. | 477 | /// containing `u32`'s, data sent in the following order `[1, 2, 3]` will be received as `[3, 2, 1]`. |
| 478 | pub struct PriorityChannel<M, T, K, const N: usize> | 478 | pub struct PriorityChannel<M, T, K, const N: usize> |
| 479 | where | 479 | where |
diff --git a/embassy-sync/src/pubsub/mod.rs b/embassy-sync/src/pubsub/mod.rs index 606efff0a..9206b9383 100644 --- a/embassy-sync/src/pubsub/mod.rs +++ b/embassy-sync/src/pubsub/mod.rs | |||
| @@ -88,7 +88,7 @@ impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usi | |||
| 88 | /// Create a new subscriber. It will only receive messages that are published after its creation. | 88 | /// Create a new subscriber. It will only receive messages that are published after its creation. |
| 89 | /// | 89 | /// |
| 90 | /// If there are no subscriber slots left, an error will be returned. | 90 | /// If there are no subscriber slots left, an error will be returned. |
| 91 | pub fn subscriber(&self) -> Result<Subscriber<M, T, CAP, SUBS, PUBS>, Error> { | 91 | pub fn subscriber(&self) -> Result<Subscriber<'_, M, T, CAP, SUBS, PUBS>, Error> { |
| 92 | self.inner.lock(|inner| { | 92 | self.inner.lock(|inner| { |
| 93 | let mut s = inner.borrow_mut(); | 93 | let mut s = inner.borrow_mut(); |
| 94 | 94 | ||
| @@ -120,7 +120,7 @@ impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usi | |||
| 120 | /// Create a new publisher | 120 | /// Create a new publisher |
| 121 | /// | 121 | /// |
| 122 | /// If there are no publisher slots left, an error will be returned. | 122 | /// If there are no publisher slots left, an error will be returned. |
| 123 | pub fn publisher(&self) -> Result<Publisher<M, T, CAP, SUBS, PUBS>, Error> { | 123 | pub fn publisher(&self) -> Result<Publisher<'_, M, T, CAP, SUBS, PUBS>, Error> { |
| 124 | self.inner.lock(|inner| { | 124 | self.inner.lock(|inner| { |
| 125 | let mut s = inner.borrow_mut(); | 125 | let mut s = inner.borrow_mut(); |
| 126 | 126 | ||
| @@ -151,13 +151,13 @@ impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usi | |||
| 151 | 151 | ||
| 152 | /// Create a new publisher that can only send immediate messages. | 152 | /// Create a new publisher that can only send immediate messages. |
| 153 | /// This kind of publisher does not take up a publisher slot. | 153 | /// This kind of publisher does not take up a publisher slot. |
| 154 | pub fn immediate_publisher(&self) -> ImmediatePublisher<M, T, CAP, SUBS, PUBS> { | 154 | pub fn immediate_publisher(&self) -> ImmediatePublisher<'_, M, T, CAP, SUBS, PUBS> { |
| 155 | ImmediatePublisher(ImmediatePub::new(self)) | 155 | ImmediatePublisher(ImmediatePub::new(self)) |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | /// Create a new publisher that can only send immediate messages. | 158 | /// Create a new publisher that can only send immediate messages. |
| 159 | /// This kind of publisher does not take up a publisher slot. | 159 | /// This kind of publisher does not take up a publisher slot. |
| 160 | pub fn dyn_immediate_publisher(&self) -> DynImmediatePublisher<T> { | 160 | pub fn dyn_immediate_publisher(&self) -> DynImmediatePublisher<'_, T> { |
| 161 | DynImmediatePublisher(ImmediatePub::new(self)) | 161 | DynImmediatePublisher(ImmediatePub::new(self)) |
| 162 | } | 162 | } |
| 163 | 163 | ||
diff --git a/embassy-sync/src/pubsub/publisher.rs b/embassy-sync/src/pubsub/publisher.rs index 7a1ab66de..52a52f926 100644 --- a/embassy-sync/src/pubsub/publisher.rs +++ b/embassy-sync/src/pubsub/publisher.rs | |||
| @@ -75,7 +75,7 @@ impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> Pub<'a, PSB, T> { | |||
| 75 | self.channel.is_full() | 75 | self.channel.is_full() |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /// Create a [`futures::Sink`] adapter for this publisher. | 78 | /// Create a [`futures_sink::Sink`] adapter for this publisher. |
| 79 | #[inline] | 79 | #[inline] |
| 80 | pub const fn sink(&self) -> PubSink<'a, '_, PSB, T> { | 80 | pub const fn sink(&self) -> PubSink<'a, '_, PSB, T> { |
| 81 | PubSink { publ: self, fut: None } | 81 | PubSink { publ: self, fut: None } |
diff --git a/embassy-sync/src/pubsub/subscriber.rs b/embassy-sync/src/pubsub/subscriber.rs index 6ad660cb3..649382cf1 100644 --- a/embassy-sync/src/pubsub/subscriber.rs +++ b/embassy-sync/src/pubsub/subscriber.rs | |||
| @@ -115,7 +115,7 @@ impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> Unpin for Sub<'a, PSB, T> {} | |||
| 115 | 115 | ||
| 116 | /// Warning: The stream implementation ignores lag results and returns all messages. | 116 | /// Warning: The stream implementation ignores lag results and returns all messages. |
| 117 | /// This might miss some messages without you knowing it. | 117 | /// This might miss some messages without you knowing it. |
| 118 | impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> futures_util::Stream for Sub<'a, PSB, T> { | 118 | impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> futures_core::Stream for Sub<'a, PSB, T> { |
| 119 | type Item = T; | 119 | type Item = T; |
| 120 | 120 | ||
| 121 | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { | 121 | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { |
diff --git a/embassy-sync/tests/ui.rs b/embassy-sync/tests/ui.rs new file mode 100644 index 000000000..e8b1080d8 --- /dev/null +++ b/embassy-sync/tests/ui.rs | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #[cfg(not(miri))] | ||
| 2 | #[test] | ||
| 3 | fn ui() { | ||
| 4 | let t = trybuild::TestCases::new(); | ||
| 5 | |||
| 6 | // These test cases should fail to compile since OnceLock and LazyLock should not unconditionally implement sync | ||
| 7 | // for all types. These tests are regression tests against the following issues: | ||
| 8 | // * https://github.com/embassy-rs/embassy/issues/4307 | ||
| 9 | // * https://github.com/embassy-rs/embassy/issues/3904 | ||
| 10 | t.compile_fail("tests/ui/sync_impl/lazy_lock_function.rs"); | ||
| 11 | t.compile_fail("tests/ui/sync_impl/lazy_lock_type.rs"); | ||
| 12 | t.compile_fail("tests/ui/sync_impl/once_lock.rs"); | ||
| 13 | } | ||
diff --git a/embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs b/embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs new file mode 100644 index 000000000..35f5587c0 --- /dev/null +++ b/embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | use embassy_sync::lazy_lock::LazyLock; | ||
| 2 | |||
| 3 | fn main() { | ||
| 4 | let x = 128u8; | ||
| 5 | let x_ptr: *const u8 = core::ptr::addr_of!(x); | ||
| 6 | let closure_capturing_non_sync_variable = || unsafe { core::ptr::read(x_ptr) }; | ||
| 7 | |||
| 8 | check_sync(LazyLock::new(closure_capturing_non_sync_variable)); | ||
| 9 | } | ||
| 10 | |||
| 11 | fn check_sync<T: Sync>(_lazy_lock: T) {} | ||
diff --git a/embassy-sync/tests/ui/sync_impl/lazy_lock_function.stderr b/embassy-sync/tests/ui/sync_impl/lazy_lock_function.stderr new file mode 100644 index 000000000..daf79ad28 --- /dev/null +++ b/embassy-sync/tests/ui/sync_impl/lazy_lock_function.stderr | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | error[E0277]: `*const u8` cannot be shared between threads safely | ||
| 2 | --> tests/ui/sync_impl/lazy_lock_function.rs:8:16 | ||
| 3 | | | ||
| 4 | 6 | let closure_capturing_non_sync_variable = || unsafe { core::ptr::read(x_ptr) }; | ||
| 5 | | -- within this `{closure@$DIR/tests/ui/sync_impl/lazy_lock_function.rs:6:47: 6:49}` | ||
| 6 | 7 | | ||
| 7 | 8 | check_sync(LazyLock::new(closure_capturing_non_sync_variable)); | ||
| 8 | | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const u8` cannot be shared between threads safely | ||
| 9 | | | | ||
| 10 | | required by a bound introduced by this call | ||
| 11 | | | ||
| 12 | = help: within `{closure@$DIR/tests/ui/sync_impl/lazy_lock_function.rs:6:47: 6:49}`, the trait `Sync` is not implemented for `*const u8` | ||
| 13 | = note: required because it appears within the type `&*const u8` | ||
| 14 | note: required because it's used within this closure | ||
| 15 | --> tests/ui/sync_impl/lazy_lock_function.rs:6:47 | ||
| 16 | | | ||
| 17 | 6 | let closure_capturing_non_sync_variable = || unsafe { core::ptr::read(x_ptr) }; | ||
| 18 | | ^^ | ||
| 19 | = note: required for `embassy_sync::lazy_lock::LazyLock<u8, {closure@$DIR/tests/ui/sync_impl/lazy_lock_function.rs:6:47: 6:49}>` to implement `Sync` | ||
| 20 | note: required by a bound in `check_sync` | ||
| 21 | --> tests/ui/sync_impl/lazy_lock_function.rs:11:18 | ||
| 22 | | | ||
| 23 | 11 | fn check_sync<T: Sync>(_lazy_lock: T) {} | ||
| 24 | | ^^^^ required by this bound in `check_sync` | ||
diff --git a/embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs b/embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs new file mode 100644 index 000000000..4e1383143 --- /dev/null +++ b/embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | use embassy_sync::lazy_lock::LazyLock; | ||
| 2 | |||
| 3 | // *mut u8 is not Sync, so LazyLock should not implement Sync for this type. This should fail to compile. | ||
| 4 | static GLOBAL: LazyLock<*mut u8> = LazyLock::new(|| core::ptr::null_mut()); | ||
| 5 | |||
| 6 | fn main() {} | ||
diff --git a/embassy-sync/tests/ui/sync_impl/lazy_lock_type.stderr b/embassy-sync/tests/ui/sync_impl/lazy_lock_type.stderr new file mode 100644 index 000000000..1ccc54c7a --- /dev/null +++ b/embassy-sync/tests/ui/sync_impl/lazy_lock_type.stderr | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | error[E0277]: `*mut u8` cannot be shared between threads safely | ||
| 2 | --> tests/ui/sync_impl/lazy_lock_type.rs:4:16 | ||
| 3 | | | ||
| 4 | 4 | static GLOBAL: LazyLock<*mut u8> = LazyLock::new(|| core::ptr::null_mut()); | ||
| 5 | | ^^^^^^^^^^^^^^^^^ `*mut u8` cannot be shared between threads safely | ||
| 6 | | | ||
| 7 | = help: the trait `Sync` is not implemented for `*mut u8` | ||
| 8 | = note: required for `embassy_sync::lazy_lock::LazyLock<*mut u8>` to implement `Sync` | ||
| 9 | = note: shared static variables must have a type that implements `Sync` | ||
diff --git a/embassy-sync/tests/ui/sync_impl/once_lock.rs b/embassy-sync/tests/ui/sync_impl/once_lock.rs new file mode 100644 index 000000000..8f50d583b --- /dev/null +++ b/embassy-sync/tests/ui/sync_impl/once_lock.rs | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | use embassy_sync::once_lock::OnceLock; | ||
| 2 | |||
| 3 | // *mut u8 is not Sync, so OnceLock should not implement Sync for this type. This should fail to compile. | ||
| 4 | static GLOBAL: OnceLock<*mut u8> = OnceLock::new(); | ||
| 5 | |||
| 6 | fn main() {} | ||
diff --git a/embassy-sync/tests/ui/sync_impl/once_lock.stderr b/embassy-sync/tests/ui/sync_impl/once_lock.stderr new file mode 100644 index 000000000..e2419f844 --- /dev/null +++ b/embassy-sync/tests/ui/sync_impl/once_lock.stderr | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | error[E0277]: `*mut u8` cannot be shared between threads safely | ||
| 2 | --> tests/ui/sync_impl/once_lock.rs:4:16 | ||
| 3 | | | ||
| 4 | 4 | static GLOBAL: OnceLock<*mut u8> = OnceLock::new(); | ||
| 5 | | ^^^^^^^^^^^^^^^^^ `*mut u8` cannot be shared between threads safely | ||
| 6 | | | ||
| 7 | = help: the trait `Sync` is not implemented for `*mut u8` | ||
| 8 | = note: required for `embassy_sync::once_lock::OnceLock<*mut u8>` to implement `Sync` | ||
| 9 | = note: shared static variables must have a type that implements `Sync` | ||
