#![crate_type = "lib"] #![feature(transmutability)] #![allow(dead_code, incomplete_features, non_camel_case_types)] mod assert { use std::mem::{Assume, TransmuteFrom}; pub fn is_maybe_transmutable() where Dst: TransmuteFrom {} } fn void() { enum Void {} // This transmutation is vacuously acceptable; since one cannot construct a // `Void`, unsoundness cannot directly arise from transmuting a void into // anything else. assert::is_maybe_transmutable::(); assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted } // Non-ZST uninhabited types are, nonetheless, uninhabited. fn yawning_void_struct() { enum Void {} struct YawningVoid(Void, u128); const _: () = { assert!(std::mem::size_of::() == std::mem::size_of::()); // Just to be sure the above constant actually evaluated: assert!(false); //~ ERROR: evaluation of constant value failed }; // This transmutation is vacuously acceptable; since one cannot construct a // `Void`, unsoundness cannot directly arise from transmuting a void into // anything else. assert::is_maybe_transmutable::(); assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted } // Non-ZST uninhabited types are, nonetheless, uninhabited. fn yawning_void_enum() { enum Void {} enum YawningVoid { A(Void, u128), } const _: () = { assert!(std::mem::size_of::() == std::mem::size_of::()); // Just to be sure the above constant actually evaluated: assert!(false); //~ ERROR: evaluation of constant value failed }; // This transmutation is vacuously acceptable; since one cannot construct a // `Void`, unsoundness cannot directly arise from transmuting a void into // anything else. assert::is_maybe_transmutable::(); assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted } // References to uninhabited types are, logically, uninhabited, but for layout // purposes are not ZSTs, and aren't treated as uninhabited when they appear in // enum variants. fn distant_void() { enum Void {} enum DistantVoid { A(&'static Void) } const _: () = { assert!(std::mem::size_of::() == std::mem::size_of::()); // Just to be sure the above constant actually evaluated: assert!(false); //~ ERROR: evaluation of constant value failed }; assert::is_maybe_transmutable::(); assert::is_maybe_transmutable::(); assert::is_maybe_transmutable::(); //~ ERROR: cannot be safely transmuted }