Skip to content

Instantly share code, notes, and snippets.

@rksm
Created June 17, 2025 14:51
Show Gist options
  • Save rksm/7fdb88d242f7a979c133cc1d44cd105c to your computer and use it in GitHub Desktop.
Save rksm/7fdb88d242f7a979c133cc1d44cd105c to your computer and use it in GitHub Desktop.
TracingRefCell to debug borrow_mut errors.
use std::cell::{
Ref,
RefCell,
RefMut,
};
#[derive(Clone)]
pub struct TracingRefCell<T> {
value: RefCell<T>,
}
impl<T> Default for TracingRefCell<T>
where
T: Default,
{
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> TracingRefCell<T> {
pub fn new(value: T) -> Self {
Self {
value: RefCell::new(value),
}
}
pub fn borrow(&self) -> TracingRef<T> {
TracingRef::new(self.value.borrow())
}
pub fn borrow_mut(&self) -> TracingRefMut<T> {
TracingRefMut::new(self.value.borrow_mut())
}
}
pub struct TracingRef<'a, T: 'a> {
inner_ref: Ref<'a, T>,
}
impl<'a, T> TracingRef<'a, T> {
pub fn new(inner_ref: Ref<'a, T>) -> Self {
info!("========> Ref borrowed");
TracingRef { inner_ref }
}
}
impl<T> Drop for TracingRef<'_, T> {
fn drop(&mut self) {
info!("========> Ref released");
}
}
impl<T> std::ops::Deref for TracingRef<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner_ref
}
}
pub struct TracingRefMut<'a, T: 'a> {
inner_ref: RefMut<'a, T>,
}
impl<'a, T> TracingRefMut<'a, T> {
pub fn new(inner_ref: RefMut<'a, T>) -> Self {
info!("========> RefMut borrowed");
TracingRefMut { inner_ref }
}
}
impl<T> Drop for TracingRefMut<'_, T> {
fn drop(&mut self) {
info!("========> RefMut released");
}
}
impl<T> std::ops::Deref for TracingRefMut<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner_ref
}
}
impl<T> std::ops::DerefMut for TracingRefMut<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner_ref
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment