From 2d48a3a7bca119eba5648db12e74142bb93d27ea Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sat, 2 Mar 2024 01:29:20 +0100 Subject: [PATCH] Move generic `NonZero` `rustc_layout_scalar_valid_range_start` attribute to inner type. --- library/core/src/num/nonzero.rs | 125 +++++++++++------- .../consts/const-eval/raw-bytes.32bit.stderr | 4 +- .../consts/const-eval/raw-bytes.64bit.stderr | 4 +- tests/ui/consts/const-eval/ub-nonnull.stderr | 4 +- tests/ui/lint/clashing-extern-fn.stderr | 67 +++++++++- tests/ui/lint/invalid_value.stderr | 27 +--- tests/ui/lint/lint-ctypes-enum.stderr | 120 ++++++++++++++++- .../ui/print_type_sizes/niche-filling.stdout | 2 + 8 files changed, 268 insertions(+), 85 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 6cbcac20ea1..b853771b9ea 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -6,21 +6,12 @@ use crate::hash::{Hash, Hasher}; use crate::intrinsics; use crate::marker::StructuralPartialEq; use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem}; +use crate::ptr; use crate::str::FromStr; use super::from_str_radix; use super::{IntErrorKind, ParseIntError}; -mod private { - #[unstable( - feature = "nonzero_internals", - reason = "implementation detail which may disappear or be replaced at any time", - issue = "none" - )] - #[const_trait] - pub trait Sealed {} -} - /// A marker trait for primitive types which can be zero. /// /// This is an implementation detail for [NonZero]\ which may disappear or be replaced at any time. @@ -34,38 +25,70 @@ mod private { issue = "none" )] #[const_trait] -pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed {} +pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed { + #[doc(hidden)] + type NonZeroInner: Sized + Copy; +} macro_rules! impl_zeroable_primitive { - ($primitive:ty) => { - #[unstable( - feature = "nonzero_internals", - reason = "implementation detail which may disappear or be replaced at any time", - issue = "none" - )] - impl const private::Sealed for $primitive {} + ($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => { + mod private { + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + #[const_trait] + pub trait Sealed {} - #[unstable( - feature = "nonzero_internals", - reason = "implementation detail which may disappear or be replaced at any time", - issue = "none" - )] - unsafe impl const ZeroablePrimitive for $primitive {} + $( + #[derive(Debug, Clone, Copy, PartialEq)] + #[repr(transparent)] + #[rustc_layout_scalar_valid_range_start(1)] + #[rustc_nonnull_optimization_guaranteed] + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + pub struct $NonZeroInner($primitive); + )+ + } + + $( + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + impl const private::Sealed for $primitive {} + + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + unsafe impl const ZeroablePrimitive for $primitive { + type NonZeroInner = private::$NonZeroInner; + } + )+ }; } -impl_zeroable_primitive!(u8); -impl_zeroable_primitive!(u16); -impl_zeroable_primitive!(u32); -impl_zeroable_primitive!(u64); -impl_zeroable_primitive!(u128); -impl_zeroable_primitive!(usize); -impl_zeroable_primitive!(i8); -impl_zeroable_primitive!(i16); -impl_zeroable_primitive!(i32); -impl_zeroable_primitive!(i64); -impl_zeroable_primitive!(i128); -impl_zeroable_primitive!(isize); +impl_zeroable_primitive!( + NonZeroU8Inner(u8), + NonZeroU16Inner(u16), + NonZeroU32Inner(u32), + NonZeroU64Inner(u64), + NonZeroU128Inner(u128), + NonZeroUsizeInner(usize), + NonZeroI8Inner(i8), + NonZeroI16Inner(i16), + NonZeroI32Inner(i32), + NonZeroI64Inner(i64), + NonZeroI128Inner(i128), + NonZeroIsizeInner(isize), +); /// A value that is known not to equal zero. /// @@ -80,10 +103,8 @@ impl_zeroable_primitive!(isize); /// ``` #[unstable(feature = "generic_nonzero", issue = "120257")] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(1)] -#[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonZero"] -pub struct NonZero(T); +pub struct NonZero(T::NonZeroInner); macro_rules! impl_nonzero_fmt { ($Trait:ident) => { @@ -114,8 +135,7 @@ where { #[inline] fn clone(&self) -> Self { - // SAFETY: The contained value is non-zero. - unsafe { Self(self.0) } + Self(self.0) } } @@ -188,19 +208,19 @@ where #[inline] fn max(self, other: Self) -> Self { // SAFETY: The maximum of two non-zero values is still non-zero. - unsafe { Self(self.get().max(other.get())) } + unsafe { Self::new_unchecked(self.get().max(other.get())) } } #[inline] fn min(self, other: Self) -> Self { // SAFETY: The minimum of two non-zero values is still non-zero. - unsafe { Self(self.get().min(other.get())) } + unsafe { Self::new_unchecked(self.get().min(other.get())) } } #[inline] fn clamp(self, min: Self, max: Self) -> Self { // SAFETY: A non-zero value clamped between two non-zero values is still non-zero. - unsafe { Self(self.get().clamp(min.get(), max.get())) } + unsafe { Self::new_unchecked(self.get().clamp(min.get(), max.get())) } } } @@ -240,7 +260,7 @@ where #[inline] fn bitor(self, rhs: Self) -> Self::Output { // SAFETY: Bitwise OR of two non-zero values is still non-zero. - unsafe { Self(self.get() | rhs.get()) } + unsafe { Self::new_unchecked(self.get() | rhs.get()) } } } @@ -254,7 +274,7 @@ where #[inline] fn bitor(self, rhs: T) -> Self::Output { // SAFETY: Bitwise OR of a non-zero value with anything is still non-zero. - unsafe { Self(self.get() | rhs) } + unsafe { Self::new_unchecked(self.get() | rhs) } } } @@ -268,7 +288,7 @@ where #[inline] fn bitor(self, rhs: NonZero) -> Self::Output { // SAFETY: Bitwise OR of anything with a non-zero value is still non-zero. - unsafe { NonZero(self | rhs.get()) } + unsafe { NonZero::new_unchecked(self | rhs.get()) } } } @@ -346,7 +366,7 @@ where pub fn from_mut(n: &mut T) -> Option<&mut Self> { // SAFETY: Memory layout optimization guarantees that `Option>` has // the same layout and size as `T`, with `0` representing `None`. - let opt_n = unsafe { &mut *(n as *mut T as *mut Option) }; + let opt_n = unsafe { &mut *(ptr::from_mut(n).cast::>()) }; opt_n.as_mut() } @@ -390,12 +410,17 @@ where // memory somewhere. If the value of `self` was from by-value argument // of some not-inlined function, LLVM don't have range metadata // to understand that the value cannot be zero. - match Self::new(self.0) { - Some(Self(n)) => n, + // + // SAFETY: `Self` is guaranteed to have the same layout as `Option`. + match unsafe { intrinsics::transmute_unchecked(self) } { None => { // SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable. unsafe { intrinsics::unreachable() } } + Some(Self(inner)) => { + // SAFETY: `T::NonZeroInner` is guaranteed to have the same layout as `T`. + unsafe { intrinsics::transmute_unchecked(inner) } + } } } } diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr index c06c3074116..c1748c2e237 100644 --- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr @@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/raw-bytes.rs:59:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 1, align: 1) { @@ -79,7 +79,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index 0589280524c..eb97eab9db7 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr @@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/raw-bytes.rs:59:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 1, align: 1) { @@ -79,7 +79,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index 70b961fe1cd..ab0fb2abdb3 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:24:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { @@ -30,7 +30,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:26:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr index 86ee789aeb2..22d9b4d76f1 100644 --- a/tests/ui/lint/clashing-extern-fn.stderr +++ b/tests/ui/lint/clashing-extern-fn.stderr @@ -1,3 +1,31 @@ +warning: `extern` block uses type `Option>`, which is not FFI-safe + --> $DIR/clashing-extern-fn.rs:369:43 + | +LL | fn option_non_zero_usize() -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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: `#[warn(improper_ctypes)]` on by default + +warning: `extern` block uses type `Option>`, which is not FFI-safe + --> $DIR/clashing-extern-fn.rs:370:43 + | +LL | fn option_non_zero_isize() -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +warning: `extern` block uses type `Option`, which is not FFI-safe + --> $DIR/clashing-extern-fn.rs:428:46 + | +LL | fn hidden_niche_transparent() -> Option; + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + warning: `extern` block uses type `Option`, which is not FFI-safe --> $DIR/clashing-extern-fn.rs:430:55 | @@ -6,7 +34,6 @@ LL | fn hidden_niche_transparent_no_niche() -> Option>>`, which is not FFI-safe --> $DIR/clashing-extern-fn.rs:434:46 @@ -178,6 +205,30 @@ LL | fn non_null_ptr() -> *const usize; = note: expected `unsafe extern "C" fn() -> NonNull` found `unsafe extern "C" fn() -> *const usize` +warning: `option_non_zero_usize` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:369:13 + | +LL | fn option_non_zero_usize() -> usize; + | ----------------------------------- `option_non_zero_usize` previously declared here +... +LL | fn option_non_zero_usize() -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> usize` + found `unsafe extern "C" fn() -> Option>` + +warning: `option_non_zero_isize` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:370:13 + | +LL | fn option_non_zero_isize() -> isize; + | ----------------------------------- `option_non_zero_isize` previously declared here +... +LL | fn option_non_zero_isize() -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> isize` + found `unsafe extern "C" fn() -> Option>` + warning: `option_non_zero_usize_incorrect` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:374:13 | @@ -202,6 +253,18 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize; = note: expected `unsafe extern "C" fn() -> *const usize` found `unsafe extern "C" fn() -> *const isize` +warning: `hidden_niche_transparent` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:428:13 + | +LL | fn hidden_niche_transparent() -> usize; + | -------------------------------------- `hidden_niche_transparent` previously declared here +... +LL | fn hidden_niche_transparent() -> Option; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> usize` + found `unsafe extern "C" fn() -> Option` + warning: `hidden_niche_transparent_no_niche` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:430:13 | @@ -226,5 +289,5 @@ LL | fn hidden_niche_unsafe_cell() -> Option usize` found `unsafe extern "C" fn() -> Option>>` -warning: 19 warnings emitted +warning: 25 warnings emitted diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr index 955d01bd5d9..e45d061a1f0 100644 --- a/tests/ui/lint/invalid_value.stderr +++ b/tests/ui/lint/invalid_value.stderr @@ -320,10 +320,7 @@ error: the type `(NonZero, i32)` does not permit zero-initialization --> $DIR/invalid_value.rs:94:41 | LL | let _val: (NonZero, i32) = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: `std::num::NonZero` must be non-null @@ -331,13 +328,9 @@ error: the type `(NonZero, i32)` does not permit being left uninitialized --> $DIR/invalid_value.rs:95:41 | LL | let _val: (NonZero, i32) = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: `std::num::NonZero` must be non-null - = note: integers must be initialized error: the type `*const dyn Send` does not permit zero-initialization --> $DIR/invalid_value.rs:97:37 @@ -411,10 +404,7 @@ error: the type `OneFruitNonZero` does not permit zero-initialization --> $DIR/invalid_value.rs:106:37 | LL | let _val: OneFruitNonZero = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: `OneFruitNonZero` must be non-null note: because `std::num::NonZero` must be non-null (in this field of the only potentially inhabited enum variant) @@ -427,10 +417,7 @@ error: the type `OneFruitNonZero` does not permit being left uninitialized --> $DIR/invalid_value.rs:107:37 | LL | let _val: OneFruitNonZero = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: `OneFruitNonZero` must be non-null note: because `std::num::NonZero` must be non-null (in this field of the only potentially inhabited enum variant) @@ -438,7 +425,6 @@ note: because `std::num::NonZero` must be non-null (in this field of the on | LL | Banana(NonZero), | ^^^^^^^^^^^^ - = note: integers must be initialized error: the type `bool` does not permit being left uninitialized --> $DIR/invalid_value.rs:111:26 @@ -607,10 +593,7 @@ error: the type `NonZero` does not permit zero-initialization --> $DIR/invalid_value.rs:153:34 | LL | let _val: NonZero = mem::transmute(0); - | ^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: `std::num::NonZero` must be non-null diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index 48be3eb5a56..b1bacbeceda 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -45,21 +45,131 @@ note: the type is defined here LL | enum T { | ^^^^^^ -error: `extern` block uses type `u128`, which is not FFI-safe +error: `extern` block uses type `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:71:21 + | +LL | fn nonzero_u8(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:72:22 + | +LL | fn nonzero_u16(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:73:22 + | +LL | fn nonzero_u32(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:74:22 + | +LL | fn nonzero_u64(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:75:23 | LL | fn nonzero_u128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | - = note: 128-bit integers don't currently have a known stable ABI + = 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 `i128`, which is not FFI-safe +error: `extern` block uses type `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:77:24 + | +LL | fn nonzero_usize(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:78:21 + | +LL | fn nonzero_i8(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:79:22 + | +LL | fn nonzero_i16(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:80:22 + | +LL | fn nonzero_i32(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:81:22 + | +LL | fn nonzero_i64(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:82:23 | LL | fn nonzero_i128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | - = note: 128-bit integers don't currently have a known stable ABI + = 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 `Option>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:84:24 + | +LL | fn nonzero_isize(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:85:29 + | +LL | fn transparent_struct(x: Option>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:86:27 + | +LL | fn transparent_enum(x: Option>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Option>>`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:87:28 @@ -88,5 +198,5 @@ LL | fn no_result(x: Result<(), num::NonZero>); = 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 8 previous errors +error: aborting due to 20 previous errors diff --git a/tests/ui/print_type_sizes/niche-filling.stdout b/tests/ui/print_type_sizes/niche-filling.stdout index 53a58ccc4ee..eeb5de53241 100644 --- a/tests/ui/print_type_sizes/niche-filling.stdout +++ b/tests/ui/print_type_sizes/niche-filling.stdout @@ -68,6 +68,8 @@ print-type-size type: `Union2, u32>`: 4 bytes, alignment: print-type-size variant `Union2`: 4 bytes print-type-size field `.a`: 4 bytes print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes +print-type-size type: `core::num::nonzero::private::NonZeroU32Inner`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `std::num::NonZero`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `std::option::Option>`: 4 bytes, alignment: 4 bytes