From ded44ec228b3eaceed820585882414831eb196c0 Mon Sep 17 00:00:00 2001 From: Mica White Date: Fri, 8 Mar 2024 15:47:40 -0500 Subject: Extra lifetime shenanigans --- src/guard.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'src/guard.rs') diff --git a/src/guard.rs b/src/guard.rs index 30e7d4a..12021e2 100644 --- a/src/guard.rs +++ b/src/guard.rs @@ -1,21 +1,26 @@ -use std::ops::{Deref, DerefMut}; +use std::{ + marker::PhantomData, + ops::{Deref, DerefMut}, +}; use crate::{key::Keyable, lockable::Lockable}; /// A guard for a generic [`Lockable`] type. -pub struct LockGuard<'a, L: Lockable<'a>, Key: Keyable> { +pub struct LockGuard<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable + 'key> { guard: L::Output, - _key: Key, + key: Key, + _phantom: PhantomData<&'key ()>, } -impl<'a, L: Lockable<'a>, Key: Keyable> LockGuard<'a, L, Key> { +impl<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable> LockGuard<'a, 'key, L, Key> { /// Locks the lockable type and returns a guard that can be used to access /// the underlying data. pub fn lock(lock: &'a L, key: Key) -> Self { Self { // safety: we have the thread's key guard: unsafe { lock.lock() }, - _key: key, + key, + _phantom: PhantomData, } } @@ -24,18 +29,23 @@ impl<'a, L: Lockable<'a>, Key: Keyable> LockGuard<'a, L, Key> { /// is given back as an error. pub fn try_lock(lock: &'a L, key: Key) -> Option { // safety: we have the thread's key - unsafe { lock.try_lock() }.map(|guard| Self { guard, _key: key }) + unsafe { lock.try_lock() }.map(|guard| Self { + guard, + key, + _phantom: PhantomData, + }) } /// Unlocks the underlying lockable data type, returning the key that's /// associated with it. #[allow(clippy::missing_const_for_fn)] - pub fn unlock(self) { - L::unlock(self.guard); + pub fn unlock(guard: Self) -> Key { + L::unlock(guard.guard); + guard.key } } -impl<'a, L: Lockable<'a>, Key: Keyable> Deref for LockGuard<'a, L, Key> { +impl<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable> Deref for LockGuard<'a, 'key, L, Key> { type Target = L::Output; fn deref(&self) -> &Self::Target { @@ -43,7 +53,7 @@ impl<'a, L: Lockable<'a>, Key: Keyable> Deref for LockGuard<'a, L, Key> { } } -impl<'a, L: Lockable<'a>, Key: Keyable> DerefMut for LockGuard<'a, L, Key> { +impl<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable> DerefMut for LockGuard<'a, 'key, L, Key> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.guard } -- cgit v1.2.3