diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 0c5fe6e8d8b76..534458046945c 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -353,6 +353,9 @@ declare_features! ( (accepted, repr_packed, "1.33.0", Some(33158)), /// Allows `#[repr(transparent)]` attribute on newtype structs. (accepted, repr_transparent, "1.28.0", Some(43036)), + /// Allows enums like Result to be used across FFI, if T's niche value can + /// be used to describe E or vice-versa. + (accepted, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)), /// Allows return-position `impl Trait` in traits. (accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611)), /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1067156958dc1..fc3696c402265 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -580,9 +580,6 @@ declare_features! ( (incomplete, repr128, "1.16.0", Some(56071)), /// Allows `repr(simd)` and importing the various simd intrinsics. (unstable, repr_simd, "1.4.0", Some(27731)), - /// Allows enums like Result to be used across FFI, if T's niche value can - /// be used to describe E or vise-versa. - (unstable, result_ffi_guarantees, "1.80.0", Some(110503)), /// Allows bounding the return type of AFIT/RPITIT. (unstable, return_type_notation, "1.70.0", Some(109417)), /// Allows `extern "rust-cold"`. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index e9c61a41d6d60..60ff925b40e0d 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -730,7 +730,6 @@ fn is_niche_optimization_candidate<'tcx>( /// can, return the type that `ty` can be safely converted to, otherwise return `None`. /// Currently restricted to function pointers, boxes, references, `core::num::NonZero`, /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes. -/// FIXME: This duplicates code in codegen. pub(crate) fn repr_nullable_ptr<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -743,10 +742,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>( [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { ([], [field]) | ([field], []) => field.ty(tcx, args), ([field1], [field2]) => { - if !tcx.features().result_ffi_guarantees { - return None; - } - let ty1 = field1.ty(tcx, args); let ty2 = field2.ty(tcx, args); diff --git a/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md b/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md deleted file mode 100644 index dc9c196524ed4..0000000000000 --- a/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md +++ /dev/null @@ -1,14 +0,0 @@ -# `result_ffi_guarantees` - -The tracking issue for this feature is: [#110503] - -[#110503]: https://github.com/rust-lang/rust/issues/110503 - ------------------------- - -This feature adds the possibility of using `Result` in FFI if T's niche -value can be used to describe E or vise-versa. - -See [RFC 3391] for more information. - -[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md diff --git a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs deleted file mode 100644 index dda317aecc3c3..0000000000000 --- a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![allow(dead_code)] -#![deny(improper_ctypes)] -#![feature(ptr_internals)] - -use std::num; - -enum Z {} - -#[repr(transparent)] -struct TransparentStruct(T, std::marker::PhantomData); - -#[repr(transparent)] -enum TransparentEnum { - Variant(T, std::marker::PhantomData), -} - -struct NoField; - -extern "C" { - fn result_ref_t(x: Result<&'static u8, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_fn_t(x: Result); - //~^ ERROR `extern` block uses type `Result - fn result_nonnull_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_unique_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u8_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u16_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u32_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u64_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_usize_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i8_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i16_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i32_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i64_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_isize_t(x: Result, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_transparent_struct_t(x: Result>, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_transparent_enum_t(x: Result>, ()>); - //~^ ERROR `extern` block uses type `Result - fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); - //~^ ERROR `extern` block uses type `Result - fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); - //~^ ERROR `extern` block uses type `Result - fn result_1zst_exhaustive_no_field_t(x: Result, NoField>); - //~^ ERROR `extern` block uses type `Result - - fn result_ref_e(x: Result<(), &'static u8>); - //~^ ERROR `extern` block uses type `Result - fn result_fn_e(x: Result<(), extern "C" fn()>); - //~^ ERROR `extern` block uses type `Result - fn result_nonnull_e(x: Result<(), std::ptr::NonNull>); - //~^ ERROR `extern` block uses type `Result - fn result_unique_e(x: Result<(), std::ptr::Unique>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u8_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u16_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u32_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_u64_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_usize_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i8_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i16_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i32_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_i64_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_nonzero_isize_e(x: Result<(), num::NonZero>); - //~^ ERROR `extern` block uses type `Result - fn result_transparent_struct_e(x: Result<(), TransparentStruct>>); - //~^ ERROR `extern` block uses type `Result - fn result_transparent_enum_e(x: Result<(), TransparentEnum>>); - //~^ ERROR `extern` block uses type `Result - fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); - //~^ ERROR `extern` block uses type `Result - fn result_1zst_exhaustive_no_variant_e(x: Result>); - //~^ ERROR `extern` block uses type `Result - fn result_1zst_exhaustive_no_field_e(x: Result>); - //~^ ERROR `extern` block uses type `Result -} - -pub fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr deleted file mode 100644 index 94416eb99c878..0000000000000 --- a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr +++ /dev/null @@ -1,349 +0,0 @@ -error: `extern` block uses type `Result<&u8, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:20:24 - | -LL | fn result_ref_t(x: Result<&'static 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 -note: the lint level is defined here - --> $DIR/feature-gate-result_ffi_guarantees.rs:2:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ - -error: `extern` block uses type `Result`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:22:23 - | -LL | fn result_fn_t(x: Result); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:24:28 - | -LL | fn result_nonnull_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:26:27 - | -LL | fn result_unique_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:28:31 - | -LL | fn result_nonzero_u8_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:30:32 - | -LL | fn result_nonzero_u16_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:32:32 - | -LL | fn result_nonzero_u32_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:34:32 - | -LL | fn result_nonzero_u64_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:36:34 - | -LL | fn result_nonzero_usize_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:38:31 - | -LL | fn result_nonzero_i8_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:40:32 - | -LL | fn result_nonzero_i16_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:42:32 - | -LL | fn result_nonzero_i32_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:44:32 - | -LL | fn result_nonzero_i64_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:46:34 - | -LL | fn result_nonzero_isize_t(x: Result, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:48:39 - | -LL | fn result_transparent_struct_t(x: Result>, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>, ()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:50:37 - | -LL | fn result_transparent_enum_t(x: Result>, ()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, PhantomData<()>>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:52:28 - | -LL | fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, Z>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:54:47 - | -LL | fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, NoField>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:56:45 - | -LL | fn result_1zst_exhaustive_no_field_t(x: Result, NoField>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<(), &u8>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:59:24 - | -LL | fn result_ref_e(x: Result<(), &'static 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<(), extern "C" fn()>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:61:23 - | -LL | fn result_fn_e(x: Result<(), extern "C" fn()>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<(), NonNull>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:63:28 - | -LL | fn result_nonnull_e(x: Result<(), std::ptr::NonNull>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<(), Unique>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:65:27 - | -LL | fn result_unique_e(x: Result<(), std::ptr::Unique>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:67:31 - | -LL | fn result_nonzero_u8_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:69:32 - | -LL | fn result_nonzero_u16_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:71:32 - | -LL | fn result_nonzero_u32_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:73:32 - | -LL | fn result_nonzero_u64_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:75:34 - | -LL | fn result_nonzero_usize_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:77:31 - | -LL | fn result_nonzero_i8_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:79:32 - | -LL | fn result_nonzero_i16_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:81:32 - | -LL | fn result_nonzero_i32_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:83:32 - | -LL | fn result_nonzero_i64_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:85:34 - | -LL | fn result_nonzero_isize_e(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<(), TransparentStruct>>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:87:39 - | -LL | fn result_transparent_struct_e(x: Result<(), TransparentStruct>>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<(), TransparentEnum>>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:89:37 - | -LL | fn result_transparent_enum_e(x: Result<(), TransparentEnum>>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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, PhantomData<()>>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:91:28 - | -LL | fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:93:47 - | -LL | fn result_1zst_exhaustive_no_variant_e(x: Result>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>`, which is not FFI-safe - --> $DIR/feature-gate-result_ffi_guarantees.rs:95:45 - | -LL | fn result_1zst_exhaustive_no_field_e(x: Result>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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: aborting due to 38 previous errors - diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index cb8e9e8067513..19af1de95760b 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -2,7 +2,6 @@ #![deny(improper_ctypes)] #![feature(ptr_internals)] #![feature(transparent_unions)] -#![feature(result_ffi_guarantees)] use std::num; diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index bba5b09b69cc9..8e92e7e694627 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `U`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:69:14 + --> $DIR/lint-ctypes-enum.rs:68:14 | LL | fn uf(x: U); | ^ not FFI-safe @@ -7,7 +7,7 @@ LL | fn uf(x: U); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:10:1 + --> $DIR/lint-ctypes-enum.rs:9:1 | LL | enum U { | ^^^^^^ @@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ error: `extern` block uses type `B`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:70:14 + --> $DIR/lint-ctypes-enum.rs:69:14 | LL | fn bf(x: B); | ^ not FFI-safe @@ -26,13 +26,13 @@ LL | fn bf(x: B); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:13:1 + --> $DIR/lint-ctypes-enum.rs:12:1 | LL | enum B { | ^^^^^^ error: `extern` block uses type `T`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:71:14 + --> $DIR/lint-ctypes-enum.rs:70:14 | LL | fn tf(x: T); | ^ not FFI-safe @@ -40,13 +40,13 @@ LL | fn tf(x: T); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:17:1 + --> $DIR/lint-ctypes-enum.rs:16:1 | LL | enum T { | ^^^^^^ error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:83:31 + --> $DIR/lint-ctypes-enum.rs:82:31 | LL | fn option_nonzero_u128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -54,7 +54,7 @@ LL | fn option_nonzero_u128(x: Option>); = 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:90:31 + --> $DIR/lint-ctypes-enum.rs:89:31 | LL | fn option_nonzero_i128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -62,7 +62,7 @@ LL | fn option_nonzero_i128(x: Option>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:95:36 + --> $DIR/lint-ctypes-enum.rs:94:36 | LL | fn option_transparent_union(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -71,7 +71,7 @@ LL | fn option_transparent_union(x: Option = note: enum has no representation hint error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:97:28 + --> $DIR/lint-ctypes-enum.rs:96:28 | LL | fn option_repr_rust(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -80,7 +80,7 @@ LL | fn option_repr_rust(x: Option>>); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:107:33 + --> $DIR/lint-ctypes-enum.rs:106:33 | LL | fn result_nonzero_u128_t(x: Result, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -88,7 +88,7 @@ LL | fn result_nonzero_u128_t(x: Result, ()>); = 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:114:33 + --> $DIR/lint-ctypes-enum.rs:113:33 | LL | fn result_nonzero_i128_t(x: Result, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -96,7 +96,7 @@ LL | fn result_nonzero_i128_t(x: Result, ()>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:119:38 + --> $DIR/lint-ctypes-enum.rs:118:38 | LL | fn result_transparent_union_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -105,7 +105,7 @@ LL | fn result_transparent_union_t(x: Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:121:30 + --> $DIR/lint-ctypes-enum.rs:120:30 | LL | fn result_repr_rust_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -114,7 +114,7 @@ LL | fn result_repr_rust_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `Result, U>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:125:51 + --> $DIR/lint-ctypes-enum.rs:124:51 | LL | fn result_1zst_exhaustive_single_variant_t(x: Result, U>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -123,7 +123,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, B>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:127:53 + --> $DIR/lint-ctypes-enum.rs:126:53 | LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -132,7 +132,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result = note: enum has no representation hint error: `extern` block uses type `Result, NonExhaustive>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:129:51 + --> $DIR/lint-ctypes-enum.rs:128:51 | LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -141,7 +141,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, Field>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:132:49 + --> $DIR/lint-ctypes-enum.rs:131:49 | LL | fn result_1zst_exhaustive_single_field_t(x: Result, Field>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -150,7 +150,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result, Fi = note: enum has no representation hint error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:134:30 + --> $DIR/lint-ctypes-enum.rs:133:30 | LL | fn result_cascading_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -159,7 +159,7 @@ LL | fn result_cascading_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:145:33 + --> $DIR/lint-ctypes-enum.rs:144:33 | LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -167,7 +167,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); = 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:152:33 + --> $DIR/lint-ctypes-enum.rs:151:33 | LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -175,7 +175,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:157:38 + --> $DIR/lint-ctypes-enum.rs:156:38 | LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -184,7 +184,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:159:30 + --> $DIR/lint-ctypes-enum.rs:158:30 | LL | fn result_repr_rust_e(x: Result<(), Rust>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -193,7 +193,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust>>); = note: enum has no representation hint error: `extern` block uses type `Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:163:51 + --> $DIR/lint-ctypes-enum.rs:162:51 | LL | fn result_1zst_exhaustive_single_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -202,7 +202,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:165:53 + --> $DIR/lint-ctypes-enum.rs:164:53 | LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -211,7 +211,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:167:51 + --> $DIR/lint-ctypes-enum.rs:166:51 | LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -220,7 +220,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:170:49 + --> $DIR/lint-ctypes-enum.rs:169:49 | LL | fn result_1zst_exhaustive_single_field_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -229,7 +229,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:172:30 + --> $DIR/lint-ctypes-enum.rs:171:30 | LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -238,7 +238,7 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); = note: enum has no representation hint error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:174:27 + --> $DIR/lint-ctypes-enum.rs:173:27 | LL | fn result_unit_t_e(x: Result<(), ()>); | ^^^^^^^^^^^^^^ not FFI-safe diff --git a/tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs b/tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs new file mode 100644 index 0000000000000..9b8092526b950 --- /dev/null +++ b/tests/ui/rfcs/rfc-3391-result-ffi-guarantees.rs @@ -0,0 +1,133 @@ +//@ build-pass +/*! + +The guarantees in RFC 3391 were strengthened as a result of the 2024 Oct 09 T-lang meeting[^1] +following the precedent of T-lang's guaranteeing[^2] ABI compatibility for "Option-like" enums[^2]. +We now guarantee ABI compatibility for enums that conform to these rules described by scottmcm: + +* The enum `E` has exactly two variants. +* One variant has exactly one field, of type `T`. +* `T` is a `rustc_nonnull_optimization_guaranteed` type. +* All fields of the other variant are 1-ZSTs. + +Where "all" fields includes "there aren't any fields, so they're vacuously all 1-ZSTs". + +Note: "1-ZST" means a type of size 0 and alignment 1. + +The reason alignment of the zero-sized type matters is it can affect the alignment of the enum, +which also will affect its size if the enum has a non-zero size. + +[^1]: +[^2]: + +*/ + +#![allow(dead_code)] +#![deny(improper_ctypes)] +#![feature(ptr_internals)] + +use std::num; + +enum Z {} + +#[repr(transparent)] +struct TransparentStruct(T, std::marker::PhantomData); + +#[repr(transparent)] +enum TransparentEnum { + Variant(T, std::marker::PhantomData), +} + +struct NoField; + +extern "C" { + fn result_ref_t(x: Result<&'static u8, ()>); + fn result_fn_t(x: Result); + fn result_nonnull_t(x: Result, ()>); + fn result_unique_t(x: Result, ()>); + fn result_nonzero_u8_t(x: Result, ()>); + fn result_nonzero_u16_t(x: Result, ()>); + fn result_nonzero_u32_t(x: Result, ()>); + fn result_nonzero_u64_t(x: Result, ()>); + fn result_nonzero_usize_t(x: Result, ()>); + fn result_nonzero_i8_t(x: Result, ()>); + fn result_nonzero_i16_t(x: Result, ()>); + fn result_nonzero_i32_t(x: Result, ()>); + fn result_nonzero_i64_t(x: Result, ()>); + fn result_nonzero_isize_t(x: Result, ()>); + fn result_transparent_struct_t(x: Result>, ()>); + fn result_transparent_enum_t(x: Result>, ()>); + fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); + fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); + fn result_1zst_exhaustive_no_field_t(x: Result, NoField>); + + fn result_ref_e(x: Result<(), &'static u8>); + fn result_fn_e(x: Result<(), extern "C" fn()>); + fn result_nonnull_e(x: Result<(), std::ptr::NonNull>); + fn result_unique_e(x: Result<(), std::ptr::Unique>); + fn result_nonzero_u8_e(x: Result<(), num::NonZero>); + fn result_nonzero_u16_e(x: Result<(), num::NonZero>); + fn result_nonzero_u32_e(x: Result<(), num::NonZero>); + fn result_nonzero_u64_e(x: Result<(), num::NonZero>); + fn result_nonzero_usize_e(x: Result<(), num::NonZero>); + fn result_nonzero_i8_e(x: Result<(), num::NonZero>); + fn result_nonzero_i16_e(x: Result<(), num::NonZero>); + fn result_nonzero_i32_e(x: Result<(), num::NonZero>); + fn result_nonzero_i64_e(x: Result<(), num::NonZero>); + fn result_nonzero_isize_e(x: Result<(), num::NonZero>); + fn result_transparent_struct_e(x: Result<(), TransparentStruct>>); + fn result_transparent_enum_e(x: Result<(), TransparentEnum>>); + fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); + fn result_1zst_exhaustive_no_variant_e(x: Result>); + fn result_1zst_exhaustive_no_field_e(x: Result>); +} + +// Custom "Result-like" enum for testing custom "Option-like" types are also accepted +enum Either { + Left(L), + Right(R), +} + +extern "C" { + fn either_ref_t(x: Either<&'static u8, ()>); + fn either_fn_t(x: Either); + fn either_nonnull_t(x: Either, ()>); + fn either_unique_t(x: Either, ()>); + fn either_nonzero_u8_t(x: Either, ()>); + fn either_nonzero_u16_t(x: Either, ()>); + fn either_nonzero_u32_t(x: Either, ()>); + fn either_nonzero_u64_t(x: Either, ()>); + fn either_nonzero_usize_t(x: Either, ()>); + fn either_nonzero_i8_t(x: Either, ()>); + fn either_nonzero_i16_t(x: Either, ()>); + fn either_nonzero_i32_t(x: Either, ()>); + fn either_nonzero_i64_t(x: Either, ()>); + fn either_nonzero_isize_t(x: Either, ()>); + fn either_transparent_struct_t(x: Either>, ()>); + fn either_transparent_enum_t(x: Either>, ()>); + fn either_phantom_t(x: Either, std::marker::PhantomData<()>>); + fn either_1zst_exhaustive_no_variant_t(x: Either, Z>); + fn either_1zst_exhaustive_no_field_t(x: Either, NoField>); + + fn either_ref_e(x: Either<(), &'static u8>); + fn either_fn_e(x: Either<(), extern "C" fn()>); + fn either_nonnull_e(x: Either<(), std::ptr::NonNull>); + fn either_unique_e(x: Either<(), std::ptr::Unique>); + fn either_nonzero_u8_e(x: Either<(), num::NonZero>); + fn either_nonzero_u16_e(x: Either<(), num::NonZero>); + fn either_nonzero_u32_e(x: Either<(), num::NonZero>); + fn either_nonzero_u64_e(x: Either<(), num::NonZero>); + fn either_nonzero_usize_e(x: Either<(), num::NonZero>); + fn either_nonzero_i8_e(x: Either<(), num::NonZero>); + fn either_nonzero_i16_e(x: Either<(), num::NonZero>); + fn either_nonzero_i32_e(x: Either<(), num::NonZero>); + fn either_nonzero_i64_e(x: Either<(), num::NonZero>); + fn either_nonzero_isize_e(x: Either<(), num::NonZero>); + fn either_transparent_struct_e(x: Either<(), TransparentStruct>>); + fn either_transparent_enum_e(x: Either<(), TransparentEnum>>); + fn either_phantom_e(x: Either, std::marker::PhantomData<()>>); + fn either_1zst_exhaustive_no_variant_e(x: Either>); + fn either_1zst_exhaustive_no_field_e(x: Either>); +} + +pub fn main() {}