Skip to content

Instantly share code, notes, and snippets.

@lostkagamine
Created June 7, 2022 14:38
Show Gist options
  • Save lostkagamine/3c2e6ece2c7d9ef27d117de48519a03f to your computer and use it in GitHub Desktop.
Save lostkagamine/3c2e6ece2c7d9ef27d117de48519a03f to your computer and use it in GitHub Desktop.
(Rust) An extremely naughty implementation of transmute as an extension method. Never do this, literally ever.
// foof: toolchain nightly
#![feature(downcast_unchecked)]
use std::any::Any;
trait GoTo {
fn to<T>(&self) -> T;
}
/// A very, very stupid transmute as an extension method
///
/// # Usage
/// Don't
///
/// # Safety
/// Absolutely not
///
/// # Notes
/// Please `std::mem::forget` the original otherwise rustc will double-free it
impl GoTo for dyn Any {
fn to<T2>(&self) -> T2 {
unsafe {
let dc: &Self = self.downcast_ref_unchecked::<&Self>();
let ptr_a = dc as *const Self;
let ptrptr_a = &ptr_a as *const *const Self;
let ptrptr_b = ptrptr_a as *const *const T2;
let ptr_b = *ptrptr_b as *const T2;
let a = ptr_b.read_unaligned();
a
}
}
}
#[derive(Debug)]
struct One(String);
#[derive(Debug)]
struct Two(String);
fn main() {
let a: Box<dyn Any> = Box::new(One("hi".into()));
let b = a.to::<Two>();
std::mem::forget(a);
println!("{:?}", b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment