From 99bb2453a1a20beb2e9c0c4444e972d83ce696ff Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Sat, 29 Apr 2023 10:40:04 -0400 Subject: [PATCH] Make Debug impls useful --- src/lib.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d3acd22..850bd23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,7 +58,7 @@ // 5. Inner::state transitions from QINIT_BIT to READY_BIT during QuickInitGuard's Drop // // If the init future fails (due to returning an error or a panic), then: -// 4. The UnsafeCell remains set to None +// 4. The UnsafeCell remains uninitialized // 5. Inner::state transitions from QINIT_BIT to NEW during QuickInitGuard's Drop // // The fast path does not use Inner::queue at all, and only needs to check it once the cell @@ -98,6 +98,7 @@ use alloc::{boxed::Box, vec, vec::Vec}; use core::{ cell::UnsafeCell, convert::Infallible, + fmt, future::Future, marker::PhantomData, mem::MaybeUninit, @@ -182,7 +183,6 @@ fn with_lock(mutex: &Mutex, f: impl FnOnce(&mut T) -> R) -> R { /// /// # } /// ``` -#[derive(Debug)] pub struct OnceCell { value: UnsafeCell>, inner: Inner, @@ -204,12 +204,24 @@ impl UnwindSafe for OnceCell {} /// The queue pointer starts out as NULL. If contention is detected during the initialization of /// the object, it is initialized to a Box, and will remain pointing at that Queue until the /// state has changed to ready with zero active QueueRefs. -#[derive(Debug)] struct Inner { state: AtomicUsize, queue: AtomicPtr, } +impl fmt::Debug for Inner { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let state = self.state.load(Ordering::Relaxed); + let queue = self.queue.load(Ordering::Relaxed); + fmt.debug_struct("Inner") + .field("ready", &(state & READY_BIT != 0)) + .field("quick_init", &(state & QINIT_BIT != 0)) + .field("refcount", &(state & (QINIT_BIT - 1))) + .field("queue", &queue) + .finish() + } +} + /// Transient state during initialization /// /// Unlike the sync OnceCell, this cannot be a linked list through stack frames, because Futures @@ -715,6 +727,13 @@ impl OnceCell { } } +impl fmt::Debug for OnceCell { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let value = self.get(); + fmt.debug_struct("OnceCell").field("value", &value).field("inner", &self.inner).finish() + } +} + impl Drop for OnceCell { fn drop(&mut self) { let state = *self.inner.state.get_mut(); @@ -738,7 +757,6 @@ impl From for OnceCell { } } -#[derive(Debug)] enum LazyState { Running(F), Ready(T), @@ -765,7 +783,6 @@ enum LazyState { /// assert_eq!(shared.as_ref().get().await.id, 4); /// # } /// ``` -#[derive(Debug)] pub struct Lazy { value: UnsafeCell>, inner: Inner, @@ -929,3 +946,10 @@ impl Lazy { } } } + +impl fmt::Debug for Lazy { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let value = self.try_get(); + fmt.debug_struct("Lazy").field("value", &value).field("inner", &self.inner).finish() + } +}