Skip to content

Instantly share code, notes, and snippets.

@DutchGhost
Created July 29, 2019 20:34
Show Gist options
  • Select an option

  • Save DutchGhost/54fedb8529fe6ede405eac8b3e5baf04 to your computer and use it in GitHub Desktop.

Select an option

Save DutchGhost/54fedb8529fe6ede405eac8b3e5baf04 to your computer and use it in GitHub Desktop.
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