Auto merge of #60463 - mjbshaw:transparent, r=varkor,rkruppe

Implement RFC 2645 (transparent enums and unions)

Tracking issue: #60405
This commit is contained in:
bors 2019-06-11 11:06:38 +00:00
commit 8e948df707
34 changed files with 730 additions and 208 deletions

View file

@ -1,4 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// ignore-arm
// ignore-mips
@ -7,36 +8,76 @@
// ignore-powerpc64
// See repr-transparent.rs
#![feature(transparent_enums, transparent_unions)]
#![crate_type="lib"]
#[derive(Clone, Copy)]
#[repr(C)]
pub struct Big([u32; 16]);
pub struct BigS([u32; 16]);
#[repr(transparent)]
pub struct BigW(Big);
pub struct TsBigS(BigS);
// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], %Big* [[BIG_ARG_ATTRS:.*]])
#[repr(transparent)]
pub union TuBigS {
field: BigS,
}
#[repr(transparent)]
pub enum TeBigS {
Variant(BigS),
}
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS:.*]])
#[no_mangle]
pub extern fn test_Big(_: Big) -> Big { loop {} }
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], %BigW* [[BIG_ARG_ATTRS]])
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS]])
#[no_mangle]
pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS]])
#[no_mangle]
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS]])
#[no_mangle]
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
#[derive(Clone, Copy)]
#[repr(C)]
pub union BigU {
foo: [u32; 16],
}
#[repr(transparent)]
pub struct BigUw(BigU);
pub struct TsBigU(BigU);
#[repr(transparent)]
pub union TuBigU {
field: BigU,
}
#[repr(transparent)]
pub enum TeBigU {
Variant(BigU),
}
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS:.*]])
#[no_mangle]
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], %BigUw* [[BIGU_ARG_ATTRS]])
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS]])
#[no_mangle]
pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS]])
#[no_mangle]
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS]])
#[no_mangle]
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }

View file

@ -14,36 +14,76 @@
// ignore-x86_64
// See repr-transparent.rs
#![feature(transparent_enums, transparent_unions)]
#![crate_type="lib"]
#[derive(Clone, Copy)]
#[repr(C)]
pub struct Big([u32; 16]);
pub struct BigS([u32; 16]);
#[repr(transparent)]
pub struct BigW(Big);
pub struct TsBigS(BigS);
// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [16 x i32]
#[repr(transparent)]
pub union TuBigS {
field: BigS,
}
#[repr(transparent)]
pub enum TeBigS {
Variant(BigS),
}
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [16 x i32]
#[no_mangle]
pub extern fn test_Big(_: Big) -> Big { loop {} }
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [16 x i32]
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [16 x i32]
#[no_mangle]
pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [16 x i32]
#[no_mangle]
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [16 x i32]
#[no_mangle]
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
#[derive(Clone, Copy)]
#[repr(C)]
pub union BigU {
foo: [u32; 16],
}
#[repr(transparent)]
pub struct BigUw(BigU);
pub struct TsBigU(BigU);
#[repr(transparent)]
pub union TuBigU {
field: BigU,
}
#[repr(transparent)]
pub enum TeBigU {
Variant(BigU),
}
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
#[no_mangle]
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [16 x i32]
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
#[no_mangle]
pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [16 x i32]
#[no_mangle]
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [16 x i32]
#[no_mangle]
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }

View file

@ -3,36 +3,76 @@
// only-mips64
// See repr-transparent.rs
#![feature(transparent_enums, transparent_unions)]
#![crate_type="lib"]
#[derive(Clone, Copy)]
#[repr(C)]
pub struct Big([u32; 16]);
pub struct BigS([u32; 16]);
#[repr(transparent)]
pub struct BigW(Big);
pub struct TsBigS(BigS);
// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [8 x i64]
#[repr(transparent)]
pub union TuBigS {
field: BigS,
}
#[repr(transparent)]
pub enum TeBigS {
Variant(BigS),
}
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [8 x i64]
#[no_mangle]
pub extern fn test_Big(_: Big) -> Big { loop {} }
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [8 x i64]
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [8 x i64]
#[no_mangle]
pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [8 x i64]
#[no_mangle]
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [8 x i64]
#[no_mangle]
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
#[derive(Clone, Copy)]
#[repr(C)]
pub union BigU {
foo: [u32; 16],
}
#[repr(transparent)]
pub struct BigUw(BigU);
pub struct TsBigU(BigU);
#[repr(transparent)]
pub union TuBigU {
field: BigU,
}
#[repr(transparent)]
pub enum TeBigU {
Variant(BigU),
}
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
#[no_mangle]
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [8 x i64]
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
#[no_mangle]
pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [8 x i64]
#[no_mangle]
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [8 x i64]
#[no_mangle]
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }

View file

@ -1,13 +1,16 @@
// compile-flags: -C no-prepopulate-passes
#![crate_type="lib"]
#![feature(repr_simd)]
#![feature(repr_simd, transparent_enums, transparent_unions)]
use std::marker::PhantomData;
#[derive(Copy, Clone)]
pub struct Zst1;
#[derive(Copy, Clone)]
pub struct Zst2(());
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct F32(f32);
@ -112,6 +115,44 @@ pub struct StructWithProjection(<f32 as Mirror>::It);
#[no_mangle]
pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
#[repr(transparent)]
pub enum EnumF32 {
Variant(F32)
}
// CHECK: define float @test_EnumF32(float %arg0)
#[no_mangle]
pub extern fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
#[repr(transparent)]
pub enum EnumF32WithZsts {
Variant(Zst1, F32, Zst2)
}
// CHECK: define float @test_EnumF32WithZsts(float %arg0)
#[no_mangle]
pub extern fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
#[repr(transparent)]
pub union UnionF32 {
field: F32,
}
// CHECK: define float @test_UnionF32(float %arg0)
#[no_mangle]
pub extern fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
#[repr(transparent)]
pub union UnionF32WithZsts {
zst1: Zst1,
field: F32,
zst2: Zst2,
}
// CHECK: define float @test_UnionF32WithZsts(float %arg0)
#[no_mangle]
pub extern fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
// All that remains to be tested are aggregates. They are tested in separate files called repr-
// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR

View file

@ -1,4 +1,6 @@
// run-pass
#![feature(transparent_unions)]
use std::mem::size_of;
use std::num::NonZeroUsize;
use std::ptr::NonNull;
@ -10,6 +12,11 @@ trait Mirror { type Image; }
impl<T> Mirror for T { type Image = T; }
struct ParamTypeStruct<T>(T);
struct AssocTypeStruct<T>(<T as Mirror>::Image);
#[repr(transparent)]
union MaybeUninitUnion<T: Copy> {
_value: T,
_uninit: (),
}
fn main() {
// Functions
@ -29,9 +36,12 @@ fn main() {
// Pointers - Box<T>
assert_eq!(size_of::<Box<isize>>(), size_of::<Option<Box<isize>>>());
// The optimization can't apply to raw pointers
// The optimization can't apply to raw pointers or unions with a ZST field.
assert!(size_of::<Option<*const isize>>() != size_of::<*const isize>());
assert!(Some(0 as *const isize).is_some()); // Can't collapse None to null
assert_ne!(size_of::<fn(isize)>(), size_of::<Option<MaybeUninitUnion<fn(isize)>>>());
assert_ne!(size_of::<&str>(), size_of::<Option<MaybeUninitUnion<&str>>>());
assert_ne!(size_of::<NonNull<isize>>(), size_of::<Option<MaybeUninitUnion<NonNull<isize>>>>());
struct Foo {
_a: Box<isize>

View file

@ -1,6 +1,6 @@
#![feature(repr_simd)]
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum, or union
fn f() {}
#[repr(C)]

View file

@ -1,10 +1,10 @@
error[E0517]: attribute should be applied to struct, enum or union
error[E0517]: attribute should be applied to struct, enum, or union
--> $DIR/attr-usage-repr.rs:3:8
|
LL | #[repr(C)]
| ^
LL | fn f() {}
| --------- not a struct, enum or union
| --------- not a struct, enum, or union
error[E0517]: attribute should be applied to enum
--> $DIR/attr-usage-repr.rs:15:8

View file

@ -1,10 +1,10 @@
error[E0517]: attribute should be applied to struct, enum or union
error[E0517]: attribute should be applied to struct, enum, or union
--> $DIR/E0517.rs:1:8
|
LL | #[repr(C)]
| ^
LL | type Foo = u8;
| -------------- not a struct, enum or union
| -------------- not a struct, enum, or union
error[E0517]: attribute should be applied to struct or union
--> $DIR/E0517.rs:4:8
@ -22,14 +22,14 @@ LL | #[repr(u8)]
LL | struct Foo3 {bar: bool, baz: bool}
| ---------------------------------- not an enum
error[E0517]: attribute should be applied to struct, enum or union
error[E0517]: attribute should be applied to struct, enum, or union
--> $DIR/E0517.rs:10:8
|
LL | #[repr(C)]
| ^
LL | / impl Foo3 {
LL | | }
| |_- not a struct, enum or union
| |_- not a struct, enum, or union
error: aborting due to 4 previous errors

View file

@ -0,0 +1,6 @@
#[repr(transparent)]
enum OkButUnstableEnum { //~ ERROR transparent enums are unstable
Foo((), String, ()),
}
fn main() {}

View file

@ -0,0 +1,14 @@
error[E0658]: transparent enums are unstable
--> $DIR/feature-gate-transparent_enums.rs:2:1
|
LL | / enum OkButUnstableEnum {
LL | | Foo((), String, ()),
LL | | }
| |_^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/60405
= help: add #![feature(transparent_enums)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -0,0 +1,7 @@
#[repr(transparent)]
union OkButUnstableUnion { //~ ERROR transparent unions are unstable
field: u8,
zst: (),
}
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0658]: transparent unions are unstable
--> $DIR/feature-gate-transparent_unions.rs:2:1
|
LL | / union OkButUnstableUnion {
LL | | field: u8,
LL | | zst: (),
LL | | }
| |_^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/60405
= help: add #![feature(transparent_unions)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -9,7 +9,7 @@ note: lint level defined here
|
LL | #![deny(improper_ctypes)]
| ^^^^^^^^^^^^^^^
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/issue-14309.rs:4:1
|
@ -24,7 +24,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
LL | fn bar(x: B);
| ^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/issue-14309.rs:4:1
|
@ -39,7 +39,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
LL | fn qux(x: A2);
| ^^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/issue-14309.rs:4:1
|
@ -54,7 +54,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
LL | fn quux(x: B2);
| ^^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/issue-14309.rs:4:1
|
@ -69,7 +69,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
LL | fn fred(x: D);
| ^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/issue-14309.rs:4:1
|

View file

@ -10,7 +10,7 @@ note: lint level defined here
LL | #![deny(warnings)]
| ^^^^^^^^
= note: #[deny(improper_ctypes)] implied by #[deny(warnings)]
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/issue-16250.rs:3:1
|

View file

@ -1,4 +1,4 @@
fn main() {
#[inline] struct Foo; //~ ERROR attribute should be applied to function or closure
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum or union
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum, or union
}

View file

@ -4,11 +4,11 @@ error[E0518]: attribute should be applied to function or closure
LL | #[inline] struct Foo;
| ^^^^^^^^^ ----------- not a function or closure
error[E0517]: attribute should be applied to struct, enum or union
error[E0517]: attribute should be applied to struct, enum, or union
--> $DIR/issue-31769.rs:3:12
|
LL | #[repr(C)] fn foo() {}
| ^ ----------- not a struct, enum or union
| ^ ----------- not a struct, enum, or union
error: aborting due to 2 previous errors

View file

@ -32,7 +32,7 @@ error[E0517]: attribute should not be applied to a statement
LL | #[repr(nothing)]
| ^^^^^^^^^^^^^^^^
LL | let _x = 0;
| ----------- not a struct, enum or union
| ----------- not a struct, enum, or union
error[E0517]: attribute should not be applied to an expression
--> $DIR/issue-43988.rs:18:5
@ -42,7 +42,7 @@ LL | #[repr(something_not_real)]
LL | / loop {
LL | | ()
LL | | };
| |_____- not defining a struct, enum or union
| |_____- not defining a struct, enum, or union
error[E0517]: attribute should not be applied to a statement
--> $DIR/issue-43988.rs:24:5
@ -50,7 +50,7 @@ error[E0517]: attribute should not be applied to a statement
LL | #[repr]
| ^^^^^^^
LL | let _y = "123";
| --------------- not a struct, enum or union
| --------------- not a struct, enum, or union
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43988.rs:31:5
@ -64,7 +64,7 @@ error[E0517]: attribute should not be applied to an expression
--> $DIR/issue-43988.rs:35:14
|
LL | let _z = #[repr] 1;
| ^^^^^^^ - not defining a struct, enum or union
| ^^^^^^^ - not defining a struct, enum, or union
error: aborting due to 9 previous errors

View file

@ -1,3 +1,4 @@
#![feature(transparent_enums, transparent_unions)]
#![deny(improper_ctypes)]
#![allow(dead_code)]
@ -18,7 +19,17 @@ enum U8 { A, B, C }
enum Isize { A, B, C }
#[repr(transparent)]
struct Transparent<T>(T, std::marker::PhantomData<Z>);
struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
#[repr(transparent)]
enum TransparentEnum<T> {
Variant(T, std::marker::PhantomData<Z>),
}
#[repr(transparent)]
union TransparentUnion<T: Copy> {
field: T,
}
struct Rust<T>(T);
@ -47,7 +58,10 @@ extern {
fn nonzero_i128(x: Option<num::NonZeroI128>);
//~^ ERROR 128-bit integers don't currently have a known stable ABI
fn nonzero_isize(x: Option<num::NonZeroIsize>);
fn repr_transparent(x: Option<Transparent<num::NonZeroU8>>);
fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
//~^ ERROR enum has no representation hint
fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR enum has no representation hint
fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR enum has no representation hint
}

View file

@ -1,74 +1,82 @@
error: `extern` block uses type `U` which is not FFI-safe: enum has no representation hint
--> $DIR/lint-ctypes-enum.rs:27:13
--> $DIR/lint-ctypes-enum.rs:38:13
|
LL | fn uf(x: U);
| ^
|
note: lint level defined here
--> $DIR/lint-ctypes-enum.rs:1:9
--> $DIR/lint-ctypes-enum.rs:2:9
|
LL | #![deny(improper_ctypes)]
| ^^^^^^^^^^^^^^^
= help: consider adding a #[repr(...)] attribute to this enum
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
note: type defined here
--> $DIR/lint-ctypes-enum.rs:7:1
--> $DIR/lint-ctypes-enum.rs:8:1
|
LL | enum U { A }
| ^^^^^^^^^^^^
error: `extern` block uses type `B` which is not FFI-safe: enum has no representation hint
--> $DIR/lint-ctypes-enum.rs:28:13
--> $DIR/lint-ctypes-enum.rs:39:13
|
LL | fn bf(x: B);
| ^
|
= help: consider adding a #[repr(...)] attribute to this enum
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
note: type defined here
--> $DIR/lint-ctypes-enum.rs:8:1
--> $DIR/lint-ctypes-enum.rs:9:1
|
LL | enum B { C, D }
| ^^^^^^^^^^^^^^^
error: `extern` block uses type `T` which is not FFI-safe: enum has no representation hint
--> $DIR/lint-ctypes-enum.rs:29:13
--> $DIR/lint-ctypes-enum.rs:40:13
|
LL | fn tf(x: T);
| ^
|
= help: consider adding a #[repr(...)] attribute to this enum
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
note: type defined here
--> $DIR/lint-ctypes-enum.rs:9:1
--> $DIR/lint-ctypes-enum.rs:10:1
|
LL | enum T { E, F, G }
| ^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
--> $DIR/lint-ctypes-enum.rs:40:23
--> $DIR/lint-ctypes-enum.rs:51:23
|
LL | fn nonzero_u128(x: Option<num::NonZeroU128>);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
--> $DIR/lint-ctypes-enum.rs:47:23
--> $DIR/lint-ctypes-enum.rs:58:23
|
LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
--> $DIR/lint-ctypes-enum.rs:63:28
|
LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
--> $DIR/lint-ctypes-enum.rs:51:20
--> $DIR/lint-ctypes-enum.rs:65:20
|
LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding a #[repr(...)] attribute to this enum
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>` which is not FFI-safe: enum has no representation hint
--> $DIR/lint-ctypes-enum.rs:52:20
--> $DIR/lint-ctypes-enum.rs:66:20
|
LL | fn no_result(x: Result<(), num::NonZeroI32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding a #[repr(...)] attribute to this enum
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
error: aborting due to 7 previous errors
error: aborting due to 8 previous errors

View file

@ -9,7 +9,7 @@ note: lint level defined here
|
LL | #![deny(improper_ctypes)]
| ^^^^^^^^^^^^^^^
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/lint-ctypes.rs:24:1
|
@ -22,7 +22,7 @@ error: `extern` block uses type `Foo` which is not FFI-safe: this struct has uns
LL | pub fn ptr_type2(size: *const Foo);
| ^^^^^^^^^^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
note: type defined here
--> $DIR/lint-ctypes.rs:24:1
|
@ -51,7 +51,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
LL | pub fn box_type(p: Box<u32>);
| ^^^^^^^^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
error: `extern` block uses type `char` which is not FFI-safe: the `char` type has no C equivalent
--> $DIR/lint-ctypes.rs:51:25
@ -142,7 +142,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
LL | pub fn fn_contained(p: RustBadRet);
| ^^^^^^^^^^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
--> $DIR/lint-ctypes.rs:64:32
@ -164,7 +164,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
LL | pub fn transparent_fn(p: TransparentBadFn);
| ^^^^^^^^^^^^^^^^
|
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
error: aborting due to 20 previous errors

View file

@ -1,26 +1,5 @@
// See also repr-transparent.rs
#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
enum Void {} //~| ERROR should be applied to struct
#[repr(transparent)] //~ ERROR should be applied to struct
enum FieldlessEnum {
Foo,
Bar,
}
#[repr(transparent)] //~ ERROR should be applied to struct
enum Enum {
Foo(String),
Bar(u32),
}
#[repr(transparent)] //~ ERROR should be applied to struct
union Foo {
u: u32,
s: i32
}
#[repr(transparent)] //~ ERROR should be applied to struct
fn cant_repr_this() {}

View file

@ -1,69 +1,19 @@
error[E0517]: attribute should be applied to struct
error[E0517]: attribute should be applied to struct, enum, or union
--> $DIR/repr-transparent-other-items.rs:3:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
LL | enum Void {}
| ------------ not a struct
error[E0517]: attribute should be applied to struct
--> $DIR/repr-transparent-other-items.rs:6:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
LL | / enum FieldlessEnum {
LL | | Foo,
LL | | Bar,
LL | | }
| |_- not a struct
error[E0517]: attribute should be applied to struct
--> $DIR/repr-transparent-other-items.rs:12:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
LL | / enum Enum {
LL | | Foo(String),
LL | | Bar(u32),
LL | | }
| |_- not a struct
error[E0517]: attribute should be applied to struct
--> $DIR/repr-transparent-other-items.rs:18:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
LL | / union Foo {
LL | | u: u32,
LL | | s: i32
LL | | }
| |_- not a struct
error[E0517]: attribute should be applied to struct
--> $DIR/repr-transparent-other-items.rs:24:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
LL | fn cant_repr_this() {}
| ---------------------- not a struct
| ---------------------- not a struct, enum, or union
error[E0517]: attribute should be applied to struct
--> $DIR/repr-transparent-other-items.rs:27:8
error[E0517]: attribute should be applied to struct, enum, or union
--> $DIR/repr-transparent-other-items.rs:6:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
LL | static CANT_REPR_THIS: u32 = 0;
| ------------------------------- not a struct
| ------------------------------- not a struct, enum, or union
error[E0084]: unsupported representation for zero-variant enum
--> $DIR/repr-transparent-other-items.rs:3:1
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^^^^^^^^^^
LL | enum Void {}
| ------------ zero-variant enum
error: aborting due to 2 previous errors
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0084, E0517.
For more information about an error, try `rustc --explain E0084`.
For more information about this error, try `rustc --explain E0517`.

View file

@ -3,7 +3,7 @@
// - repr-transparent-other-reprs.rs
// - repr-transparent-other-items.rs
#![feature(repr_align)]
#![feature(repr_align, transparent_enums, transparent_unions)]
use std::marker::PhantomData;
@ -39,4 +39,36 @@ struct ZstAlign32<T>(PhantomData<T>);
#[repr(transparent)]
struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1
#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
enum Void {}
//~^ ERROR transparent enum needs exactly one variant, but has 0
#[repr(transparent)]
enum FieldlessEnum { //~ ERROR transparent enum needs exactly one non-zero-sized field, but has 0
Foo,
}
#[repr(transparent)]
enum TooManyFieldsEnum {
Foo(u32, String),
}
//~^^^ ERROR transparent enum needs exactly one non-zero-sized field, but has 2
#[repr(transparent)]
enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
Foo(String),
Bar,
}
#[repr(transparent)]
union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0
u: (),
}
#[repr(transparent)]
union TooManyFields { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 2
u: u32,
s: i32
}
fn main() {}

View file

@ -3,32 +3,24 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
|
LL | struct NoFields;
| ^^^^^^^^^^^^^^^^
|
= note: non-zero-sized field
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
--> $DIR/repr-transparent.rs:14:1
|
LL | struct ContainsOnlyZst(());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: non-zero-sized field
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
--> $DIR/repr-transparent.rs:17:1
|
LL | struct ContainsOnlyZstArray([bool; 0]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: non-zero-sized field
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
--> $DIR/repr-transparent.rs:20:1
|
LL | struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: non-zero-sized field
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
--> $DIR/repr-transparent.rs:24:1
@ -36,7 +28,7 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
LL | struct MultipleNonZst(u8, u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: non-zero-sized field
note: the following non-zero-sized fields exist on `MultipleNonZst`:
--> $DIR/repr-transparent.rs:24:23
|
LL | struct MultipleNonZst(u8, u8);
@ -48,7 +40,7 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: non-zero-sized field
note: the following non-zero-sized fields exist on `StructWithProjection`:
--> $DIR/repr-transparent.rs:30:33
|
LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
@ -66,7 +58,85 @@ error[E0691]: zero-sized field in transparent struct has alignment larger than 1
LL | struct GenericAlign<T>(ZstAlign32<T>, u32);
| ^^^^^^^^^^^^^
error: aborting due to 8 previous errors
error[E0084]: unsupported representation for zero-variant enum
--> $DIR/repr-transparent.rs:42:1
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^^^^^^^^^^
LL | enum Void {}
| ------------ zero-variant enum
Some errors have detailed explanations: E0690, E0691.
For more information about an error, try `rustc --explain E0690`.
error[E0731]: transparent enum needs exactly one variant, but has 0
--> $DIR/repr-transparent.rs:43:1
|
LL | enum Void {}
| ^^^^^^^^^^^^
error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 0
--> $DIR/repr-transparent.rs:47:1
|
LL | / enum FieldlessEnum {
LL | | Foo,
LL | | }
| |_^
error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 2
--> $DIR/repr-transparent.rs:52:1
|
LL | / enum TooManyFieldsEnum {
LL | | Foo(u32, String),
LL | | }
| |_^
|
note: the following non-zero-sized fields exist on `TooManyFieldsEnum`:
--> $DIR/repr-transparent.rs:53:9
|
LL | Foo(u32, String),
| ^^^ ^^^^^^
error[E0731]: transparent enum needs exactly one variant, but has 2
--> $DIR/repr-transparent.rs:58:1
|
LL | / enum TooManyVariants {
LL | | Foo(String),
LL | | Bar,
LL | | }
| |_^
|
note: the following variants exist on `TooManyVariants`
--> $DIR/repr-transparent.rs:59:5
|
LL | Foo(String),
| ^^^^^^^^^^^
LL | Bar,
| ^^^
error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0
--> $DIR/repr-transparent.rs:64:1
|
LL | / union UnitUnion {
LL | | u: (),
LL | | }
| |_^
error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2
--> $DIR/repr-transparent.rs:69:1
|
LL | / union TooManyFields {
LL | | u: u32,
LL | | s: i32
LL | | }
| |_^
|
note: the following non-zero-sized fields exist on `TooManyFields`:
--> $DIR/repr-transparent.rs:70:5
|
LL | u: u32,
| ^^^^^^
LL | s: i32
| ^^^^^^
error: aborting due to 15 previous errors
Some errors have detailed explanations: E0084, E0690, E0691, E0731.
For more information about an error, try `rustc --explain E0084`.

View file

@ -9,7 +9,7 @@ note: lint level defined here
|
LL | #![deny(improper_ctypes)]
| ^^^^^^^^^^^^^^^
= help: consider adding a #[repr(C)] attribute to this union
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
note: type defined here
--> $DIR/union-repr-c.rs:9:1
|