Skip to content

Instantly share code, notes, and snippets.

@toyboot4e
Last active August 11, 2021 15:32
Show Gist options
  • Save toyboot4e/1b56499999ff6c3b6d4f358d3c62af6c to your computer and use it in GitHub Desktop.
Save toyboot4e/1b56499999ff6c3b6d4f358d3c62af6c to your computer and use it in GitHub Desktop.
Cheat the borrow checker
/*!
Cheat the borrow checker using raw pointer
*/
pub fn cheat<T>(x: &T) -> Cheat<T> {
unsafe { Cheat::new(x) }
}
/// Lifetime-free mutable reference to type `T`
///
/// # Safety
///
/// Make sure the pointer lives as long as needed.
#[derive(Debug, Clone)]
pub struct Cheat<T> {
ptr: *mut T,
}
impl<T> Clone for Cheat<T> {
fn clone(&self) -> Self {
Self { ptr: self.ptr }
}
}
impl<T> Cheat<T> {
#[inline]
pub fn new(reference: &T) -> Self {
Self {
ptr: reference as *const _ as *mut _,
}
}
pub fn empty() -> Self {
Self {
ptr: std::ptr::null_mut(),
}
}
#[inline]
pub fn as_mut(&self) -> &mut T {
&mut *self.ptr
}
}
impl<T> std::ops::Deref for Cheat<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.ptr }
}
}
impl<T> std::ops::DerefMut for Cheat<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.ptr }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment