summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/collection/boxed.rs1
-rw-r--r--src/collection/guard.rs6
-rw-r--r--src/collection/owned.rs2
-rw-r--r--src/collection/ref.rs1
-rw-r--r--src/key.rs1
-rw-r--r--src/mutex.rs17
-rw-r--r--src/mutex/guard.rs8
-rw-r--r--src/mutex/mutex.rs1
-rw-r--r--src/poisonable.rs26
-rw-r--r--src/poisonable/error.rs2
-rw-r--r--src/poisonable/flag.rs1
-rw-r--r--src/poisonable/guard.rs8
-rw-r--r--src/poisonable/poisonable.rs8
-rw-r--r--src/rwlock.rs31
-rw-r--r--src/rwlock/read_guard.rs8
-rw-r--r--src/rwlock/read_lock.rs1
-rw-r--r--src/rwlock/rwlock.rs1
-rw-r--r--src/rwlock/write_guard.rs8
-rw-r--r--src/rwlock/write_lock.rs1
19 files changed, 126 insertions, 6 deletions
diff --git a/src/collection/boxed.rs b/src/collection/boxed.rs
index 7a84b2a..98d7632 100644
--- a/src/collection/boxed.rs
+++ b/src/collection/boxed.rs
@@ -154,6 +154,7 @@ impl<T, L: AsRef<T>> AsRef<T> for BoxedLockCollection<L> {
}
}
+#[mutants::skip]
impl<L: Debug> Debug for BoxedLockCollection<L> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(stringify!(BoxedLockCollection))
diff --git a/src/collection/guard.rs b/src/collection/guard.rs
index fc8df30..9412343 100644
--- a/src/collection/guard.rs
+++ b/src/collection/guard.rs
@@ -6,32 +6,38 @@ use crate::key::Keyable;
use super::LockGuard;
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: PartialEq, Key: Keyable> PartialEq for LockGuard<'_, Guard, Key> {
fn eq(&self, other: &Self) -> bool {
self.guard.eq(&other.guard)
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: PartialOrd, Key: Keyable> PartialOrd for LockGuard<'_, Guard, Key> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.guard.partial_cmp(&other.guard)
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: Eq, Key: Keyable> Eq for LockGuard<'_, Guard, Key> {}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: Ord, Key: Keyable> Ord for LockGuard<'_, Guard, Key> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.guard.cmp(&other.guard)
}
}
+#[mutants::skip] // hashing involves RNG and is hard to test
impl<Guard: Hash, Key: Keyable> Hash for LockGuard<'_, Guard, Key> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
+#[mutants::skip]
impl<Guard: Debug, Key: Keyable> Debug for LockGuard<'_, Guard, Key> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
diff --git a/src/collection/owned.rs b/src/collection/owned.rs
index 8e8afce..a96300d 100644
--- a/src/collection/owned.rs
+++ b/src/collection/owned.rs
@@ -7,6 +7,7 @@ use crate::Keyable;
use super::{utils, LockGuard, OwnedLockCollection};
+#[mutants::skip] // it's hard to test individual locks in an OwnedLockCollection
fn get_locks<L: Lockable>(data: &L) -> Vec<&dyn RawLock> {
let mut locks = Vec::new();
data.get_ptrs(&mut locks);
@@ -61,6 +62,7 @@ unsafe impl<L: Lockable> Lockable for OwnedLockCollection<L> {
where
Self: 'g;
+ #[mutants::skip] // It's hard to test lkocks in an OwnedLockCollection, because they're owned
fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn RawLock>) {
self.data.get_ptrs(ptrs)
}
diff --git a/src/collection/ref.rs b/src/collection/ref.rs
index 2f4db20..512bdec 100644
--- a/src/collection/ref.rs
+++ b/src/collection/ref.rs
@@ -108,6 +108,7 @@ impl<T, L: AsRef<T>> AsRef<T> for RefLockCollection<'_, L> {
}
}
+#[mutants::skip]
impl<L: Debug> Debug for RefLockCollection<'_, L> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(stringify!(RefLockCollection))
diff --git a/src/key.rs b/src/key.rs
index 768f09e..c7369be 100644
--- a/src/key.rs
+++ b/src/key.rs
@@ -43,6 +43,7 @@ unsafe impl Keyable for &mut ThreadKey {}
// Safety: a &ThreadKey is useless by design.
unsafe impl Sync for ThreadKey {}
+#[mutants::skip]
impl Debug for ThreadKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ThreadKey")
diff --git a/src/mutex.rs b/src/mutex.rs
index 004e5d4..99d0981 100644
--- a/src/mutex.rs
+++ b/src/mutex.rs
@@ -161,7 +161,7 @@ pub struct MutexGuard<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable + 'key, R: RawM
#[cfg(test)]
mod tests {
- use crate::ThreadKey;
+ use crate::{LockCollection, ThreadKey};
use super::*;
@@ -199,6 +199,21 @@ mod tests {
}
#[test]
+ fn ord_works() {
+ let key = ThreadKey::get().unwrap();
+ let mutex1: crate::Mutex<_> = Mutex::new(1);
+ let mutex2: crate::Mutex<_> = Mutex::new(2);
+ let mutex3: crate::Mutex<_> = Mutex::new(2);
+ let collection = LockCollection::try_new((&mutex1, &mutex2, &mutex3)).unwrap();
+
+ let guard = collection.lock(key);
+ assert!(guard.0 < guard.1);
+ assert!(guard.1 > guard.0);
+ assert!(guard.1 == guard.2);
+ assert!(guard.0 != guard.2)
+ }
+
+ #[test]
fn dropping_guard_releases_mutex() {
let mut 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 0d35cf4..f7a01a4 100644
--- a/src/mutex/guard.rs
+++ b/src/mutex/guard.rs
@@ -33,12 +33,14 @@ impl<T: Ord + ?Sized, R: RawMutex> Ord for MutexRef<'_, T, R> {
}
}
+#[mutants::skip] // hashing involves RNG and is hard to test
impl<T: Hash + ?Sized, R: RawMutex> Hash for MutexRef<'_, T, R> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
+#[mutants::skip]
impl<T: Debug + ?Sized, R: RawMutex> Debug for MutexRef<'_, T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
@@ -103,14 +105,17 @@ impl<'a, T: ?Sized, R: RawMutex> MutexRef<'a, T, R> {
// it's kinda annoying to re-implement some of this stuff on guards
// there's nothing i can do about that
+#[mutants::skip] // it's hard to get two guards safely
impl<T: PartialEq + ?Sized, R: RawMutex, Key: Keyable> PartialEq for MutexGuard<'_, '_, T, Key, R> {
fn eq(&self, other: &Self) -> bool {
self.deref().eq(&**other)
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<T: Eq + ?Sized, R: RawMutex, Key: Keyable> Eq for MutexGuard<'_, '_, T, Key, R> {}
+#[mutants::skip] // it's hard to get two guards safely
impl<T: PartialOrd + ?Sized, R: RawMutex, Key: Keyable> PartialOrd
for MutexGuard<'_, '_, T, Key, R>
{
@@ -119,18 +124,21 @@ impl<T: PartialOrd + ?Sized, R: RawMutex, Key: Keyable> PartialOrd
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<T: Ord + ?Sized, R: RawMutex, Key: Keyable> Ord for MutexGuard<'_, '_, T, Key, R> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.deref().cmp(&**other)
}
}
+#[mutants::skip] // hashing involves RNG and is hard to test
impl<T: Hash + ?Sized, R: RawMutex, Key: Keyable> Hash for MutexGuard<'_, '_, T, Key, R> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
+#[mutants::skip]
impl<T: Debug + ?Sized, Key: Keyable, R: RawMutex> Debug for MutexGuard<'_, '_, T, Key, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
diff --git a/src/mutex/mutex.rs b/src/mutex/mutex.rs
index 7a3f75c..5b838a2 100644
--- a/src/mutex/mutex.rs
+++ b/src/mutex/mutex.rs
@@ -129,6 +129,7 @@ impl<T, R: RawMutex> Mutex<T, R> {
}
}
+#[mutants::skip]
impl<T: ?Sized + Debug, R: RawMutex> Debug for Mutex<T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// safety: this is just a try lock, and the value is dropped
diff --git a/src/poisonable.rs b/src/poisonable.rs
index da7758f..e577ce9 100644
--- a/src/poisonable.rs
+++ b/src/poisonable.rs
@@ -96,7 +96,7 @@ pub type TryLockPoisonableResult<'flag, 'key, G, Key> =
mod tests {
use super::*;
use crate::lockable::Lockable;
- use crate::{Mutex, ThreadKey};
+ use crate::{LockCollection, Mutex, ThreadKey};
#[test]
fn display_works() {
@@ -109,6 +109,24 @@ mod tests {
}
#[test]
+ fn ord_works() {
+ let key = ThreadKey::get().unwrap();
+ let lock1 = Poisonable::new(Mutex::new(1));
+ let lock2 = Poisonable::new(Mutex::new(3));
+ let lock3 = Poisonable::new(Mutex::new(3));
+ let collection = LockCollection::try_new((&lock1, &lock2, &lock3)).unwrap();
+
+ let guard = collection.lock(key);
+ let guard1 = guard.0.as_ref().unwrap();
+ let guard2 = guard.1.as_ref().unwrap();
+ let guard3 = guard.2.as_ref().unwrap();
+ assert!(guard1 < guard2);
+ assert!(guard2 > guard1);
+ assert!(guard2 == guard3);
+ assert!(guard1 != guard3);
+ }
+
+ #[test]
fn get_ptrs() {
let mutex = Mutex::new(5);
let poisonable = Poisonable::new(mutex);
@@ -118,4 +136,10 @@ mod tests {
assert_eq!(lock_ptrs.len(), 1);
assert!(std::ptr::addr_eq(lock_ptrs[0], &poisonable.inner));
}
+
+ #[test]
+ fn new_poisonable_is_not_poisoned() {
+ let mutex = Poisonable::new(Mutex::new(42));
+ assert!(!mutex.is_poisoned());
+ }
}
diff --git a/src/poisonable/error.rs b/src/poisonable/error.rs
index d543294..9721ce4 100644
--- a/src/poisonable/error.rs
+++ b/src/poisonable/error.rs
@@ -3,6 +3,7 @@ use std::error::Error;
use super::{PoisonError, PoisonGuard, TryLockPoisonableError};
+#[mutants::skip]
impl<Guard> fmt::Debug for PoisonError<Guard> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PoisonError").finish_non_exhaustive()
@@ -149,6 +150,7 @@ impl<Guard> PoisonError<Guard> {
}
}
+#[mutants::skip]
impl<G, Key> fmt::Debug for TryLockPoisonableError<'_, '_, G, Key> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
diff --git a/src/poisonable/flag.rs b/src/poisonable/flag.rs
index 7714f5f..6b567c8 100644
--- a/src/poisonable/flag.rs
+++ b/src/poisonable/flag.rs
@@ -28,6 +28,7 @@ impl PoisonFlag {
Self()
}
+ #[mutants::skip] // None of the tests have panic = "abort", so this can't be tested
pub fn is_poisoned(&self) -> bool {
false
}
diff --git a/src/poisonable/guard.rs b/src/poisonable/guard.rs
index 97d1c60..36566f5 100644
--- a/src/poisonable/guard.rs
+++ b/src/poisonable/guard.rs
@@ -48,12 +48,14 @@ impl<Guard: Ord> Ord for PoisonRef<'_, Guard> {
}
}
+#[mutants::skip] // hashing involves RNG and is hard to test
impl<Guard: Hash> Hash for PoisonRef<'_, Guard> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
+#[mutants::skip]
impl<Guard: Debug> Debug for PoisonRef<'_, Guard> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
@@ -92,32 +94,38 @@ impl<Guard> AsMut<Guard> for PoisonRef<'_, Guard> {
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: PartialEq, Key: Keyable> PartialEq for PoisonGuard<'_, '_, Guard, Key> {
fn eq(&self, other: &Self) -> bool {
self.guard.eq(&other.guard)
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: PartialOrd, Key: Keyable> PartialOrd for PoisonGuard<'_, '_, Guard, Key> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.guard.partial_cmp(&other.guard)
}
}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: Eq, Key: Keyable> Eq for PoisonGuard<'_, '_, Guard, Key> {}
+#[mutants::skip] // it's hard to get two guards safely
impl<Guard: Ord, Key: Keyable> Ord for PoisonGuard<'_, '_, Guard, Key> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.guard.cmp(&other.guard)
}
}
+#[mutants::skip] // hashing involves RNG and is hard to test
impl<Guard: Hash, Key: Keyable> Hash for PoisonGuard<'_, '_, Guard, Key> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
+#[mutants::skip]
impl<Guard: Debug, Key: Keyable> Debug for PoisonGuard<'_, '_, Guard, Key> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&self.guard, f)
diff --git a/src/poisonable/poisonable.rs b/src/poisonable/poisonable.rs
index c6da89d..0bc2b03 100644
--- a/src/poisonable/poisonable.rs
+++ b/src/poisonable/poisonable.rs
@@ -56,9 +56,9 @@ unsafe impl<L: Lockable> Lockable for Poisonable<L> {
let ref_guard = PoisonRef::new(&self.poisoned, self.inner.guard());
if self.is_poisoned() {
- Ok(ref_guard)
- } else {
Err(PoisonError::new(ref_guard))
+ } else {
+ Ok(ref_guard)
}
}
}
@@ -73,9 +73,9 @@ unsafe impl<L: Sharable> Sharable for Poisonable<L> {
let ref_guard = PoisonRef::new(&self.poisoned, self.inner.read_guard());
if self.is_poisoned() {
- Ok(ref_guard)
- } else {
Err(PoisonError::new(ref_guard))
+ } else {
+ Ok(ref_guard)
}
}
}
diff --git a/src/rwlock.rs b/src/rwlock.rs
index ea7d3f0..f78e648 100644
--- a/src/rwlock.rs
+++ b/src/rwlock.rs
@@ -117,6 +117,7 @@ pub struct RwLockWriteGuard<'a, 'key: 'a, T: ?Sized, Key: Keyable + 'key, R: Raw
#[cfg(test)]
mod tests {
use crate::lockable::Lockable;
+ use crate::LockCollection;
use crate::RwLock;
use crate::ThreadKey;
@@ -234,6 +235,21 @@ mod tests {
}
#[test]
+ fn write_ord() {
+ let key = ThreadKey::get().unwrap();
+ let lock1: crate::RwLock<_> = RwLock::new(1);
+ let lock2: crate::RwLock<_> = RwLock::new(5);
+ let lock3: crate::RwLock<_> = RwLock::new(5);
+ let collection = LockCollection::try_new((&lock1, &lock2, &lock3)).unwrap();
+ let guard = collection.lock(key);
+
+ assert!(guard.0 < guard.1);
+ assert!(guard.1 > guard.0);
+ assert!(guard.1 == guard.2);
+ assert!(guard.0 != guard.2);
+ }
+
+ #[test]
fn read_ref_display_works() {
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
let guard = unsafe { lock.try_read_no_key().unwrap() };
@@ -248,6 +264,21 @@ mod tests {
}
#[test]
+ fn read_ord() {
+ let key = ThreadKey::get().unwrap();
+ let lock1: crate::RwLock<_> = RwLock::new(1);
+ let lock2: crate::RwLock<_> = RwLock::new(5);
+ let lock3: crate::RwLock<_> = RwLock::new(5);
+ let collection = LockCollection::try_new((&lock1, &lock2, &lock3)).unwrap();
+ let guard = collection.read(key);
+
+ assert!(guard.0 < guard.1);
+ assert!(guard.1 > guard.0);
+ assert!(guard.1 == guard.2);
+ assert!(guard.0 != guard.2);
+ }
+
+ #[test]
fn dropping_read_ref_releases_rwlock() {
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
diff --git a/src/rwlock/read_guard.rs b/src/rwlock/read_guard.rs
index 8678a8e..2195e44 100644
--- a/src/rwlock/read_guard.rs
+++ b/src/rwlock/read_guard.rs
@@ -33,12 +33,14 @@ impl<T: Ord + ?Sized, R: RawRwLock> Ord for RwLockReadRef<'_, T, R> {
}
}
+#[mutants::skip] // hashing involves PRNG and is hard to test
impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadRef<'_, T, R> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
+#[mutants::skip]
impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockReadRef<'_, T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
@@ -85,6 +87,7 @@ impl<'a, T: ?Sized, R: RawRwLock> RwLockReadRef<'a, T, R> {
}
}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: PartialEq + ?Sized, R: RawRwLock, Key: Keyable> PartialEq
for RwLockReadGuard<'_, '_, T, Key, R>
{
@@ -93,8 +96,10 @@ impl<T: PartialEq + ?Sized, R: RawRwLock, Key: Keyable> PartialEq
}
}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: Eq + ?Sized, R: RawRwLock, Key: Keyable> Eq for RwLockReadGuard<'_, '_, T, Key, R> {}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: PartialOrd + ?Sized, R: RawRwLock, Key: Keyable> PartialOrd
for RwLockReadGuard<'_, '_, T, Key, R>
{
@@ -103,18 +108,21 @@ impl<T: PartialOrd + ?Sized, R: RawRwLock, Key: Keyable> PartialOrd
}
}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: Ord + ?Sized, R: RawRwLock, Key: Keyable> Ord for RwLockReadGuard<'_, '_, T, Key, R> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.deref().cmp(&**other)
}
}
+#[mutants::skip] // hashing involves PRNG and is hard to test
impl<T: Hash + ?Sized, R: RawRwLock, Key: Keyable> Hash for RwLockReadGuard<'_, '_, T, Key, R> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
+#[mutants::skip]
impl<T: Debug + ?Sized, Key: Keyable, R: RawRwLock> Debug for RwLockReadGuard<'_, '_, T, Key, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
diff --git a/src/rwlock/read_lock.rs b/src/rwlock/read_lock.rs
index ae593e2..5ac0bbb 100644
--- a/src/rwlock/read_lock.rs
+++ b/src/rwlock/read_lock.rs
@@ -33,6 +33,7 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for ReadLock<'_, T, R>
}
}
+#[mutants::skip]
impl<T: ?Sized + Debug, R: RawRwLock> Debug for ReadLock<'_, T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// safety: this is just a try lock, and the value is dropped
diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs
index a249675..7a105d7 100644
--- a/src/rwlock/rwlock.rs
+++ b/src/rwlock/rwlock.rs
@@ -140,6 +140,7 @@ impl<T, R: RawRwLock> RwLock<T, R> {
}
}
+#[mutants::skip]
impl<T: ?Sized + Debug, R: RawRwLock> Debug for RwLock<T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// safety: this is just a try lock, and the value is dropped
diff --git a/src/rwlock/write_guard.rs b/src/rwlock/write_guard.rs
index aec3d3d..ff559b8 100644
--- a/src/rwlock/write_guard.rs
+++ b/src/rwlock/write_guard.rs
@@ -33,12 +33,14 @@ impl<T: Ord + ?Sized, R: RawRwLock> Ord for RwLockWriteRef<'_, T, R> {
}
}
+#[mutants::skip] // hashing involves PRNG and is difficult to test
impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteRef<'_, T, R> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
+#[mutants::skip]
impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockWriteRef<'_, T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
@@ -100,6 +102,7 @@ impl<'a, T: ?Sized + 'a, R: RawRwLock> RwLockWriteRef<'a, T, R> {
}
}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: PartialEq + ?Sized, R: RawRwLock, Key: Keyable> PartialEq
for RwLockWriteGuard<'_, '_, T, Key, R>
{
@@ -108,8 +111,10 @@ impl<T: PartialEq + ?Sized, R: RawRwLock, Key: Keyable> PartialEq
}
}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: Eq + ?Sized, R: RawRwLock, Key: Keyable> Eq for RwLockWriteGuard<'_, '_, T, Key, R> {}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: PartialOrd + ?Sized, R: RawRwLock, Key: Keyable> PartialOrd
for RwLockWriteGuard<'_, '_, T, Key, R>
{
@@ -118,18 +123,21 @@ impl<T: PartialOrd + ?Sized, R: RawRwLock, Key: Keyable> PartialOrd
}
}
+#[mutants::skip] // it's hard to get two read guards safely
impl<T: Ord + ?Sized, R: RawRwLock, Key: Keyable> Ord for RwLockWriteGuard<'_, '_, T, Key, R> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.deref().cmp(&**other)
}
}
+#[mutants::skip] // hashing involves PRNG and is difficult to test
impl<T: Hash + ?Sized, R: RawRwLock, Key: Keyable> Hash for RwLockWriteGuard<'_, '_, T, Key, R> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
+#[mutants::skip]
impl<T: Debug + ?Sized, Key: Keyable, R: RawRwLock> Debug for RwLockWriteGuard<'_, '_, T, Key, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&**self, f)
diff --git a/src/rwlock/write_lock.rs b/src/rwlock/write_lock.rs
index ff00c06..443fbcd 100644
--- a/src/rwlock/write_lock.rs
+++ b/src/rwlock/write_lock.rs
@@ -25,6 +25,7 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<'_, T, R
// Technically, the exclusive locks can also be shared, but there's currently
// no way to express that. I don't think I want to ever express that.
+#[mutants::skip]
impl<T: ?Sized + Debug, R: RawRwLock> Debug for WriteLock<'_, T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// safety: this is just a try lock, and the value is dropped