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:
|
/// A type is niche_optimization_candiate iff:
|
||||||
/// - Is a zero-sized type with alignment 1 (a “1-ZST”).
|
/// - Is a zero-sized type with alignment 1 (a “1-ZST”).
|
||||||
/// - Has no fields.
|
/// - Has no fields.
|
||||||
/// - Does not have the #[non_exhaustive] attribute.
|
/// - Does not have the `#[non_exhaustive]` attribute.
|
||||||
fn is_niche_optimization_candidate<'tcx>(
|
fn is_niche_optimization_candidate<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> bool {
|
) -> 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Adt(ty_def, _) => {
|
ty::Adt(ty_def, _) => {
|
||||||
let non_exhaustive = ty_def.is_variant_list_non_exhaustive();
|
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(),
|
ty::Tuple(tys) => tys.is_empty(),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -122,6 +122,7 @@ extern "C" {
|
|||||||
fn result_phantom_t(x: Result<num::NonZero<u8>, std::marker::PhantomData<()>>);
|
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_no_variant_t(x: Result<num::NonZero<u8>, Z>);
|
||||||
fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
|
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>);
|
fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
||||||
//~^ ERROR `extern` block uses type
|
//~^ ERROR `extern` block uses type
|
||||||
fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
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_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_no_variant_e(x: Result<Z, num::NonZero<u8>>);
|
||||||
fn result_1zst_exhaustive_single_variant_e(x: Result<U, 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>>);
|
fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
||||||
//~^ ERROR `extern` block uses type
|
//~^ ERROR `extern` block uses type
|
||||||
fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
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
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= 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
|
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>);
|
LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
|
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>);
|
LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
|
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>);
|
LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
|
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>>, ()>);
|
LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
@ -150,7 +159,7 @@ LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
|||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
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>>);
|
LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
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>>);
|
LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= 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
|
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>>>);
|
LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
@ -175,7 +184,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
|
|||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
|
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>>>);
|
LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= 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
|
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>>);
|
LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
|
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>>);
|
LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
|
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>>);
|
LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
|
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>>>);
|
LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= 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