#![warn(clippy::transmute_undefined_repr)] #![allow(clippy::unit_arg, clippy::transmute_ptr_to_ref, clippy::useless_transmute)] use core::any::TypeId; use core::ffi::c_void; use core::mem::{size_of, transmute, MaybeUninit}; use core::ptr::NonNull; fn value() -> T { unimplemented!() } struct Empty; struct Ty(T); struct Ty2(T, U); #[repr(C)] struct Ty2C(T, U); fn main() { unsafe { let _: () = transmute(value::()); let _: Empty = transmute(value::<()>()); let _: Ty = transmute(value::()); let _: Ty = transmute(value::()); // Lint, Ty2 is unordered let _: Ty2C = transmute(value::>()); //~^ ERROR: transmute from `Ty2` which has an undefined layout //~| NOTE: `-D clippy::transmute-undefined-repr` implied by `-D warnings` // Lint, Ty2 is unordered let _: Ty2 = transmute(value::>()); //~^ ERROR: transmute into `Ty2` which has an undefined layout // Ok, Ty2 types are the same let _: Ty2 = transmute(value::>>()); // Ok, Ty2 types are the same let _: Ty> = transmute(value::>()); // Lint, different Ty2 instances let _: Ty2 = transmute(value::>>()); //~^ ERROR: transmute from `Ty>` to `Ty2`, both of which h //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou // Lint, different Ty2 instances let _: Ty> = transmute(value::>()); //~^ ERROR: transmute from `Ty2` to `Ty>`, both of which h //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou let _: Ty<&()> = transmute(value::<&()>()); let _: &() = transmute(value::>()); // Lint, different Ty2 instances let _: &Ty2 = transmute(value::>>()); //~^ ERROR: transmute from `Ty<&Ty2>` to `&Ty2`, both of which //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou // Lint, different Ty2 instances let _: Ty<&Ty2> = transmute(value::<&Ty2>()); //~^ ERROR: transmute from `&Ty2` to `Ty<&Ty2>`, both of which //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou // Ok, pointer to usize conversion let _: Ty = transmute(value::<&Ty2>()); // Ok, pointer to usize conversion let _: &Ty2 = transmute(value::>()); // Ok, transmute to byte array let _: Ty<[u8; 8]> = transmute(value::>()); // Ok, transmute from byte array let _: Ty2 = transmute(value::>()); // issue #8417 // Ok, Ty2 types are the same let _: Ty2C, ()> = transmute(value::>()); // Ok, Ty2 types are the same let _: Ty2 = transmute(value::, ()>>()); // Ok, Ty2 types are the same let _: &'static mut Ty2 = transmute(value::>>()); // Ok, Ty2 types are the same let _: Box> = transmute(value::<&'static mut Ty2>()); // Ok, Ty2 types are the same let _: *mut Ty2 = transmute(value::>>()); // Ok, Ty2 types are the same let _: Box> = transmute(value::<*mut Ty2>()); // Lint, different Ty2 instances let _: &'static mut Ty2 = transmute(value::>>()); //~^ ERROR: transmute from `std::boxed::Box>` to `&mut Ty2 //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou // Lint, different Ty2 instances let _: Box> = transmute(value::<&'static mut Ty2>()); //~^ ERROR: transmute from `&mut Ty2` to `std::boxed::Box> //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou // Ok, type erasure let _: *const () = transmute(value::>>()); // Ok, reverse type erasure let _: Ty<&Ty2> = transmute(value::<*const ()>()); // Ok, type erasure let _: *const c_void = transmute(value::>>()); // Ok, reverse type erasure let _: Ty<&Ty2> = transmute(value::<*const c_void>()); enum Erase {} // Ok, type erasure let _: *const Erase = transmute(value::>>()); // Ok, reverse type erasure let _: Ty<&Ty2> = transmute(value::<*const Erase>()); struct Erase2( [u8; 0], core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, ); // Ok, type erasure let _: *const Erase2 = transmute(value::>>()); // Ok, reverse type erasure let _: Ty<&Ty2> = transmute(value::<*const Erase2>()); // Ok, type erasure let _: *const () = transmute(value::<&&[u8]>()); // Ok, reverse type erasure let _: &&[u8] = transmute(value::<*const ()>()); // Ok, type erasure let _: *mut c_void = transmute(value::<&mut &[u8]>()); // Ok, reverse type erasure let _: &mut &[u8] = transmute(value::<*mut c_void>()); // Ok, transmute to byte array let _: [u8; size_of::<&[u8]>()] = transmute(value::<&[u8]>()); // Ok, transmute from byte array let _: &[u8] = transmute(value::<[u8; size_of::<&[u8]>()]>()); // Ok, transmute to int array let _: [usize; 2] = transmute(value::<&[u8]>()); // Ok, transmute from int array let _: &[u8] = transmute(value::<[usize; 2]>()); // Ok let _: *const [u8] = transmute(value::>()); // Ok let _: Box<[u8]> = transmute(value::<*mut [u8]>()); // Ok let _: Ty2 = transmute(value::<(Ty2,)>()); // Ok let _: (Ty2,) = transmute(value::>()); // Ok let _: Ty2 = transmute(value::<(Ty2, ())>()); // Ok let _: (Ty2, ()) = transmute(value::>()); // Ok let _: Ty2 = transmute(value::<((), Ty2)>()); // Ok let _: ((), Ty2) = transmute(value::>()); // Ok let _: (usize, usize) = transmute(value::<&[u8]>()); // Ok let _: &[u8] = transmute(value::<(usize, usize)>()); trait Trait {} // Ok let _: (isize, isize) = transmute(value::<&dyn Trait>()); let _: &dyn Trait = transmute(value::<(isize, isize)>()); // Ok let _: MaybeUninit> = transmute(value::>()); // Ok let _: Ty2 = transmute(value::>>()); // Ok let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec>()); // Ok let _: *const Ty2 = transmute(value::<*const Ty2C, u32>>()); // Ok let _: *const Ty2C, u32> = transmute(value::<*const Ty2>()); // Ok let _: *const Ty2 = transmute(value::<*const Ty2C<(), Ty2>>()); // Ok let _: *const Ty2C<(), Ty2> = transmute(value::<*const Ty2>()); // Err let _: *const Ty2 = transmute(value::<*const Ty2C>>()); //~^ ERROR: transmute into `*const Ty2` which has an undefined layout //~| NOTE: the contained type `Ty2` has an undefined layout // Err let _: *const Ty2C> = transmute(value::<*const Ty2>()); //~^ ERROR: transmute from `*const Ty2` which has an undefined layout //~| NOTE: the contained type `Ty2` has an undefined layout // Ok let _: NonNull = transmute(value::>()); // Ok let _: NonNull<(String, String)> = transmute(value::>()); } } fn _with_generics() { if TypeId::of::() != TypeId::of::() || TypeId::of::() != TypeId::of::() { return; } unsafe { // Ok let _: &u32 = transmute(value::<&T>()); // Ok let _: &T = transmute(value::<&u32>()); // Ok let _: Vec = transmute(value::>()); // Ok let _: Vec = transmute(value::>()); // Ok let _: Ty<&u32> = transmute(value::<&T>()); // Ok let _: Ty<&T> = transmute(value::<&u32>()); // Ok let _: Vec = transmute(value::>()); // Ok let _: Vec = transmute(value::>()); // Ok let _: &Ty2 = transmute(value::<&Ty2>()); // Ok let _: &Ty2 = transmute(value::<&Ty2>()); // Ok let _: Vec> = transmute(value::>>()); // Ok let _: Vec> = transmute(value::>>()); // Err let _: Vec> = transmute(value::>>()); //~^ ERROR: transmute from `std::vec::Vec>` to `std::vec::Vec> = transmute(value::>>()); //~^ ERROR: transmute from `std::vec::Vec>` to `std::vec::Vec>()); // Ok let _: Box = transmute(value::<*const u32>()); } }