diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 064d765368e..cb82e7b6ee2 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -1,6 +1,7 @@ // check-pass -#![feature(rustc_attrs)] +#![feature(rustc_attrs, transparent_unions)] #![allow(unused, improper_ctypes_definitions)] +use std::marker::PhantomData; use std::num::NonZeroI32; use std::ptr::NonNull; @@ -27,7 +28,7 @@ struct ReprC2Int(i32, T); #[repr(C)] struct ReprC2Float(f32, T); #[repr(C)] -struct ReprC4(T, T, T, T); +struct ReprC4(T, Vec, Zst, T); #[repr(C)] struct ReprC4Mixed(T, f32, i32, T); #[repr(C)] @@ -73,6 +74,45 @@ test_abi_compatible!(zst_unit, Zst, ()); test_abi_compatible!(zst_array, Zst, [u8; 0]); test_abi_compatible!(nonzero_int, NonZeroI32, i32); +// `repr(transparent)` compatibility. +#[repr(transparent)] +struct Wrapper1(T); +#[repr(transparent)] +struct Wrapper2((), Zst, T); +#[repr(transparent)] +struct Wrapper3(T, [u8; 0], PhantomData); +#[repr(transparent)] +union WrapperUnion { + nothing: (), + something: T, +} + +macro_rules! test_transparent { + ($name:ident, $t:ty) => { + mod $name { + use super::*; + test_abi_compatible!(wrap1, $t, Wrapper1<$t>); + test_abi_compatible!(wrap2, $t, Wrapper2<$t>); + test_abi_compatible!(wrap3, $t, Wrapper3<$t>); + test_abi_compatible!(wrap4, $t, WrapperUnion<$t>); + } + }; +} + +test_transparent!(simple, i32); +test_transparent!(reference, &'static i32); +test_transparent!(zst, Zst); +test_transparent!(unit, ()); +test_transparent!(pair, (i32, f32)); // mixing in some floats since they often get special treatment +test_transparent!(triple, (i8, i16, f32)); // chosen to fit into 64bit +test_transparent!(tuple, (i32, f32, i64, f64)); +test_transparent!(empty_array, [u32; 0]); +test_transparent!(empty_1zst_array, [u8; 0]); +test_transparent!(small_array, [i32; 2]); // chosen to fit into 64bit +test_transparent!(large_array, [i32; 16]); +test_transparent!(enum_, Option); +test_transparent!(enum_niched, Option<&'static i32>); + // RFC 3391 . macro_rules! test_nonnull { ($name:ident, $t:ty) => { diff --git a/tests/ui/abi/transparent.rs b/tests/ui/abi/transparent.rs deleted file mode 100644 index 90bdc129a4a..00000000000 --- a/tests/ui/abi/transparent.rs +++ /dev/null @@ -1,79 +0,0 @@ -// check-pass -#![feature(rustc_attrs)] -#![allow(unused, improper_ctypes_definitions)] - -use std::marker::PhantomData; - -macro_rules! assert_abi_compatible { - ($name:ident, $t1:ty, $t2:ty) => { - mod $name { - use super::*; - // Test argument and return value, `Rust` and `C` ABIs. - #[rustc_abi(assert_eq)] - type TestRust = (fn($t1) -> $t1, fn($t2) -> $t2); - #[rustc_abi(assert_eq)] - type TestC = (extern "C" fn($t1) -> $t1, extern "C" fn($t2) -> $t2); - } - } -} - -#[derive(Copy, Clone)] -struct Zst; - -// Check that various `transparent` wrappers result in equal ABIs. -#[repr(transparent)] -struct Wrapper1(T); -#[repr(transparent)] -struct Wrapper2((), Zst, T); -#[repr(transparent)] -struct Wrapper3(T, [u8; 0], PhantomData); - -#[repr(C)] -struct ReprCStruct(T, f32, i32, T); -#[repr(C)] -enum ReprCEnum { - Variant1, - Variant2(T), -} -#[repr(C)] -union ReprCUnion { - nothing: (), - something: T, -} - -macro_rules! test_transparent { - ($name:ident, $t:ty) => { - mod $name { - use super::*; - assert_abi_compatible!(wrap1, $t, Wrapper1<$t>); - assert_abi_compatible!(wrap2, $t, Wrapper2<$t>); - assert_abi_compatible!(wrap3, $t, Wrapper3<$t>); - // Also try adding some surrounding `repr(C)` types. - assert_abi_compatible!(repr_c_struct_wrap1, ReprCStruct<$t>, ReprCStruct>); - assert_abi_compatible!(repr_c_enum_wrap1, ReprCEnum<$t>, ReprCEnum>); - assert_abi_compatible!(repr_c_union_wrap1, ReprCUnion<$t>, ReprCUnion>); - assert_abi_compatible!(repr_c_struct_wrap2, ReprCStruct<$t>, ReprCStruct>); - assert_abi_compatible!(repr_c_enum_wrap2, ReprCEnum<$t>, ReprCEnum>); - assert_abi_compatible!(repr_c_union_wrap2, ReprCUnion<$t>, ReprCUnion>); - assert_abi_compatible!(repr_c_struct_wrap3, ReprCStruct<$t>, ReprCStruct>); - assert_abi_compatible!(repr_c_enum_wrap3, ReprCEnum<$t>, ReprCEnum>); - assert_abi_compatible!(repr_c_union_wrap3, ReprCUnion<$t>, ReprCUnion>); - } - } -} - -test_transparent!(simple, i32); -test_transparent!(reference, &'static i32); -test_transparent!(zst, Zst); -test_transparent!(unit, ()); -test_transparent!(pair, (i32, f32)); -test_transparent!(triple, (i8, i16, f32)); // chosen to fit into 64bit -test_transparent!(tuple, (i32, f32, i64, f64)); -test_transparent!(empty_array, [u32; 0]); -test_transparent!(empty_1zst_array, [u8; 0]); -test_transparent!(small_array, [i32; 2]); // chosen to fit into 64bit -test_transparent!(large_array, [i32; 16]); -test_transparent!(enum_, Option); -test_transparent!(enum_niched, Option<&'static i32>); - -fn main() {}