Last active
August 11, 2021 15:32
-
-
Save toyboot4e/1b56499999ff6c3b6d4f358d3c62af6c to your computer and use it in GitHub Desktop.
Cheat the borrow checker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
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