Move generic NonZero
rustc_layout_scalar_valid_range_start
attribute to inner type.
This commit is contained in:
parent
3521a2f2f3
commit
2d48a3a7bc
8 changed files with 268 additions and 85 deletions
|
@ -6,21 +6,12 @@ use crate::hash::{Hash, Hasher};
|
||||||
use crate::intrinsics;
|
use crate::intrinsics;
|
||||||
use crate::marker::StructuralPartialEq;
|
use crate::marker::StructuralPartialEq;
|
||||||
use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
|
use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
|
||||||
|
use crate::ptr;
|
||||||
use crate::str::FromStr;
|
use crate::str::FromStr;
|
||||||
|
|
||||||
use super::from_str_radix;
|
use super::from_str_radix;
|
||||||
use super::{IntErrorKind, ParseIntError};
|
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.
|
/// A marker trait for primitive types which can be zero.
|
||||||
///
|
///
|
||||||
/// This is an implementation detail for <code>[NonZero]\<T></code> which may disappear or be replaced at any time.
|
/// This is an implementation detail for <code>[NonZero]\<T></code> which may disappear or be replaced at any time.
|
||||||
|
@ -34,38 +25,70 @@ mod private {
|
||||||
issue = "none"
|
issue = "none"
|
||||||
)]
|
)]
|
||||||
#[const_trait]
|
#[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 {
|
macro_rules! impl_zeroable_primitive {
|
||||||
($primitive:ty) => {
|
($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => {
|
||||||
#[unstable(
|
mod private {
|
||||||
feature = "nonzero_internals",
|
#[unstable(
|
||||||
reason = "implementation detail which may disappear or be replaced at any time",
|
feature = "nonzero_internals",
|
||||||
issue = "none"
|
reason = "implementation detail which may disappear or be replaced at any time",
|
||||||
)]
|
issue = "none"
|
||||||
impl const private::Sealed for $primitive {}
|
)]
|
||||||
|
#[const_trait]
|
||||||
|
pub trait Sealed {}
|
||||||
|
|
||||||
#[unstable(
|
$(
|
||||||
feature = "nonzero_internals",
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
reason = "implementation detail which may disappear or be replaced at any time",
|
#[repr(transparent)]
|
||||||
issue = "none"
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
)]
|
#[rustc_nonnull_optimization_guaranteed]
|
||||||
unsafe impl const ZeroablePrimitive for $primitive {}
|
#[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!(
|
||||||
impl_zeroable_primitive!(u16);
|
NonZeroU8Inner(u8),
|
||||||
impl_zeroable_primitive!(u32);
|
NonZeroU16Inner(u16),
|
||||||
impl_zeroable_primitive!(u64);
|
NonZeroU32Inner(u32),
|
||||||
impl_zeroable_primitive!(u128);
|
NonZeroU64Inner(u64),
|
||||||
impl_zeroable_primitive!(usize);
|
NonZeroU128Inner(u128),
|
||||||
impl_zeroable_primitive!(i8);
|
NonZeroUsizeInner(usize),
|
||||||
impl_zeroable_primitive!(i16);
|
NonZeroI8Inner(i8),
|
||||||
impl_zeroable_primitive!(i32);
|
NonZeroI16Inner(i16),
|
||||||
impl_zeroable_primitive!(i64);
|
NonZeroI32Inner(i32),
|
||||||
impl_zeroable_primitive!(i128);
|
NonZeroI64Inner(i64),
|
||||||
impl_zeroable_primitive!(isize);
|
NonZeroI128Inner(i128),
|
||||||
|
NonZeroIsizeInner(isize),
|
||||||
|
);
|
||||||
|
|
||||||
/// A value that is known not to equal zero.
|
/// A value that is known not to equal zero.
|
||||||
///
|
///
|
||||||
|
@ -80,10 +103,8 @@ impl_zeroable_primitive!(isize);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "generic_nonzero", issue = "120257")]
|
#[unstable(feature = "generic_nonzero", issue = "120257")]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[rustc_layout_scalar_valid_range_start(1)]
|
|
||||||
#[rustc_nonnull_optimization_guaranteed]
|
|
||||||
#[rustc_diagnostic_item = "NonZero"]
|
#[rustc_diagnostic_item = "NonZero"]
|
||||||
pub struct NonZero<T: ZeroablePrimitive>(T);
|
pub struct NonZero<T: ZeroablePrimitive>(T::NonZeroInner);
|
||||||
|
|
||||||
macro_rules! impl_nonzero_fmt {
|
macro_rules! impl_nonzero_fmt {
|
||||||
($Trait:ident) => {
|
($Trait:ident) => {
|
||||||
|
@ -114,8 +135,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
// SAFETY: The contained value is non-zero.
|
Self(self.0)
|
||||||
unsafe { Self(self.0) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,19 +208,19 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max(self, other: Self) -> Self {
|
fn max(self, other: Self) -> Self {
|
||||||
// SAFETY: The maximum of two non-zero values is still non-zero.
|
// 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]
|
#[inline]
|
||||||
fn min(self, other: Self) -> Self {
|
fn min(self, other: Self) -> Self {
|
||||||
// SAFETY: The minimum of two non-zero values is still non-zero.
|
// 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]
|
#[inline]
|
||||||
fn clamp(self, min: Self, max: Self) -> Self {
|
fn clamp(self, min: Self, max: Self) -> Self {
|
||||||
// SAFETY: A non-zero value clamped between two non-zero values is still non-zero.
|
// 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]
|
#[inline]
|
||||||
fn bitor(self, rhs: Self) -> Self::Output {
|
fn bitor(self, rhs: Self) -> Self::Output {
|
||||||
// SAFETY: Bitwise OR of two non-zero values is still non-zero.
|
// 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]
|
#[inline]
|
||||||
fn bitor(self, rhs: T) -> Self::Output {
|
fn bitor(self, rhs: T) -> Self::Output {
|
||||||
// SAFETY: Bitwise OR of a non-zero value with anything is still non-zero.
|
// 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]
|
#[inline]
|
||||||
fn bitor(self, rhs: NonZero<T>) -> Self::Output {
|
fn bitor(self, rhs: NonZero<T>) -> Self::Output {
|
||||||
// SAFETY: Bitwise OR of anything with a non-zero value is still non-zero.
|
// 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> {
|
pub fn from_mut(n: &mut T) -> Option<&mut Self> {
|
||||||
// SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
|
// SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
|
||||||
// the same layout and size as `T`, with `0` representing `None`.
|
// the same layout and size as `T`, with `0` representing `None`.
|
||||||
let opt_n = unsafe { &mut *(n as *mut T as *mut Option<Self>) };
|
let opt_n = unsafe { &mut *(ptr::from_mut(n).cast::<Option<Self>>()) };
|
||||||
|
|
||||||
opt_n.as_mut()
|
opt_n.as_mut()
|
||||||
}
|
}
|
||||||
|
@ -390,12 +410,17 @@ where
|
||||||
// memory somewhere. If the value of `self` was from by-value argument
|
// memory somewhere. If the value of `self` was from by-value argument
|
||||||
// of some not-inlined function, LLVM don't have range metadata
|
// of some not-inlined function, LLVM don't have range metadata
|
||||||
// to understand that the value cannot be zero.
|
// 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<Self>`.
|
||||||
|
match unsafe { intrinsics::transmute_unchecked(self) } {
|
||||||
None => {
|
None => {
|
||||||
// SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable.
|
// SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable.
|
||||||
unsafe { intrinsics::unreachable() }
|
unsafe { intrinsics::unreachable() }
|
||||||
}
|
}
|
||||||
|
Some(Self(inner)) => {
|
||||||
|
// SAFETY: `T::NonZeroInner` is guaranteed to have the same layout as `T`.
|
||||||
|
unsafe { intrinsics::transmute_unchecked(inner) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/raw-bytes.rs:59:1
|
--> $DIR/raw-bytes.rs:59:1
|
||||||
|
|
|
|
||||||
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
LL | const NULL_U8: NonZero<u8> = 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 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) {
|
= 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
|
--> $DIR/raw-bytes.rs:61:1
|
||||||
|
|
|
|
||||||
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
|
LL | const NULL_USIZE: NonZero<usize> = 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 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) {
|
= note: the raw bytes of the constant (size: 4, align: 4) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/raw-bytes.rs:59:1
|
--> $DIR/raw-bytes.rs:59:1
|
||||||
|
|
|
|
||||||
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
LL | const NULL_U8: NonZero<u8> = 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 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) {
|
= 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
|
--> $DIR/raw-bytes.rs:61:1
|
||||||
|
|
|
|
||||||
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
|
LL | const NULL_USIZE: NonZero<usize> = 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 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) {
|
= note: the raw bytes of the constant (size: 8, align: 8) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-nonnull.rs:24:1
|
--> $DIR/ub-nonnull.rs:24:1
|
||||||
|
|
|
|
||||||
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
LL | const NULL_U8: NonZero<u8> = 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 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) {
|
= 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
|
--> $DIR/ub-nonnull.rs:26:1
|
||||||
|
|
|
|
||||||
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
|
LL | const NULL_USIZE: NonZero<usize> = 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 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) {
|
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
|
||||||
|
|
|
@ -1,3 +1,31 @@
|
||||||
|
warning: `extern` block uses type `Option<NonZero<usize>>`, which is not FFI-safe
|
||||||
|
--> $DIR/clashing-extern-fn.rs:369:43
|
||||||
|
|
|
||||||
|
LL | fn option_non_zero_usize() -> Option<core::num::NonZero<usize>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<isize>>`, which is not FFI-safe
|
||||||
|
--> $DIR/clashing-extern-fn.rs:370:43
|
||||||
|
|
|
||||||
|
LL | fn option_non_zero_isize() -> Option<core::num::NonZero<isize>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<Transparent>`, which is not FFI-safe
|
||||||
|
--> $DIR/clashing-extern-fn.rs:428:46
|
||||||
|
|
|
||||||
|
LL | fn hidden_niche_transparent() -> Option<Transparent>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ 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<TransparentNoNiche>`, which is not FFI-safe
|
warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
|
||||||
--> $DIR/clashing-extern-fn.rs:430:55
|
--> $DIR/clashing-extern-fn.rs:430:55
|
||||||
|
|
|
|
||||||
|
@ -6,7 +34,6 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
|
||||||
|
|
|
|
||||||
= 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
|
||||||
= note: `#[warn(improper_ctypes)]` on by default
|
|
||||||
|
|
||||||
warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
|
warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
|
||||||
--> $DIR/clashing-extern-fn.rs:434:46
|
--> $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<usize>`
|
= note: expected `unsafe extern "C" fn() -> NonNull<usize>`
|
||||||
found `unsafe extern "C" fn() -> *const usize`
|
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<core::num::NonZero<usize>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||||
|
|
|
||||||
|
= note: expected `unsafe extern "C" fn() -> usize`
|
||||||
|
found `unsafe extern "C" fn() -> Option<NonZero<usize>>`
|
||||||
|
|
||||||
|
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<core::num::NonZero<isize>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||||
|
|
|
||||||
|
= note: expected `unsafe extern "C" fn() -> isize`
|
||||||
|
found `unsafe extern "C" fn() -> Option<NonZero<isize>>`
|
||||||
|
|
||||||
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
|
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
|
||||||
--> $DIR/clashing-extern-fn.rs:374:13
|
--> $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`
|
= note: expected `unsafe extern "C" fn() -> *const usize`
|
||||||
found `unsafe extern "C" fn() -> *const isize`
|
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<Transparent>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||||
|
|
|
||||||
|
= note: expected `unsafe extern "C" fn() -> usize`
|
||||||
|
found `unsafe extern "C" fn() -> Option<Transparent>`
|
||||||
|
|
||||||
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
|
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
|
||||||
--> $DIR/clashing-extern-fn.rs:430:13
|
--> $DIR/clashing-extern-fn.rs:430:13
|
||||||
|
|
|
|
||||||
|
@ -226,5 +289,5 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
|
||||||
= note: expected `unsafe extern "C" fn() -> usize`
|
= note: expected `unsafe extern "C" fn() -> usize`
|
||||||
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
|
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
|
||||||
|
|
||||||
warning: 19 warnings emitted
|
warning: 25 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -320,10 +320,7 @@ error: the type `(NonZero<u32>, i32)` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:94:41
|
--> $DIR/invalid_value.rs:94:41
|
||||||
|
|
|
|
||||||
LL | let _val: (NonZero<u32>, i32) = mem::zeroed();
|
LL | let _val: (NonZero<u32>, i32) = mem::zeroed();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: `std::num::NonZero<u32>` must be non-null
|
= note: `std::num::NonZero<u32>` must be non-null
|
||||||
|
|
||||||
|
@ -331,13 +328,9 @@ error: the type `(NonZero<u32>, i32)` does not permit being left uninitialized
|
||||||
--> $DIR/invalid_value.rs:95:41
|
--> $DIR/invalid_value.rs:95:41
|
||||||
|
|
|
|
||||||
LL | let _val: (NonZero<u32>, i32) = mem::uninitialized();
|
LL | let _val: (NonZero<u32>, i32) = mem::uninitialized();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: `std::num::NonZero<u32>` must be non-null
|
= note: `std::num::NonZero<u32>` must be non-null
|
||||||
= note: integers must be initialized
|
|
||||||
|
|
||||||
error: the type `*const dyn Send` does not permit zero-initialization
|
error: the type `*const dyn Send` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:97:37
|
--> $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
|
--> $DIR/invalid_value.rs:106:37
|
||||||
|
|
|
|
||||||
LL | let _val: OneFruitNonZero = mem::zeroed();
|
LL | let _val: OneFruitNonZero = mem::zeroed();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: `OneFruitNonZero` must be non-null
|
= note: `OneFruitNonZero` must be non-null
|
||||||
note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
|
note: because `std::num::NonZero<u32>` 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
|
--> $DIR/invalid_value.rs:107:37
|
||||||
|
|
|
|
||||||
LL | let _val: OneFruitNonZero = mem::uninitialized();
|
LL | let _val: OneFruitNonZero = mem::uninitialized();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: `OneFruitNonZero` must be non-null
|
= note: `OneFruitNonZero` must be non-null
|
||||||
note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
|
note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
|
||||||
|
@ -438,7 +425,6 @@ note: because `std::num::NonZero<u32>` must be non-null (in this field of the on
|
||||||
|
|
|
|
||||||
LL | Banana(NonZero<u32>),
|
LL | Banana(NonZero<u32>),
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
= note: integers must be initialized
|
|
||||||
|
|
||||||
error: the type `bool` does not permit being left uninitialized
|
error: the type `bool` does not permit being left uninitialized
|
||||||
--> $DIR/invalid_value.rs:111:26
|
--> $DIR/invalid_value.rs:111:26
|
||||||
|
@ -607,10 +593,7 @@ error: the type `NonZero<u32>` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:153:34
|
--> $DIR/invalid_value.rs:153:34
|
||||||
|
|
|
|
||||||
LL | let _val: NonZero<u32> = mem::transmute(0);
|
LL | let _val: NonZero<u32> = mem::transmute(0);
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: `std::num::NonZero<u32>` must be non-null
|
= note: `std::num::NonZero<u32>` must be non-null
|
||||||
|
|
||||||
|
|
|
@ -45,21 +45,131 @@ note: the type is defined here
|
||||||
LL | enum T {
|
LL | enum T {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
error: `extern` block uses type `Option<NonZero<u8>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:71:21
|
||||||
|
|
|
||||||
|
LL | fn nonzero_u8(x: Option<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 `Option<NonZero<u16>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:72:22
|
||||||
|
|
|
||||||
|
LL | fn nonzero_u16(x: Option<num::NonZero<u16>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<u32>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:73:22
|
||||||
|
|
|
||||||
|
LL | fn nonzero_u32(x: Option<num::NonZero<u32>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<u64>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:74:22
|
||||||
|
|
|
||||||
|
LL | fn nonzero_u64(x: Option<num::NonZero<u64>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<u128>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:75:23
|
--> $DIR/lint-ctypes-enum.rs:75:23
|
||||||
|
|
|
|
||||||
LL | fn nonzero_u128(x: Option<num::NonZero<u128>>);
|
LL | fn nonzero_u128(x: Option<num::NonZero<u128>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<usize>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:77:24
|
||||||
|
|
|
||||||
|
LL | fn nonzero_usize(x: Option<num::NonZero<usize>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<i8>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:78:21
|
||||||
|
|
|
||||||
|
LL | fn nonzero_i8(x: Option<num::NonZero<i8>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<i16>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:79:22
|
||||||
|
|
|
||||||
|
LL | fn nonzero_i16(x: Option<num::NonZero<i16>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<i32>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:80:22
|
||||||
|
|
|
||||||
|
LL | fn nonzero_i32(x: Option<num::NonZero<i32>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<i64>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:81:22
|
||||||
|
|
|
||||||
|
LL | fn nonzero_i64(x: Option<num::NonZero<i64>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<i128>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:82:23
|
--> $DIR/lint-ctypes-enum.rs:82:23
|
||||||
|
|
|
|
||||||
LL | fn nonzero_i128(x: Option<num::NonZero<i128>>);
|
LL | fn nonzero_i128(x: Option<num::NonZero<i128>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<NonZero<isize>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:84:24
|
||||||
|
|
|
||||||
|
LL | fn nonzero_isize(x: Option<num::NonZero<isize>>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<TransparentStruct<NonZero<u8>>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:85:29
|
||||||
|
|
|
||||||
|
LL | fn transparent_struct(x: Option<TransparentStruct<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 `Option<TransparentEnum<NonZero<u8>>>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:86:27
|
||||||
|
|
|
||||||
|
LL | fn transparent_enum(x: Option<TransparentEnum<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 `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:87:28
|
--> $DIR/lint-ctypes-enum.rs:87:28
|
||||||
|
@ -88,5 +198,5 @@ LL | fn no_result(x: Result<(), num::NonZero<i32>>);
|
||||||
= 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 8 previous errors
|
error: aborting due to 20 previous errors
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ print-type-size type: `Union2<std::num::NonZero<u32>, u32>`: 4 bytes, alignment:
|
||||||
print-type-size variant `Union2`: 4 bytes
|
print-type-size variant `Union2`: 4 bytes
|
||||||
print-type-size field `.a`: 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 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<u32>`: 4 bytes, alignment: 4 bytes
|
print-type-size type: `std::num::NonZero<u32>`: 4 bytes, alignment: 4 bytes
|
||||||
print-type-size field `.0`: 4 bytes
|
print-type-size field `.0`: 4 bytes
|
||||||
print-type-size type: `std::option::Option<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
|
print-type-size type: `std::option::Option<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue