use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use cluFullTransmute::transmute_unchecked;
#[test]
fn full_transmute_correct() {
#[derive(Hash, Debug)]
struct A(usize, usize, bool);
static mut CHECK_DROP1: bool = false;
impl Drop for A {
#[inline]
fn drop(&mut self) {
unsafe {
CHECK_DROP1 = true;
}
}
}
#[derive(Hash, Debug)]
struct B(usize, usize, bool);
static mut CHECK_DROP2: bool = false;
impl Drop for B {
fn drop(&mut self) {
unsafe {
CHECK_DROP2 = true;
}
}
}
const ONE_DATA: usize = usize::MAX;
const TWO_DATA: usize = usize::MIN;
const THREE_DATA: bool = true;
let a = A(ONE_DATA, TWO_DATA, THREE_DATA);
let a_hash = {
let mut hasher = DefaultHasher::new();
a.hash(&mut hasher);
hasher.finish()
};
let b: B = unsafe { transmute_unchecked(a) };
let b_hash = {
let mut hasher = DefaultHasher::new();
b.hash(&mut hasher);
hasher.finish()
};
assert_eq!(b.0, ONE_DATA);
assert_eq!(b.1, TWO_DATA);
assert_eq!(b.2, THREE_DATA);
assert_eq!(a_hash, b_hash);
drop(b);
assert!(!unsafe { CHECK_DROP1 });
assert!(unsafe { CHECK_DROP2 });
}