Disallow single-variant enums
Couldn't find documentation supporting that single-variant `#[repr(Rust)]` enums with RHS assigned work as expected with this change. ```rust enum Variants { A = 17, } // Would this be zero sized optimized guaranteed? ```
This commit is contained in:
parent
223d5eb64f
commit
014ddac9c9
@ -1102,22 +1102,24 @@ fn get_nullable_type<'tcx>(
|
||||
/// A type is niche_optimization_candiate iff:
|
||||
/// - Is a zero-sized type with alignment 1 (a “1-ZST”).
|
||||
/// - Has no fields.
|
||||
/// - Does not have the #[non_exhaustive] attribute.
|
||||
/// - Does not have the `#[non_exhaustive]` attribute.
|
||||
fn is_niche_optimization_candidate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
if !tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| layout.is_1zst()) {
|
||||
if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match ty.kind() {
|
||||
ty::Adt(ty_def, _) => {
|
||||
let non_exhaustive = ty_def.is_variant_list_non_exhaustive();
|
||||
let contains_no_fields = ty_def.all_fields().next().is_none();
|
||||
// Should single-variant enums be allowed?
|
||||
let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none())
|
||||
|| (ty_def.is_enum() && ty_def.variants().is_empty());
|
||||
|
||||
!non_exhaustive && contains_no_fields
|
||||
!non_exhaustive && empty
|
||||
}
|
||||
ty::Tuple(tys) => tys.is_empty(),
|
||||
_ => false,
|
||||
|
@ -122,6 +122,7 @@ extern "C" {
|
||||
fn result_phantom_t(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
|
||||
fn result_1zst_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, Z>);
|
||||
fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
|
||||
//~^ ERROR `extern` block uses type
|
||||
fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
||||
//~^ ERROR `extern` block uses type
|
||||
fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
||||
@ -159,6 +160,7 @@ extern "C" {
|
||||
fn result_phantom_e(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
|
||||
fn result_1zst_exhaustive_no_variant_e(x: Result<Z, num::NonZero<u8>>);
|
||||
fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
|
||||
//~^ ERROR `extern` block uses type
|
||||
fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
||||
//~^ ERROR `extern` block uses type
|
||||
fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
||||
|
@ -113,8 +113,17 @@ LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:124:51
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:125:53
|
||||
--> $DIR/lint-ctypes-enum.rs:126:53
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -123,7 +132,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:127:51
|
||||
--> $DIR/lint-ctypes-enum.rs:128:51
|
||||
|
|
||||
LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -132,7 +141,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>,
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:130:49
|
||||
--> $DIR/lint-ctypes-enum.rs:131:49
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -141,7 +150,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Fi
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:132:30
|
||||
--> $DIR/lint-ctypes-enum.rs:133:30
|
||||
|
|
||||
LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -150,7 +159,7 @@ LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:143:33
|
||||
--> $DIR/lint-ctypes-enum.rs:144:33
|
||||
|
|
||||
LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -158,7 +167,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:150:33
|
||||
--> $DIR/lint-ctypes-enum.rs:151:33
|
||||
|
|
||||
LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -166,7 +175,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:155:38
|
||||
--> $DIR/lint-ctypes-enum.rs:156:38
|
||||
|
|
||||
LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -175,7 +184,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:157:30
|
||||
--> $DIR/lint-ctypes-enum.rs:158:30
|
||||
|
|
||||
LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -183,8 +192,17 @@ LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:162:51
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:162:53
|
||||
--> $DIR/lint-ctypes-enum.rs:164:53
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -193,7 +211,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:164:51
|
||||
--> $DIR/lint-ctypes-enum.rs:166:51
|
||||
|
|
||||
LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -202,7 +220,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:167:49
|
||||
--> $DIR/lint-ctypes-enum.rs:169:49
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -211,7 +229,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:169:30
|
||||
--> $DIR/lint-ctypes-enum.rs:171:30
|
||||
|
|
||||
LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -219,5 +237,5 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: aborting due to 23 previous errors
|
||||
error: aborting due to 25 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user