216df4a8e6
The source referent absolutely must be smaller than the destination referent of a ref-to-ref transmute; the excess bytes referenced cannot arise from thin air, even if those bytes are uninitialized.
50 lines
1.0 KiB
Rust
50 lines
1.0 KiB
Rust
//@ check-fail
|
|
|
|
//! Reject extensions behind references.
|
|
|
|
#![crate_type = "lib"]
|
|
#![feature(transmutability)]
|
|
|
|
mod assert {
|
|
use std::mem::{Assume, BikeshedIntrinsicFrom};
|
|
|
|
pub fn is_transmutable<Src, Dst>()
|
|
where
|
|
Dst: BikeshedIntrinsicFrom<
|
|
Src,
|
|
{
|
|
Assume {
|
|
alignment: true,
|
|
lifetimes: true,
|
|
safety: true,
|
|
validity: true,
|
|
}
|
|
},
|
|
>,
|
|
{
|
|
}
|
|
}
|
|
|
|
#[repr(C, packed)]
|
|
struct Packed<T>(T);
|
|
|
|
fn reject_extension() {
|
|
#[repr(C, align(2))]
|
|
struct Two(u8);
|
|
|
|
#[repr(C, align(4))]
|
|
struct Four(u8);
|
|
|
|
// These two types differ in the number of trailing padding bytes they have.
|
|
type Src = Packed<Two>;
|
|
type Dst = Packed<Four>;
|
|
|
|
const _: () = {
|
|
use std::mem::size_of;
|
|
assert!(size_of::<Src>() == 2);
|
|
assert!(size_of::<Dst>() == 4);
|
|
};
|
|
|
|
assert::is_transmutable::<&Src, &Dst>(); //~ ERROR cannot be safely transmuted
|
|
}
|