From 16d6bd7ece4c4b9b72f6bd51c9b034270b745525 Mon Sep 17 00:00:00 2001 From: Mica White Date: Sun, 13 Sep 2026 15:12:08 -0400 Subject: Support no_std --- src/collection.rs | 4 +++- src/collection/boxed.rs | 38 ++++++++++++++++++++++++-------- src/collection/guard.rs | 18 ++++++++++----- src/collection/owned.rs | 28 ++++++++++++++++++++---- src/collection/ref.rs | 35 ++++++++++++++++++++++------- src/collection/retry.rs | 52 ++++++++++++++++++++++++++++++++++++++------ src/collection/utils.rs | 6 +++-- src/context.rs | 17 ++++++++++++++- src/context/context.rs | 2 +- src/context/guard.rs | 12 +++++----- src/context/iterator.rs | 6 ++--- src/context/tuple.rs | 2 +- src/handle_unwind.rs | 38 +++++++++++++++++++++++--------- src/key.rs | 47 ++++++++++++++++++++++++++++++++++----- src/lib.rs | 3 +++ src/lockable.rs | 37 +++++++++++++++++++++---------- src/mutex.rs | 13 +++++++++-- src/mutex/guard.rs | 20 ++++++++--------- src/mutex/mutex.rs | 13 ++++++----- src/poisonable.rs | 40 +++++++++++++++++++++++++++++----- src/poisonable/error.rs | 2 +- src/poisonable/flag.rs | 2 +- src/poisonable/guard.rs | 26 ++++++++++++---------- src/poisonable/poisonable.rs | 4 +++- src/rwlock.rs | 25 +++++++++++++++++++-- src/rwlock/read_guard.rs | 20 ++++++++--------- src/rwlock/rwlock.rs | 15 ++++++++----- src/rwlock/write_guard.rs | 20 ++++++++--------- 28 files changed, 402 insertions(+), 143 deletions(-) (limited to 'src') diff --git a/src/collection.rs b/src/collection.rs index c97bbd2..c02e2c2 100755 --- a/src/collection.rs +++ b/src/collection.rs @@ -1,4 +1,6 @@ -use std::cell::UnsafeCell; +use core::cell::UnsafeCell; + +use alloc::vec::Vec; use crate::{lockable::RawLock, ThreadKey}; diff --git a/src/collection/boxed.rs b/src/collection/boxed.rs index 66e6df0..88f3073 100755 --- a/src/collection/boxed.rs +++ b/src/collection/boxed.rs @@ -1,5 +1,8 @@ -use std::cell::UnsafeCell; -use std::fmt::Debug; +use core::cell::UnsafeCell; +use core::fmt::Debug; + +use alloc::boxed::Box; +use alloc::vec::Vec; use crate::lockable::{Lockable, LockableIntoInner, OwnedLockable, RawLock, Sharable}; use crate::{Keyable, ThreadKey}; @@ -169,7 +172,7 @@ impl> AsRef for BoxedLockCollection { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for BoxedLockCollection { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct(stringify!(BoxedLockCollection)) .field("data", &self.child) // there's not much reason to show the sorted locks @@ -207,11 +210,11 @@ impl BoxedLockCollection { pub fn into_child(mut self) -> L { unsafe { // safety: this collection will never be used again - std::ptr::drop_in_place(&raw mut self.locks); + core::ptr::drop_in_place(&raw mut self.locks); // safety: this was allocated using a box, and is now unique let boxed: Box> = Box::from_raw(self.child.cast_mut()); // to prevent a double free - std::mem::forget(self); + core::mem::forget(self); boxed.into_inner() } @@ -327,7 +330,7 @@ impl BoxedLockCollection { locks.sort_by_key(|lock| (&raw const **lock).cast::<()>() as usize); // safety: we're just changing the lifetimes - let locks: Vec<&'static dyn RawLock> = unsafe { std::mem::transmute(locks) }; + let locks: Vec<&'static dyn RawLock> = unsafe { core::mem::transmute(locks) }; let data = &raw const *data; Self { child: data, locks } } @@ -770,9 +773,12 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{Mutex, RwLock, ThreadKey}; + use crate::Mutex; + #[cfg(feature = "std")] + use crate::{RwLock, ThreadKey}; #[test] + #[cfg(feature = "std")] fn from_iterator() { let key = ThreadKey::get().unwrap(); let collection: BoxedLockCollection>> = @@ -786,6 +792,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn from() { let key = ThreadKey::get().unwrap(); let collection = @@ -805,6 +812,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn into_ref_iterator() { let mut key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]); @@ -814,6 +822,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ref_iterator() { let mut key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]); @@ -847,6 +856,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_read_sees_changes() { let mut key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -863,6 +873,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_lock_can_fail() { let key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([Mutex::new(1), Mutex::new(2)]); @@ -880,6 +891,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_read_can_fail() { let key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([RwLock::new(1), RwLock::new(2)]); @@ -897,6 +909,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_works() { let key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([Mutex::new(1), Mutex::new(2)]); @@ -914,6 +927,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_works() { let key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([RwLock::new(1), RwLock::new(2)]); @@ -931,6 +945,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_fails_with_one_exclusive_lock() { let key = ThreadKey::get().unwrap(); let locks = [Mutex::new(1), Mutex::new(2)]; @@ -949,6 +964,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_fails_during_exclusive_lock() { let key = ThreadKey::get().unwrap(); let collection = BoxedLockCollection::new([RwLock::new(1), RwLock::new(2)]); @@ -966,6 +982,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_fails_with_one_exclusive_lock() { let key = ThreadKey::get().unwrap(); let locks = [RwLock::new(1), RwLock::new(2)]; @@ -984,6 +1001,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn unlock_collection_works() { let key = ThreadKey::get().unwrap(); let mutex1 = Mutex::new("foo"); @@ -996,6 +1014,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_unlock_collection_works() { let key = ThreadKey::get().unwrap(); let lock1 = RwLock::new("foo"); @@ -1014,6 +1033,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn works_in_collection() { let key = ThreadKey::get().unwrap(); let mutex1 = RwLock::new(0); @@ -1043,7 +1063,7 @@ mod tests { let mutexes = [Mutex::new(0), Mutex::new(1)]; let collection = BoxedLockCollection::new_ref(&mutexes); - assert!(std::ptr::addr_eq(&raw const mutexes, collection.as_ref())) + assert!(core::ptr::addr_eq(&raw const mutexes, collection.as_ref())) } #[test] @@ -1051,6 +1071,6 @@ mod tests { let mutexes = [Mutex::new(0), Mutex::new(1)]; let collection = BoxedLockCollection::new_ref(&mutexes); - assert!(std::ptr::addr_eq(&raw const mutexes, *collection.child())) + assert!(core::ptr::addr_eq(&raw const mutexes, *collection.child())) } } diff --git a/src/collection/guard.rs b/src/collection/guard.rs index ab66ffe..a9bf66e 100755 --- a/src/collection/guard.rs +++ b/src/collection/guard.rs @@ -1,13 +1,13 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::ops::{Deref, DerefMut}; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::ops::{Deref, DerefMut}; use super::LockGuard; #[mutants::skip] // hashing involves RNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for LockGuard { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.guard.hash(state) } } @@ -20,13 +20,13 @@ impl Hash for LockGuard { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for LockGuard { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for LockGuard { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } @@ -59,10 +59,13 @@ impl AsMut for LockGuard { #[cfg(test)] mod tests { + #[cfg(feature = "std")] use crate::collection::OwnedLockCollection; + #[cfg(feature = "std")] use crate::{LockCollection, Mutex, RwLock, ThreadKey}; #[test] + #[cfg(feature = "std")] fn guard_display_works() { let key = ThreadKey::get().unwrap(); let lock = OwnedLockCollection::new(RwLock::new("Hello, world!")); @@ -71,6 +74,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn deref_mut_works() { let key = ThreadKey::get().unwrap(); let locks = (Mutex::new(1), Mutex::new(2)); @@ -88,6 +92,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn as_ref_works() { let key = ThreadKey::get().unwrap(); let locks = (Mutex::new(1), Mutex::new(2)); @@ -105,6 +110,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn as_mut_works() { let key = ThreadKey::get().unwrap(); let locks = (Mutex::new(1), Mutex::new(2)); diff --git a/src/collection/owned.rs b/src/collection/owned.rs index ab45e86..e53feb7 100755 --- a/src/collection/owned.rs +++ b/src/collection/owned.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::context::LockContext; use crate::lockable::{ Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, @@ -676,10 +678,15 @@ impl OwnedLockCollection { #[cfg(test)] mod tests { + use alloc::{string::String, vec}; + use super::*; - use crate::{LockCollection, Mutex, RwLock, ThreadKey}; + use crate::{LockCollection, Mutex}; + #[cfg(feature = "std")] + use crate::{RwLock, ThreadKey}; #[test] + #[cfg(feature = "std")] fn get_mut_applies_changes() { let key = ThreadKey::get().unwrap(); let mut collection = OwnedLockCollection::new([Mutex::new("foo"), Mutex::new("bar")]); @@ -693,6 +700,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn into_inner_works() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::from([Mutex::new("foo")]); @@ -727,6 +735,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_read_works() { let mut key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new([RwLock::new(24), RwLock::new(42)]); @@ -735,6 +744,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_lock_works() { let mut key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new([RwLock::new(24), RwLock::new(42)]); @@ -750,6 +760,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_lock_can_fail() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new([Mutex::new(1), Mutex::new(2)]); @@ -767,6 +778,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_read_can_fail() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new([RwLock::new(1), RwLock::new(2)]); @@ -784,6 +796,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_works_on_unlocked() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((Mutex::new(0), Mutex::new(1))); @@ -793,6 +806,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_fails_on_locked() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((Mutex::new(0), Mutex::new(1))); @@ -801,7 +815,7 @@ mod tests { s.spawn(|| { let key = ThreadKey::get().unwrap(); let guard = collection.lock(key); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -809,6 +823,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_succeeds_for_unlocked_collection() { let key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -819,6 +834,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_fails_on_locked() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((RwLock::new(0), RwLock::new(1))); @@ -827,7 +843,7 @@ mod tests { s.spawn(|| { let key = ThreadKey::get().unwrap(); let guard = collection.lock(key); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -835,6 +851,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn can_read_twice_on_different_threads() { let key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -846,7 +863,7 @@ mod tests { let guard = collection.read(key); assert_eq!(*guard[0], 24); assert_eq!(*guard[1], 42); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -856,6 +873,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn unlock_collection_works() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((Mutex::new("foo"), Mutex::new("bar"))); @@ -866,6 +884,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_unlock_collection_works() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((RwLock::new("foo"), RwLock::new("bar"))); @@ -897,6 +916,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn works_in_collection() { let key = ThreadKey::get().unwrap(); let collection = diff --git a/src/collection/ref.rs b/src/collection/ref.rs index a422bb2..8ab7120 100755 --- a/src/collection/ref.rs +++ b/src/collection/ref.rs @@ -1,4 +1,6 @@ -use std::fmt::Debug; +use core::fmt::Debug; + +use alloc::vec::Vec; use crate::lockable::{Lockable, OwnedLockable, RawLock, Sharable}; use crate::{Keyable, ThreadKey}; @@ -114,7 +116,7 @@ impl> AsRef for RefLockCollection<'_, L> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for RefLockCollection<'_, L> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct(stringify!(RefLockCollection)) .field("data", self.child) // there's not much reason to show the sorting order @@ -640,7 +642,9 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{Mutex, RwLock, ThreadKey}; + use crate::Mutex; + #[cfg(feature = "std")] + use crate::{RwLock, ThreadKey}; #[test] fn non_duplicates_allowed() { @@ -656,6 +660,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn from() { let key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new("foo"), Mutex::new("bar"), Mutex::new("baz")]; @@ -667,6 +672,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_lock_changes_collection() { let mut key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new(24), Mutex::new(42)]; @@ -684,6 +690,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_read_sees_changes() { let mut key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -702,6 +709,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_lock_can_fail() { let key = ThreadKey::get().unwrap(); let locks = [Mutex::new(1), Mutex::new(2)]; @@ -720,6 +728,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_read_can_fail() { let key = ThreadKey::get().unwrap(); let locks = [RwLock::new(1), RwLock::new(2)]; @@ -738,6 +747,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_succeeds_for_unlocked_collection() { let key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new(24), Mutex::new(42)]; @@ -748,6 +758,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_fails_for_locked_collection() { let key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new(24), Mutex::new(42)]; @@ -758,7 +769,7 @@ mod tests { let key = ThreadKey::get().unwrap(); let guard = mutexes[1].lock(key); assert_eq!(*guard, 42); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -767,6 +778,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_succeeds_for_unlocked_collection() { let key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -777,6 +789,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_fails_for_locked_collection() { let key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -787,7 +800,7 @@ mod tests { let key = ThreadKey::get().unwrap(); let guard = mutexes[1].write(key); assert_eq!(*guard, 42); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -796,6 +809,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn can_read_twice_on_different_threads() { let key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -807,7 +821,7 @@ mod tests { let guard = collection.read(key); assert_eq!(*guard[0], 24); assert_eq!(*guard[1], 42); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -817,6 +831,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn into_ref_iterator() { let mut key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new(0), Mutex::new(1), Mutex::new(2)]; @@ -827,6 +842,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ref_iterator() { let mut key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new(0), Mutex::new(1), Mutex::new(2)]; @@ -837,6 +853,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn works_in_collection() { let key = ThreadKey::get().unwrap(); let mutex1 = RwLock::new(0); @@ -862,6 +879,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn unlock_collection_works() { let key = ThreadKey::get().unwrap(); let mutexes = (Mutex::new("foo"), Mutex::new("bar")); @@ -873,6 +891,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_unlock_collection_works() { let key = ThreadKey::get().unwrap(); let locks = (RwLock::new("foo"), RwLock::new("bar")); @@ -888,7 +907,7 @@ mod tests { let mutexes = [Mutex::new(0), Mutex::new(1)]; let collection = RefLockCollection::new(&mutexes); - assert!(std::ptr::addr_eq(&raw const mutexes, collection.as_ref())) + assert!(core::ptr::addr_eq(&raw const mutexes, collection.as_ref())) } #[test] @@ -896,6 +915,6 @@ mod tests { let mutexes = [Mutex::new(0), Mutex::new(1)]; let collection = RefLockCollection::new(&mutexes); - assert!(std::ptr::addr_eq(&raw const mutexes, collection.child())) + assert!(core::ptr::addr_eq(&raw const mutexes, collection.child())) } } diff --git a/src/collection/retry.rs b/src/collection/retry.rs index b9ac530..1cce663 100755 --- a/src/collection/retry.rs +++ b/src/collection/retry.rs @@ -1,5 +1,6 @@ -use std::cell::Cell; -use std::collections::HashSet; +use core::cell::Cell; + +use alloc::vec::Vec; use crate::collection::utils; use crate::handle_unwind::handle_unwind; @@ -14,6 +15,20 @@ use super::utils::{ }; use super::{LockGuard, RetryingLockCollection}; +cfg_select! { + feature = "std" => { + fn set_with_capacity(capacity: usize) -> std::collections::HashSet { + std::collections::HashSet::with_capacity(capacity) + } + }, + _ => { + #[expect(clippy::missing_const_for_fn)] + fn set_with_capacity(_capacity: usize) -> alloc::collections::btree_set::BTreeSet { + alloc::collections::btree_set::BTreeSet::new() + } + }, +} + /// Checks that a collection contains no duplicate references to a lock. fn contains_duplicates(data: L) -> bool { let mut locks = Vec::new(); @@ -21,7 +36,7 @@ fn contains_duplicates(data: L) -> bool { // cast to *const () so that the v-table pointers are not used for hashing let locks = locks.into_iter().map(|l| (&raw const *l).cast::<()>()); - let mut locks_set = HashSet::with_capacity(locks.len()); + let mut locks_set = set_with_capacity(locks.len()); for lock in locks { if !locks_set.insert(lock) { return true; @@ -1004,9 +1019,14 @@ where #[cfg(test)] mod tests { + use alloc::vec; + use super::*; + #[cfg(feature = "std")] use crate::collection::BoxedLockCollection; - use crate::{Mutex, RwLock, ThreadKey}; + #[cfg(feature = "std")] + use crate::ThreadKey; + use crate::{Mutex, RwLock}; #[test] fn nonduplicate_lock_references_are_allowed() { @@ -1033,6 +1053,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn from() { let key = ThreadKey::get().unwrap(); let collection = @@ -1044,6 +1065,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn new_ref_works() { let key = ThreadKey::get().unwrap(); let mutexes = [Mutex::new(0), Mutex::new(1)]; @@ -1055,6 +1077,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_read_sees_changes() { let mut key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -1071,6 +1094,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn get_mut_affects_scoped_read() { let mut key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -1088,6 +1112,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_lock_can_fail() { let key = ThreadKey::get().unwrap(); let collection = RetryingLockCollection::new([Mutex::new(1), Mutex::new(2)]); @@ -1105,6 +1130,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_read_can_fail() { let key = ThreadKey::get().unwrap(); let collection = RetryingLockCollection::new([RwLock::new(1), RwLock::new(2)]); @@ -1122,6 +1148,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_works() { let key = ThreadKey::get().unwrap(); let collection = RetryingLockCollection::new([Mutex::new(1), Mutex::new(2)]); @@ -1139,6 +1166,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_works() { let key = ThreadKey::get().unwrap(); let collection = RetryingLockCollection::new([RwLock::new(1), RwLock::new(2)]); @@ -1156,6 +1184,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_fails_for_locked_collection() { let key = ThreadKey::get().unwrap(); let mutexes = [RwLock::new(24), RwLock::new(42)]; @@ -1166,7 +1195,7 @@ mod tests { let key = ThreadKey::get().unwrap(); let guard = mutexes[1].write(key); assert_eq!(*guard, 42); - std::mem::forget(guard); + core::mem::forget(guard); }); }); @@ -1175,6 +1204,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locks_all_inner_mutexes() { let key = ThreadKey::get().unwrap(); let mutex1 = Mutex::new(0); @@ -1190,6 +1220,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locks_all_inner_rwlocks() { let key = ThreadKey::get().unwrap(); let rwlock1 = RwLock::new(0); @@ -1205,6 +1236,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn works_with_other_collections() { let key = ThreadKey::get().unwrap(); let mutex1 = Mutex::new(0); @@ -1222,6 +1254,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn from_iterator() { let key = ThreadKey::get().unwrap(); let collection: RetryingLockCollection>> = @@ -1243,6 +1276,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn into_ref_iterator() { let mut key = ThreadKey::get().unwrap(); let collection = RetryingLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]); @@ -1252,6 +1286,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ref_iterator() { let mut key = ThreadKey::get().unwrap(); let collection = RetryingLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]); @@ -1261,6 +1296,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn mut_iterator() { let mut key = ThreadKey::get().unwrap(); let mut collection = @@ -1282,6 +1318,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn lock_empty_lock_collection() { let key = ThreadKey::get().unwrap(); let collection: RetryingLockCollection<[RwLock; 0]> = RetryingLockCollection::new([]); @@ -1295,6 +1332,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_empty_lock_collection() { let key = ThreadKey::get().unwrap(); let collection: RetryingLockCollection<[RwLock; 0]> = RetryingLockCollection::new([]); @@ -1312,7 +1350,7 @@ mod tests { let mutexes = [Mutex::new(0), Mutex::new(1)]; let collection = RetryingLockCollection::new_ref(&mutexes); - assert!(std::ptr::addr_eq(&raw const mutexes, collection.as_ref())) + assert!(core::ptr::addr_eq(&raw const mutexes, collection.as_ref())) } #[test] @@ -1330,7 +1368,7 @@ mod tests { let mutexes = [Mutex::new(0), Mutex::new(1)]; let collection = RetryingLockCollection::new_ref(&mutexes); - assert!(std::ptr::addr_eq(&raw const mutexes, *collection.child())) + assert!(core::ptr::addr_eq(&raw const mutexes, *collection.child())) } #[test] diff --git a/src/collection/utils.rs b/src/collection/utils.rs index e79b78b..236853c 100755 --- a/src/collection/utils.rs +++ b/src/collection/utils.rs @@ -1,4 +1,6 @@ -use std::cell::Cell; +use core::cell::Cell; + +use alloc::vec::Vec; use crate::handle_unwind::handle_unwind; use crate::lockable::{Lockable, RawLock, Sharable}; @@ -32,7 +34,7 @@ pub fn ordered_contains_duplicates(l: &[&dyn RawLock]) -> bool { l.windows(2) // NOTE: addr_eq is necessary because eq would also compare the v-table pointers - .any(|window| std::ptr::addr_eq(window[0], window[1])) + .any(|window| core::ptr::addr_eq(window[0], window[1])) } /// Lock a set of locks in the given order. It's UB to call this without a `ThreadKey` diff --git a/src/context.rs b/src/context.rs index 1707022..12564f1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use crate::ThreadKey; @@ -183,12 +183,14 @@ pub struct ContextGuard<'a, Guard, Key> { #[cfg(test)] mod tests { + #[cfg(feature = "std")] use crate::{ collection::OwnedLockCollection, context::iterator::TryLockNextError, Mutex, RwLock, ThreadKey, }; #[test] + #[cfg(feature = "std")] fn display_works_for_guard() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((Mutex::new("Hello, world!"),)); @@ -199,6 +201,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_mut_works_single_element_tuple() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((RwLock::new(42),)); @@ -235,6 +238,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_mut_works_double_element_tuple() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((RwLock::new(42), RwLock::new(67))); @@ -300,6 +304,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_mut_works_triple_element_tuple() { let key = ThreadKey::get().unwrap(); let collection = OwnedLockCollection::new((RwLock::new(1), RwLock::new(2), RwLock::new(3))); @@ -393,6 +398,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn basic_iteration() { let key = ThreadKey::get().unwrap(); let data = [Mutex::new(1), Mutex::new(3), Mutex::new(8)]; @@ -410,6 +416,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_tuple_of_lists() { let key = ThreadKey::get().unwrap(); let data = ( @@ -435,6 +442,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_list_of_lists() { let key = ThreadKey::get().unwrap(); let data = [ @@ -465,6 +473,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_last_list_of_lists() { let key = ThreadKey::get().unwrap(); let data = [ @@ -486,6 +495,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_last_list_of_empty_list() { let key = ThreadKey::get().unwrap(); let data: [[Mutex; 0]; 0] = []; @@ -498,6 +508,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_list_of_tuples() { let key = ThreadKey::get().unwrap(); let data = [ @@ -534,6 +545,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_last_list_of_tuples() { let key = ThreadKey::get().unwrap(); let data = [ @@ -556,6 +568,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn recurse_last_of_empty_list_of_tuples() { let key = ThreadKey::get().unwrap(); let data: [(Mutex, Mutex); 0] = []; @@ -568,6 +581,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn lock_last_of_list() { let key = ThreadKey::get().unwrap(); let data = [Mutex::new(1), Mutex::new(3), Mutex::new(8)]; @@ -579,6 +593,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_lock_next_works() { let key = ThreadKey::get().unwrap(); let data = [Mutex::new(1), Mutex::new(3), Mutex::new(8)]; diff --git a/src/context/context.rs b/src/context/context.rs index f67d686..67ee6d9 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use crate::{ context::{LockContext, LockingIterator, LockingTuple}, diff --git a/src/context/guard.rs b/src/context/guard.rs index 0898c1f..6cd80ed 100644 --- a/src/context/guard.rs +++ b/src/context/guard.rs @@ -1,13 +1,13 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::ops::{Deref, DerefMut}; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::ops::{Deref, DerefMut}; use super::ContextGuard; #[mutants::skip] // hashing involves RNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for ContextGuard<'_, Guard, Key> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.guard.hash(state) } } @@ -20,13 +20,13 @@ impl Hash for ContextGuard<'_, Guard, Key> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for ContextGuard<'_, Guard, Key> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for ContextGuard<'_, Guard, Key> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } diff --git a/src/context/iterator.rs b/src/context/iterator.rs index 1eacaea..d7f7287 100644 --- a/src/context/iterator.rs +++ b/src/context/iterator.rs @@ -1,7 +1,5 @@ -use std::{ - iter::{Fuse, Peekable, Skip, Take}, - marker::PhantomData, -}; +use core::iter::{Fuse, Peekable, Skip, Take}; +use core::marker::PhantomData; use super::{ContextGuard, LockingIterator}; diff --git a/src/context/tuple.rs b/src/context/tuple.rs index d2a1b0d..65d372a 100644 --- a/src/context/tuple.rs +++ b/src/context/tuple.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use crate::{ context::{ContextGuard, LockingIterator, LockingTuple}, diff --git a/src/handle_unwind.rs b/src/handle_unwind.rs index 42b6fc5..e00bbbd 100755 --- a/src/handle_unwind.rs +++ b/src/handle_unwind.rs @@ -1,13 +1,31 @@ +#[cfg(feature = "std")] use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; -/// Runs `try_fn`. If it unwinds, it will run `catch` and then continue -/// unwinding. This is used instead of `scopeguard` to ensure the `catch` -/// function doesn't run if the thread is already panicking. The unwind -/// must specifically be caused by the `try_fn` -pub fn handle_unwind R, G: FnOnce()>(try_fn: F, catch: G) -> R { - let try_fn = AssertUnwindSafe(try_fn); - catch_unwind(try_fn).unwrap_or_else(|e| { - catch(); - resume_unwind(e) - }) +cfg_select! { + feature = "std" => { + /// Runs `try_fn`. If it unwinds, it will run `catch` and then continue + /// unwinding. This is used instead of `scopeguard` to ensure the `catch` + /// function doesn't run if the thread is already panicking. The unwind + /// must specifically be caused by the `try_fn` + /// + /// This has no effect in `no_std` environments + pub fn handle_unwind R, G: FnOnce()>(try_fn: F, catch: G) -> R { + let try_fn = AssertUnwindSafe(try_fn); + catch_unwind(try_fn).unwrap_or_else(|e| { + catch(); + resume_unwind(e) + }) + } + } + _ => { + /// Runs `try_fn`. If it unwinds, it will run `catch` and then continue + /// unwinding. This is used instead of `scopeguard` to ensure the `catch` + /// function doesn't run if the thread is already panicking. The unwind + /// must specifically be caused by the `try_fn` + /// + /// This has no effect in `no_std` environments + pub fn handle_unwind R, G: FnOnce()>(try_fn: F, _catch: G) -> R { + try_fn() + } + } } diff --git a/src/key.rs b/src/key.rs index c788b32..06f219b 100755 --- a/src/key.rs +++ b/src/key.rs @@ -1,6 +1,7 @@ -use std::cell::{Cell, LazyCell}; -use std::fmt::{self, Debug}; -use std::marker::PhantomData; +#[cfg(feature = "std")] +use core::cell::Cell; +use core::fmt::{self, Debug}; +use core::marker::PhantomData; use sealed::Sealed; @@ -14,8 +15,9 @@ mod sealed { impl Sealed for &mut ThreadKey {} } +#[cfg(feature = "std")] thread_local! { - static KEY: LazyCell = LazyCell::new(KeyCell::default); + static KEY: std::cell::LazyCell = std::cell::LazyCell::new(KeyCell::default); } /// The key for the current thread. @@ -55,7 +57,10 @@ impl Drop for ThreadKey { fn drop(&mut self) { // safety: a thread key cannot be acquired without creating the lock // safety: the key is lost, so it's safe to unlock the cell - unsafe { KEY.with(|key| key.force_unlock()) } + #[cfg(feature = "std")] + unsafe { + KEY.with(|key| key.force_unlock()) + } } } @@ -74,6 +79,7 @@ impl ThreadKey { /// let key = ThreadKey::get().unwrap(); /// ``` #[must_use] + #[cfg(feature = "std")] pub fn get() -> Option { // if this code changes, check to ensure the requirement for // the Drop implementation is still true @@ -83,14 +89,41 @@ impl ThreadKey { }) }) } + + /// Create a `ThreadKey` for the current thread, without checking to see if it + /// has already been acquired. + /// + /// This can be useful for `no_std` environments, where it's not possible to + /// check if the current thread has acquired a `ThreadKey` + /// + /// # Examples + /// + /// ``` + /// use happylock::ThreadKey; + /// + /// let key = ThreadKey::get().unwrap(); + /// ``` + /// + /// # Safety + /// + /// This is unsafe because it allows a thread to have multiple keys at a time. + /// Each thread must have no more than one `ThreadKey` at a time. + #[must_use] + pub const unsafe fn get_unchecked() -> Self { + Self { + phantom: PhantomData, + } + } } /// A dumb lock that's just a wrapper for an [`AtomicBool`]. #[derive(Default)] +#[cfg(feature = "std")] struct KeyCell { is_locked: Cell, } +#[cfg(feature = "std")] impl KeyCell { /// Attempt to lock the `KeyCell`. This is not a fair lock. #[must_use] @@ -107,14 +140,17 @@ impl KeyCell { #[cfg(test)] mod tests { + #[cfg(feature = "std")] use super::*; #[test] + #[cfg(feature = "std")] fn thread_key_returns_some_on_first_call() { assert!(ThreadKey::get().is_some()); } #[test] + #[cfg(feature = "std")] fn thread_key_returns_none_on_second_call() { let key = ThreadKey::get(); assert!(ThreadKey::get().is_none()); @@ -122,6 +158,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn dropping_thread_key_allows_reobtaining() { drop(ThreadKey::get()); assert!(ThreadKey::get().is_some()) diff --git a/src/lib.rs b/src/lib.rs index e6e5e4c..2dbccfa 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![warn(clippy::pedantic)] #![warn(clippy::nursery)] #![warn(clippy::cargo)] @@ -194,6 +195,8 @@ //! [`OwnedLockCollection`]: `collection::OwnedLockCollection` //! [`RetryingLockCollection`]: `collection::RetryingLockCollection` +extern crate alloc; + mod handle_unwind; mod key; diff --git a/src/lockable.rs b/src/lockable.rs index 705887f..e7f7f0a 100755 --- a/src/lockable.rs +++ b/src/lockable.rs @@ -1,4 +1,6 @@ -use std::mem::MaybeUninit; +use core::mem::MaybeUninit; + +use alloc::{boxed::Box, vec::Vec}; /// A raw lock type that may be locked and unlocked /// @@ -662,8 +664,12 @@ unsafe impl OwnedLockable for Vec {} #[cfg(test)] mod tests { + use alloc::vec; + use super::*; - use crate::{LockCollection, Mutex, RwLock, ThreadKey}; + #[cfg(feature = "std")] + use crate::{LockCollection, ThreadKey}; + use crate::{Mutex, RwLock}; #[test] fn mut_ref_get_ptrs() { @@ -673,7 +679,7 @@ mod tests { mutref.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 1); - assert!(std::ptr::addr_eq(lock_ptrs[0], mutref)); + assert!(core::ptr::addr_eq(lock_ptrs[0], mutref)); } #[test] @@ -692,7 +698,7 @@ mod tests { locks.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 1); - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } } #[test] @@ -702,8 +708,8 @@ mod tests { locks.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 2); - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) } } #[test] @@ -722,7 +728,7 @@ mod tests { locks.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 1); - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } } #[test] @@ -732,8 +738,8 @@ mod tests { locks.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 2); - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) } } #[test] @@ -757,6 +763,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn vec_guard_ref() { let key = ThreadKey::get().unwrap(); let locks = vec![RwLock::new(1), RwLock::new(2)]; @@ -774,6 +781,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn vec_data_mut() { let mut key = ThreadKey::get().unwrap(); let mutexes = vec![Mutex::new(1), Mutex::new(2)]; @@ -791,6 +799,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn vec_data_ref() { let mut key = ThreadKey::get().unwrap(); let mutexes = vec![RwLock::new(1), RwLock::new(2)]; @@ -823,7 +832,7 @@ mod tests { locks.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 1); - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } } #[test] @@ -833,8 +842,8 @@ mod tests { locks.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 2); - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } - unsafe { assert!(std::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) } + unsafe { assert!(core::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) } } #[test] @@ -848,6 +857,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn box_guard_mut() { let key = ThreadKey::get().unwrap(); let x = [Mutex::new(1), Mutex::new(2)]; @@ -865,6 +875,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn box_data_mut() { let mut key = ThreadKey::get().unwrap(); let mutexes = vec![Mutex::new(1), Mutex::new(2)].into_boxed_slice(); @@ -882,6 +893,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn box_guard_ref() { let key = ThreadKey::get().unwrap(); let locks = [RwLock::new(1), RwLock::new(2)]; @@ -899,6 +911,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn box_data_ref() { let mut key = ThreadKey::get().unwrap(); let mutexes = vec![RwLock::new(1), RwLock::new(2)].into_boxed_slice(); diff --git a/src/mutex.rs b/src/mutex.rs index d7b0176..3043dfa 100755 --- a/src/mutex.rs +++ b/src/mutex.rs @@ -1,5 +1,5 @@ -use std::cell::UnsafeCell; -use std::marker::PhantomData; +use core::cell::UnsafeCell; +use core::marker::PhantomData; use lock_api::RawMutex; @@ -179,6 +179,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a, R: RawMutex> { #[cfg(test)] mod tests { + #[cfg(feature = "std")] use crate::{LockCollection, ThreadKey}; use super::*; @@ -191,6 +192,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locked_after_read() { let key = ThreadKey::get().unwrap(); let lock: crate::Mutex<_> = Mutex::new("Hello, world!"); @@ -202,6 +204,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn from_works() { let key = ThreadKey::get().unwrap(); let mutex: crate::Mutex<_> = Mutex::from("Hello, world!"); @@ -211,6 +214,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn as_mut_works() { let key = ThreadKey::get().unwrap(); let mut mutex = crate::Mutex::from(42); @@ -222,6 +226,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn display_works_for_guard() { let key = ThreadKey::get().unwrap(); let mutex: crate::Mutex<_> = Mutex::new("Hello, world!"); @@ -230,6 +235,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn display_works_for_ref() { let mutex: crate::Mutex<_> = Mutex::new("Hello, world!"); let guard = unsafe { mutex.try_lock_no_key().unwrap() }; @@ -237,6 +243,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ref_as_mut() { let key = ThreadKey::get().unwrap(); let collection = LockCollection::new(crate::Mutex::new(0)); @@ -252,6 +259,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn guard_as_mut() { let key = ThreadKey::get().unwrap(); let mutex = crate::Mutex::new(0); @@ -267,6 +275,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn dropping_guard_releases_mutex() { let key = ThreadKey::get().unwrap(); let mutex: crate::Mutex<_> = Mutex::new("Hello, world!"); diff --git a/src/mutex/guard.rs b/src/mutex/guard.rs index 538a08a..dad1cd7 100755 --- a/src/mutex/guard.rs +++ b/src/mutex/guard.rs @@ -1,7 +1,7 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; use lock_api::RawMutex; @@ -16,7 +16,7 @@ use super::{Mutex, MutexGuard, MutexRef}; #[mutants::skip] // hashing involves RNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for MutexRef<'_, T, R> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.deref().hash(state) } } @@ -24,13 +24,13 @@ impl Hash for MutexRef<'_, T, R> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for MutexRef<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for MutexRef<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } @@ -90,7 +90,7 @@ impl<'a, T: ?Sized, R: RawMutex> MutexRef<'a, T, R> { #[mutants::skip] // hashing involves RNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for MutexGuard<'_, T, R> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.deref().hash(state) } } @@ -98,13 +98,13 @@ impl Hash for MutexGuard<'_, T, R> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for MutexGuard<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for MutexGuard<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } diff --git a/src/mutex/mutex.rs b/src/mutex/mutex.rs index dc374aa..f6db081 100755 --- a/src/mutex/mutex.rs +++ b/src/mutex/mutex.rs @@ -1,8 +1,9 @@ -use std::cell::UnsafeCell; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::panic::AssertUnwindSafe; +use core::cell::UnsafeCell; +use core::fmt::Debug; +use core::marker::PhantomData; +use core::panic::AssertUnwindSafe; +use alloc::vec::Vec; use lock_api::RawMutex; use crate::handle_unwind::handle_unwind; @@ -147,7 +148,7 @@ impl Mutex { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for Mutex { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { // safety: this is just a try lock, and the value is dropped // immediately after, so there's no risk of blocking ourselves // or any other threads @@ -157,7 +158,7 @@ impl Debug for Mutex { } else { struct LockedPlaceholder; impl Debug for LockedPlaceholder { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("") } } diff --git a/src/poisonable.rs b/src/poisonable.rs index 8dada90..d81b876 100755 --- a/src/poisonable.rs +++ b/src/poisonable.rs @@ -1,5 +1,5 @@ -use std::marker::PhantomData; -use std::sync::atomic::AtomicBool; +use core::marker::PhantomData; +use core::sync::atomic::AtomicBool; use crate::ThreadKey; @@ -68,7 +68,7 @@ pub struct Poisonable { /// [`LockCollection`]: `crate::LockCollection` pub struct PoisonRef<'a, G> { guard: G, - #[cfg(panic = "unwind")] + #[cfg(all(feature = "std", panic = "unwind"))] flag: &'a PoisonFlag, _phantom: PhantomData<&'a ()>, } @@ -137,13 +137,19 @@ pub type TryLockPoisonableResult<'flag, G> = #[cfg(test)] mod tests { + #[cfg(feature = "std")] use std::sync::Arc; + use alloc::vec::Vec; + use super::*; use crate::lockable::Lockable as _; - use crate::{LockCollection, Mutex, RwLock, ThreadKey}; + use crate::Mutex; + #[cfg(feature = "std")] + use crate::{LockCollection, RwLock, ThreadKey}; #[test] + #[cfg(feature = "std")] fn locking_poisoned_mutex_returns_error_in_collection() { let key = ThreadKey::get().unwrap(); let mutex = LockCollection::new(Poisonable::new(Mutex::new(42))); @@ -169,6 +175,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locking_poisoned_rwlock_returns_error_in_collection() { let key = ThreadKey::get().unwrap(); let mutex = LockCollection::new(Poisonable::new(RwLock::new(42))); @@ -202,6 +209,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn non_poisoned_get_mut_is_err() { let mut mutex = Poisonable::new(Mutex::new(42)); @@ -226,6 +234,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn poisoned_into_inner() { let mutex = Poisonable::from(Mutex::new("foo")); @@ -250,6 +259,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn poisoned_into_child() { let mutex = Poisonable::from(Mutex::new("foo")); @@ -268,6 +278,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_lock_can_poison() { let key = ThreadKey::get().unwrap(); let mutex = Poisonable::new(Mutex::new(42)); @@ -292,6 +303,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_lock_can_fail() { let key = ThreadKey::get().unwrap(); let mutex = Poisonable::new(Mutex::new(42)); @@ -309,6 +321,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_lock_can_succeed() { let rwlock = Poisonable::new(RwLock::new(42)); @@ -324,6 +337,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_read_can_poison() { let key = ThreadKey::get().unwrap(); let mutex = Poisonable::new(RwLock::new(42)); @@ -348,6 +362,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_read_can_fail() { let key = ThreadKey::get().unwrap(); let rwlock = Poisonable::new(RwLock::new(42)); @@ -365,6 +380,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn scoped_try_read_can_succeed() { let rwlock = Poisonable::new(RwLock::new(42)); @@ -380,6 +396,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn display_works() { let key = ThreadKey::get().unwrap(); let mutex = Poisonable::new(Mutex::new("Hello, world!")); @@ -390,6 +407,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ref_as_ref() { let key = ThreadKey::get().unwrap(); let collection = LockCollection::new(Poisonable::new(Mutex::new("foo"))); @@ -401,6 +419,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ref_as_mut() { let key = ThreadKey::get().unwrap(); let collection = LockCollection::new(Poisonable::new(Mutex::new("foo"))); @@ -418,6 +437,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn guard_as_ref() { let key = ThreadKey::get().unwrap(); let collection = Poisonable::new(Mutex::new("foo")); @@ -429,6 +449,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn guard_as_mut() { let key = ThreadKey::get().unwrap(); let mutex = Poisonable::new(Mutex::new("foo")); @@ -446,6 +467,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn deref_mut_in_collection() { let key = ThreadKey::get().unwrap(); let collection = LockCollection::new(Poisonable::new(Mutex::new(42))); @@ -469,10 +491,14 @@ mod tests { poisonable.get_ptrs(&mut lock_ptrs); assert_eq!(lock_ptrs.len(), 1); - assert!(std::ptr::addr_eq(lock_ptrs[0], &raw const poisonable.inner)); + assert!(core::ptr::addr_eq( + lock_ptrs[0], + &raw const poisonable.inner + )); } #[test] + #[cfg(feature = "std")] fn clear_poison_for_poisoned_mutex() { let mutex = Arc::new(Poisonable::new(Mutex::new(0))); let c_mutex = Arc::clone(&mutex); @@ -497,6 +523,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn clear_poison_for_poisoned_rwlock() { let lock = Arc::new(Poisonable::new(RwLock::new(0))); let c_mutex = Arc::clone(&lock); @@ -522,6 +549,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn error_as_ref() { let mutex = Poisonable::new(Mutex::new("foo")); @@ -543,6 +571,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn error_as_mut() { let mutex = Poisonable::new(Mutex::new("foo")); @@ -570,6 +599,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_error_from_lock_error() { let mutex = Poisonable::new(Mutex::new("foo")); diff --git a/src/poisonable/error.rs b/src/poisonable/error.rs index eed454b..b7b9206 100755 --- a/src/poisonable/error.rs +++ b/src/poisonable/error.rs @@ -1,5 +1,5 @@ +use core::error::Error; use core::fmt; -use std::error::Error; use super::{PoisonError, PoisonGuard, TryLockPoisonableError}; diff --git a/src/poisonable/flag.rs b/src/poisonable/flag.rs index 9186bbc..9877245 100755 --- a/src/poisonable/flag.rs +++ b/src/poisonable/flag.rs @@ -1,5 +1,5 @@ #[cfg(panic = "unwind")] -use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; +use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; use super::PoisonFlag; diff --git a/src/poisonable/guard.rs b/src/poisonable/guard.rs index 32b4ee8..c4d9250 100755 --- a/src/poisonable/guard.rs +++ b/src/poisonable/guard.rs @@ -1,16 +1,18 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; use super::{PoisonFlag, PoisonGuard, PoisonRef}; impl<'a, Guard> PoisonRef<'a, Guard> { // This is used so that we don't keep accidentally adding the flag reference + #[allow(clippy::allow_attributes)] + #[allow(unused_variables)] pub(super) const fn new(flag: &'a PoisonFlag, guard: Guard) -> Self { Self { guard, - #[cfg(panic = "unwind")] + #[cfg(all(feature = "std", panic = "unwind"))] flag, _phantom: PhantomData, } @@ -19,7 +21,7 @@ impl<'a, Guard> PoisonRef<'a, Guard> { impl Drop for PoisonRef<'_, Guard> { fn drop(&mut self) { - #[cfg(panic = "unwind")] + #[cfg(all(feature = "std", panic = "unwind"))] if std::thread::panicking() { self.flag.poison(); } @@ -29,7 +31,7 @@ impl Drop for PoisonRef<'_, Guard> { #[mutants::skip] // hashing involves RNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for PoisonRef<'_, Guard> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.guard.hash(state) } } @@ -37,13 +39,13 @@ impl Hash for PoisonRef<'_, Guard> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for PoisonRef<'_, Guard> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for PoisonRef<'_, Guard> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } @@ -77,7 +79,7 @@ impl AsMut for PoisonRef<'_, Guard> { #[mutants::skip] // hashing involves RNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for PoisonGuard<'_, Guard> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.guard.hash(state) } } @@ -85,13 +87,13 @@ impl Hash for PoisonGuard<'_, Guard> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for PoisonGuard<'_, Guard> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&self.guard, f) } } impl Display for PoisonGuard<'_, Guard> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&self.guard, f) } } diff --git a/src/poisonable/poisonable.rs b/src/poisonable/poisonable.rs index 0134ff1..ccca07e 100755 --- a/src/poisonable/poisonable.rs +++ b/src/poisonable/poisonable.rs @@ -1,4 +1,6 @@ -use std::panic::{RefUnwindSafe, UnwindSafe}; +use core::panic::{RefUnwindSafe, UnwindSafe}; + +use alloc::vec::Vec; use crate::collection::OwnedLockCollection; use crate::handle_unwind::handle_unwind; diff --git a/src/rwlock.rs b/src/rwlock.rs index fca132d..bb9785a 100755 --- a/src/rwlock.rs +++ b/src/rwlock.rs @@ -1,5 +1,5 @@ -use std::cell::UnsafeCell; -use std::marker::PhantomData; +use core::cell::UnsafeCell; +use core::marker::PhantomData; use lock_api::RawRwLock; @@ -123,11 +123,14 @@ pub struct RwLockWriteGuard<'a, T: ?Sized, R: RawRwLock> { #[cfg(test)] mod tests { + #[cfg(feature = "std")] use crate::LockCollection; use crate::RwLock; + #[cfg(feature = "std")] use crate::ThreadKey; #[test] + #[cfg(feature = "std")] fn unlocked_when_initialized() { let key = ThreadKey::get().unwrap(); let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); @@ -137,6 +140,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locked_after_read() { let key = ThreadKey::get().unwrap(); let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); @@ -148,6 +152,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locked_after_write() { let key = ThreadKey::get().unwrap(); let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); @@ -159,6 +164,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn locked_after_scoped_write() { let mut key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("Hello, world!"); @@ -177,6 +183,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn get_mut_works() { let key = ThreadKey::get().unwrap(); let mut lock = crate::RwLock::from(42); @@ -188,6 +195,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_write_can_fail() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("Hello"); @@ -205,6 +213,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn try_read_can_fail() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("Hello"); @@ -222,6 +231,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_display_works() { let key = ThreadKey::get().unwrap(); let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); @@ -230,6 +240,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn write_display_works() { let key = ThreadKey::get().unwrap(); let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); @@ -238,6 +249,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_ref_display_works() { let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); let guard = unsafe { lock.try_read_no_key().unwrap() }; @@ -245,6 +257,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn write_ref_display_works() { let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); let guard = unsafe { lock.try_write_no_key().unwrap() }; @@ -262,6 +275,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn dropping_write_guard_releases_rwlock() { let key = ThreadKey::get().unwrap(); let lock: crate::RwLock<_> = RwLock::new("Hello, world!"); @@ -273,6 +287,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn unlock_write() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("Hello, world"); @@ -286,6 +301,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn unlock_read() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("Hello, world"); @@ -299,6 +315,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_ref_as_ref() { let key = ThreadKey::get().unwrap(); let lock = LockCollection::new(crate::RwLock::new("hi")); @@ -308,6 +325,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn read_guard_as_ref() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("hi"); @@ -317,6 +335,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn write_ref_as_ref() { let key = ThreadKey::get().unwrap(); let lock = LockCollection::new(crate::RwLock::new("hi")); @@ -326,6 +345,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn write_guard_as_ref() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("hi"); @@ -335,6 +355,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn write_guard_as_mut() { let key = ThreadKey::get().unwrap(); let lock = crate::RwLock::new("hi"); diff --git a/src/rwlock/read_guard.rs b/src/rwlock/read_guard.rs index f3161f5..7ca73d1 100755 --- a/src/rwlock/read_guard.rs +++ b/src/rwlock/read_guard.rs @@ -1,7 +1,7 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::marker::PhantomData; -use std::ops::Deref; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::marker::PhantomData; +use core::ops::Deref; use lock_api::RawRwLock; @@ -16,7 +16,7 @@ use super::{RwLock, RwLockReadGuard, RwLockReadRef}; #[mutants::skip] // hashing involves PRNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for RwLockReadRef<'_, T, R> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.deref().hash(state) } } @@ -24,13 +24,13 @@ impl Hash for RwLockReadRef<'_, T, R> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for RwLockReadRef<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for RwLockReadRef<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } @@ -72,7 +72,7 @@ impl<'a, T: ?Sized, R: RawRwLock> RwLockReadRef<'a, T, R> { #[mutants::skip] // hashing involves PRNG and is hard to test #[cfg(not(tarpaulin_include))] impl Hash for RwLockReadGuard<'_, T, R> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.deref().hash(state) } } @@ -80,13 +80,13 @@ impl Hash for RwLockReadGuard<'_, T, R> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for RwLockReadGuard<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for RwLockReadGuard<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs index 6adf73a..72e7742 100755 --- a/src/rwlock/rwlock.rs +++ b/src/rwlock/rwlock.rs @@ -1,8 +1,9 @@ -use std::cell::UnsafeCell; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::panic::AssertUnwindSafe; +use core::cell::UnsafeCell; +use core::fmt::Debug; +use core::marker::PhantomData; +use core::panic::AssertUnwindSafe; +use alloc::vec::Vec; use lock_api::RawRwLock; use crate::handle_unwind::handle_unwind; @@ -163,7 +164,7 @@ impl RwLock { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for RwLock { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { // safety: this is just a try lock, and the value is dropped // immediately after, so there's no risk of blocking ourselves // or any other threads @@ -172,7 +173,7 @@ impl Debug for RwLock { } else { struct LockedPlaceholder; impl Debug for LockedPlaceholder { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("") } } @@ -586,6 +587,8 @@ impl RwLock { /// Attempts to create an exclusive lock without a key. Locking this /// without exclusive access to the key is undefined behavior. #[cfg(test)] + #[allow(clippy::allow_attributes)] + #[allow(dead_code)] pub(crate) unsafe fn try_write_no_key(&self) -> Option> { unsafe { if self.raw_try_write() { diff --git a/src/rwlock/write_guard.rs b/src/rwlock/write_guard.rs index 823f7a4..5e367bd 100755 --- a/src/rwlock/write_guard.rs +++ b/src/rwlock/write_guard.rs @@ -1,7 +1,7 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; use lock_api::RawRwLock; @@ -16,7 +16,7 @@ use super::{RwLock, RwLockWriteGuard, RwLockWriteRef}; #[mutants::skip] // hashing involves PRNG and is difficult to test #[cfg(not(tarpaulin_include))] impl Hash for RwLockWriteRef<'_, T, R> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.deref().hash(state) } } @@ -24,13 +24,13 @@ impl Hash for RwLockWriteRef<'_, T, R> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for RwLockWriteRef<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for RwLockWriteRef<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } @@ -87,7 +87,7 @@ impl<'a, T: ?Sized + 'a, R: RawRwLock> RwLockWriteRef<'a, T, R> { #[mutants::skip] // hashing involves PRNG and is difficult to test #[cfg(not(tarpaulin_include))] impl Hash for RwLockWriteGuard<'_, T, R> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.deref().hash(state) } } @@ -95,13 +95,13 @@ impl Hash for RwLockWriteGuard<'_, T, R> { #[mutants::skip] #[cfg(not(tarpaulin_include))] impl Debug for RwLockWriteGuard<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(&**self, f) } } impl Display for RwLockWriteGuard<'_, T, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(&**self, f) } } -- cgit v1.3.1