Created
June 7, 2022 14:38
-
-
Save snightshade/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.
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
// 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