aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelvin Wang <[email protected]>2025-06-18 15:37:05 -0700
committerMelvin Wang <[email protected]>2025-06-18 15:37:05 -0700
commit905aed45f9c15eef9bf9afa5a6b81ae345694581 (patch)
treeb7ee277375f9ab985a3fc038067959aef4f90e09
parentdda17cc7cb85e3818d43561102b1fc6358d059c5 (diff)
add tests illustrating the problem
-rw-r--r--embassy-sync/Cargo.toml1
-rw-r--r--embassy-sync/tests/ui.rs13
-rw-r--r--embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs15
-rw-r--r--embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs6
-rw-r--r--embassy-sync/tests/ui/sync_impl/once_lock.rs6
5 files changed, 41 insertions, 0 deletions
diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml
index 1e2ea8ea1..9e5c39f5e 100644
--- a/embassy-sync/Cargo.toml
+++ b/embassy-sync/Cargo.toml
@@ -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
44critical-section = { version = "1.1", features = ["std"] } 44critical-section = { version = "1.1", features = ["std"] }
45static_cell = { version = "2" } 45static_cell = { version = "2" }
46trybuild = "1.0.105"
diff --git a/embassy-sync/tests/ui.rs b/embassy-sync/tests/ui.rs
new file mode 100644
index 000000000..9ef0d4c67
--- /dev/null
+++ b/embassy-sync/tests/ui.rs
@@ -0,0 +1,13 @@
1// #[cfg(not(miri))]
2#[test]
3fn 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..c6e6f7e64
--- /dev/null
+++ b/embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs
@@ -0,0 +1,15 @@
1use embassy_sync::lazy_lock::LazyLock;
2
3fn main() {
4 let x = 128u8;
5 let x_ptr: *const u8 = core::ptr::addr_of!(x);
6
7 let closure_capturing_non_sync_variable = || {
8 unsafe {
9 core::ptr::read(x_ptr)
10 }
11 };
12
13 // This should fail to compile because the closure captures a non-Sync variable: x_ptr.
14 let _lazy_u8: LazyLock<u8, _> = LazyLock::new(closure_capturing_non_sync_variable);
15}
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 @@
1use 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.
4static GLOBAL: LazyLock<*mut u8> = LazyLock::new(|| core::ptr::null_mut());
5
6fn main() {}
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 @@
1use 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.
4static GLOBAL: OnceLock<*mut u8> = OnceLock::new();
5
6fn main() {}