Created
July 29, 2019 20:34
-
-
Save DutchGhost/54fedb8529fe6ede405eac8b3e5baf04 to your computer and use it in GitHub Desktop.
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
| fn helper<'a, 'b, T: ?Sized>(_: &'a &'b (), v: &'b T) -> &'a T { v } | |
| fn helper_mut<'a, 'b, T: ?Sized>(_: &'a &'b (), v: &'b mut T) -> &'a mut T { v } | |
| /// Use black magic fuckery to turn any `&T` into a `&'static T`. | |
| /// May introduce undefined behavior. | |
| pub fn make_static<'a, T: ?Sized>(input: &'a T) -> &'static T { | |
| let f: fn(_, &'a T) -> &'static T = helper; | |
| f(&&(), input) | |
| } | |
| pub fn make_static_mut<'a, T: ?Sized>(input: &'a mut T) -> &'static mut T { | |
| let f: fn(_, &'a mut T) -> &'static mut T = helper_mut; | |
| f(&&(), input) | |
| } | |
| /// Only types that are not sensitive to being moved can implement this. | |
| /// Box<T> is such a type, because it can give out a 'static handle to the heap it owns, | |
| /// therefore leaking it. Same applies to Vec<T>. | |
| /// Arc<T> wouldn't be, since it could be a clone. | |
| /// (although the destructor never runs, so the atomic refcount will never hit zero, therefore not dropping its internal) | |
| trait Leak: Sized { | |
| type Output: ?Sized; | |
| fn get_ref(&self) -> &Self::Output; | |
| fn leak(self) -> &'static Self::Output { | |
| let reference = self.get_ref(); | |
| let static_ref = make_static(reference); | |
| core::mem::forget(self); | |
| static_ref | |
| } | |
| } | |
| trait LeakMut: Leak { | |
| fn get_mut(&mut self) -> &mut Self::Output; | |
| fn leak_mut(mut self) -> &'static mut Self::Output { | |
| let reference = self.get_mut(); | |
| let static_ref = make_static_mut(reference); | |
| core::mem::forget(self); | |
| static_ref | |
| } | |
| } | |
| impl <T: ?Sized> Leak for Box<T> { | |
| type Output = T; | |
| fn get_ref(&self) -> &T { | |
| &*self | |
| } | |
| } | |
| impl <T: ?Sized> LeakMut for Box<T> { | |
| fn get_mut(&mut self) -> &mut T { | |
| &mut *self | |
| } | |
| } | |
| fn main() { | |
| let b = Box::new(1); | |
| let leak = b.leak(); | |
| println!("{:?}", leak); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment