use std::cell::Ref;
use std::cell::RefCell;
use std::ptr;
#[inline]
pub(crate) unsafe fn unleak_borrow<T: ?Sized>(ref_cell: &RefCell<T>) {
let r = ref_cell.borrow();
unsafe {
drop::<Ref<T>>(ptr::read(&r as *const Ref<T>));
drop::<Ref<T>>(r);
}
}
#[cfg(test)]
mod tests {
use std::cell::RefCell;
use std::mem;
#[test]
fn test_unleak_borrow() {
let ref_cell = RefCell::new(1);
assert!(ref_cell.try_borrow_mut().is_ok());
mem::forget(ref_cell.borrow());
assert!(
ref_cell.try_borrow_mut().is_err(),
"RefCell is borrowed, so we cannot borrow it mutably"
);
unsafe { super::unleak_borrow(&ref_cell) };
assert!(
ref_cell.try_borrow_mut().is_ok(),
"Borrow is unleaked, so we can borrow it mutably"
);
mem::forget(ref_cell.borrow());
mem::forget(ref_cell.borrow());
assert!(
ref_cell.try_borrow_mut().is_err(),
"RefCell is borrowed, so we cannot borrow it mutably"
);
unsafe { super::unleak_borrow(&ref_cell) };
assert!(
ref_cell.try_borrow_mut().is_err(),
"RefCell is still borrowed"
);
unsafe { super::unleak_borrow(&ref_cell) };
assert!(ref_cell.try_borrow_mut().is_ok());
}
}