From 905aed45f9c15eef9bf9afa5a6b81ae345694581 Mon Sep 17 00:00:00 2001 From: Melvin Wang Date: Wed, 18 Jun 2025 15:37:05 -0700 Subject: add tests illustrating the problem --- embassy-sync/Cargo.toml | 1 + embassy-sync/tests/ui.rs | 13 +++++++++++++ embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs | 15 +++++++++++++++ embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs | 6 ++++++ embassy-sync/tests/ui/sync_impl/once_lock.rs | 6 ++++++ 5 files changed, 41 insertions(+) create mode 100644 embassy-sync/tests/ui.rs create mode 100644 embassy-sync/tests/ui/sync_impl/lazy_lock_function.rs create mode 100644 embassy-sync/tests/ui/sync_impl/lazy_lock_type.rs create mode 100644 embassy-sync/tests/ui/sync_impl/once_lock.rs (limited to 'embassy-sync') 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" ] } # Enable critical-section implementation for std, for tests critical-section = { version = "1.1", features = ["std"] } static_cell = { version = "2" } +trybuild = "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 @@ +// #[cfg(not(miri))] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + + // These test cases should fail to compile since OnceLock and LazyLock should not unconditionally implement sync + // for all types. These tests are regression tests against the following issues: + // * https://github.com/embassy-rs/embassy/issues/4307 + // * https://github.com/embassy-rs/embassy/issues/3904 + t.compile_fail("tests/ui/sync_impl/lazy_lock_function.rs"); + t.compile_fail("tests/ui/sync_impl/lazy_lock_type.rs"); + t.compile_fail("tests/ui/sync_impl/once_lock.rs"); +} 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 @@ +use embassy_sync::lazy_lock::LazyLock; + +fn main() { + let x = 128u8; + let x_ptr: *const u8 = core::ptr::addr_of!(x); + + let closure_capturing_non_sync_variable = || { + unsafe { + core::ptr::read(x_ptr) + } + }; + + // This should fail to compile because the closure captures a non-Sync variable: x_ptr. + let _lazy_u8: LazyLock = LazyLock::new(closure_capturing_non_sync_variable); +} 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 @@ +use embassy_sync::lazy_lock::LazyLock; + +// *mut u8 is not Sync, so LazyLock should not implement Sync for this type. This should fail to compile. +static GLOBAL: LazyLock<*mut u8> = LazyLock::new(|| core::ptr::null_mut()); + +fn 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 @@ +use embassy_sync::once_lock::OnceLock; + +// *mut u8 is not Sync, so OnceLock should not implement Sync for this type. This should fail to compile. +static GLOBAL: OnceLock<*mut u8> = OnceLock::new(); + +fn main() {} -- cgit