I was messing around with the Any
trait and seeing what was possible. I had a theory that if I made a wrapper around a type and made the wrapper #[repr(transparent)]
so they (from what I understand) have the same representation in memory, I would be able to create an instance of the wrapped type, and downcast to the wrapper type and it would be fine. Below is the code:
use std::any::Any;
use std::mem;
// A wrapper around a Vec<u8> that is transparent.
#[repr(transparent)]
#[derive(Debug)]
struct MyString {
string: Vec<u8>
}
fn main() {
// Sanity check to make sure the types do have the same repr in memory. (I know this doesn't prove they do but will prove it if they don't)
println!("String size: {}, alignment: {}", mem::size_of::<MyString>(), mem::align_of::<MyString>());
println!("Vec size: {}, alignment: {}", mem::size_of::<Vec<u8>>(), mem::align_of::<Vec<u8>>());
// Create a Vec<u8>
let vec: Vec<u8> = "JumboTrout".as_bytes().to_owned();
// Convert to an Any trait object.
let vec: Box<dyn Any> = Box::new(vec);
// Pass vec to function that will downcast.
print_any(vec);
}
fn print_any(any: Box<dyn Any>) {
// Downcast the Vec<u8> to MyString
let string = any.downcast::<MyString>().unwrap(); // panic!
println!("{string}");
}
#[repr(transparent)]
#[derive(Debug)]
struct MyString {
string: Vec<u8>
}
impl std::fmt::Display for MyString {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", String::from_utf8(self.string.clone()).unwrap())
}
}
This code panics when I try to unwrap after the attempt to downcast. This result was surprising because (I thought) the two types were identical in memory. If they are identical, shouldn't they effectively be the same type at runtime? It appears my understanding of the Rust memory model still needs work. What is going on here?
FWIW: I tried #[repr(C)]
when this didn't work to see if that would change anything, and it crashed as well.
PS: I am just messing around. I like messing around and seeing what kind of "illegal" stuff I can do using memory manipulation. I am intentionally doing something very non-idiomatic.