Unindent nonzero_integer macro body
This commit is contained in:
parent
54cb822563
commit
9196d2a552
@ -26,167 +26,167 @@ macro_rules! nonzero_integer {
|
|||||||
(
|
(
|
||||||
#[$stability:meta] #[$const_new_unchecked_stability:meta] $Ty:ident($Int:ty);
|
#[$stability:meta] #[$const_new_unchecked_stability:meta] $Ty:ident($Int:ty);
|
||||||
) => {
|
) => {
|
||||||
/// An integer that is known not to equal zero.
|
/// An integer that is known not to equal zero.
|
||||||
|
///
|
||||||
|
/// This enables some memory layout optimization.
|
||||||
|
#[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::mem::size_of;
|
||||||
|
#[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Layout
|
||||||
|
///
|
||||||
|
#[doc = concat!("`", stringify!($Ty), "` is guaranteed to have the same layout and bit validity as `", stringify!($Int), "`")]
|
||||||
|
/// with the exception that `0` is not a valid instance.
|
||||||
|
#[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
|
||||||
|
/// including in FFI.
|
||||||
|
///
|
||||||
|
/// Thanks to the [null pointer optimization],
|
||||||
|
#[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")]
|
||||||
|
/// are guaranteed to have the same size and alignment:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use std::mem::{size_of, align_of};
|
||||||
|
#[doc = concat!("use std::num::", stringify!($Ty), ";")]
|
||||||
|
///
|
||||||
|
#[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
|
||||||
|
#[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [null pointer optimization]: crate::option#representation
|
||||||
|
#[$stability]
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
|
#[rustc_nonnull_optimization_guaranteed]
|
||||||
|
#[rustc_diagnostic_item = stringify!($Ty)]
|
||||||
|
pub struct $Ty($Int);
|
||||||
|
|
||||||
|
impl $Ty {
|
||||||
|
/// Creates a non-zero without checking whether the value is non-zero.
|
||||||
|
/// This results in undefined behaviour if the value is zero.
|
||||||
///
|
///
|
||||||
/// This enables some memory layout optimization.
|
/// # Safety
|
||||||
#[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
|
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// The value must not be zero.
|
||||||
/// use std::mem::size_of;
|
|
||||||
#[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Layout
|
|
||||||
///
|
|
||||||
#[doc = concat!("`", stringify!($Ty), "` is guaranteed to have the same layout and bit validity as `", stringify!($Int), "`")]
|
|
||||||
/// with the exception that `0` is not a valid instance.
|
|
||||||
#[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
|
|
||||||
/// including in FFI.
|
|
||||||
///
|
|
||||||
/// Thanks to the [null pointer optimization],
|
|
||||||
#[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")]
|
|
||||||
/// are guaranteed to have the same size and alignment:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # use std::mem::{size_of, align_of};
|
|
||||||
#[doc = concat!("use std::num::", stringify!($Ty), ";")]
|
|
||||||
///
|
|
||||||
#[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
|
|
||||||
#[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")]
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [null pointer optimization]: crate::option#representation
|
|
||||||
#[$stability]
|
#[$stability]
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[$const_new_unchecked_stability]
|
||||||
#[repr(transparent)]
|
#[must_use]
|
||||||
#[rustc_layout_scalar_valid_range_start(1)]
|
#[inline]
|
||||||
#[rustc_nonnull_optimization_guaranteed]
|
pub const unsafe fn new_unchecked(n: $Int) -> Self {
|
||||||
#[rustc_diagnostic_item = stringify!($Ty)]
|
crate::panic::debug_assert_nounwind!(
|
||||||
pub struct $Ty($Int);
|
n != 0,
|
||||||
|
concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
|
||||||
impl $Ty {
|
);
|
||||||
/// Creates a non-zero without checking whether the value is non-zero.
|
// SAFETY: this is guaranteed to be safe by the caller.
|
||||||
/// This results in undefined behaviour if the value is zero.
|
unsafe {
|
||||||
///
|
Self(n)
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The value must not be zero.
|
|
||||||
#[$stability]
|
|
||||||
#[$const_new_unchecked_stability]
|
|
||||||
#[must_use]
|
|
||||||
#[inline]
|
|
||||||
pub const unsafe fn new_unchecked(n: $Int) -> Self {
|
|
||||||
crate::panic::debug_assert_nounwind!(
|
|
||||||
n != 0,
|
|
||||||
concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
|
|
||||||
);
|
|
||||||
// SAFETY: this is guaranteed to be safe by the caller.
|
|
||||||
unsafe {
|
|
||||||
Self(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a non-zero if the given value is not zero.
|
|
||||||
#[$stability]
|
|
||||||
#[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
|
|
||||||
#[must_use]
|
|
||||||
#[inline]
|
|
||||||
pub const fn new(n: $Int) -> Option<Self> {
|
|
||||||
if n != 0 {
|
|
||||||
// SAFETY: we just checked that there's no `0`
|
|
||||||
Some(unsafe { Self(n) })
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the value as a primitive type.
|
|
||||||
#[$stability]
|
|
||||||
#[inline]
|
|
||||||
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
|
|
||||||
pub const fn get(self) -> $Int {
|
|
||||||
// FIXME: Remove this after LLVM supports `!range` metadata for function
|
|
||||||
// arguments https://github.com/llvm/llvm-project/issues/76628
|
|
||||||
//
|
|
||||||
// Rustc can set range metadata only if it loads `self` from
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// SAFETY: It is an invariant of this type.
|
|
||||||
unsafe {
|
|
||||||
intrinsics::assume(self.0 != 0);
|
|
||||||
}
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "from_nonzero", since = "1.31.0")]
|
|
||||||
impl From<$Ty> for $Int {
|
|
||||||
#[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
|
|
||||||
#[inline]
|
|
||||||
fn from(nonzero: $Ty) -> Self {
|
|
||||||
// Call nonzero to keep information range information
|
|
||||||
// from get method.
|
|
||||||
nonzero.get()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
/// Creates a non-zero if the given value is not zero.
|
||||||
impl BitOr for $Ty {
|
#[$stability]
|
||||||
type Output = Self;
|
#[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
|
||||||
#[inline]
|
#[must_use]
|
||||||
fn bitor(self, rhs: Self) -> Self::Output {
|
#[inline]
|
||||||
// SAFETY: since `self` and `rhs` are both nonzero, the
|
pub const fn new(n: $Int) -> Option<Self> {
|
||||||
// result of the bitwise-or will be nonzero.
|
if n != 0 {
|
||||||
unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
|
// SAFETY: we just checked that there's no `0`
|
||||||
|
Some(unsafe { Self(n) })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
/// Returns the value as a primitive type.
|
||||||
impl BitOr<$Int> for $Ty {
|
#[$stability]
|
||||||
type Output = Self;
|
#[inline]
|
||||||
#[inline]
|
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
|
||||||
fn bitor(self, rhs: $Int) -> Self::Output {
|
pub const fn get(self) -> $Int {
|
||||||
// SAFETY: since `self` is nonzero, the result of the
|
// FIXME: Remove this after LLVM supports `!range` metadata for function
|
||||||
// bitwise-or will be nonzero regardless of the value of
|
// arguments https://github.com/llvm/llvm-project/issues/76628
|
||||||
// `rhs`.
|
//
|
||||||
unsafe { $Ty::new_unchecked(self.get() | rhs) }
|
// Rustc can set range metadata only if it loads `self` from
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// SAFETY: It is an invariant of this type.
|
||||||
|
unsafe {
|
||||||
|
intrinsics::assume(self.0 != 0);
|
||||||
}
|
}
|
||||||
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
}
|
||||||
impl BitOr<$Ty> for $Int {
|
|
||||||
type Output = $Ty;
|
|
||||||
#[inline]
|
|
||||||
fn bitor(self, rhs: $Ty) -> Self::Output {
|
|
||||||
// SAFETY: since `rhs` is nonzero, the result of the
|
|
||||||
// bitwise-or will be nonzero regardless of the value of
|
|
||||||
// `self`.
|
|
||||||
unsafe { $Ty::new_unchecked(self | rhs.get()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
#[stable(feature = "from_nonzero", since = "1.31.0")]
|
||||||
impl BitOrAssign for $Ty {
|
impl From<$Ty> for $Int {
|
||||||
#[inline]
|
#[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
|
||||||
fn bitor_assign(&mut self, rhs: Self) {
|
#[inline]
|
||||||
*self = *self | rhs;
|
fn from(nonzero: $Ty) -> Self {
|
||||||
}
|
// Call nonzero to keep information range information
|
||||||
|
// from get method.
|
||||||
|
nonzero.get()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
impl BitOrAssign<$Int> for $Ty {
|
impl BitOr for $Ty {
|
||||||
#[inline]
|
type Output = Self;
|
||||||
fn bitor_assign(&mut self, rhs: $Int) {
|
#[inline]
|
||||||
*self = *self | rhs;
|
fn bitor(self, rhs: Self) -> Self::Output {
|
||||||
}
|
// SAFETY: since `self` and `rhs` are both nonzero, the
|
||||||
|
// result of the bitwise-or will be nonzero.
|
||||||
|
unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_nonzero_fmt! {
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
|
impl BitOr<$Int> for $Ty {
|
||||||
|
type Output = Self;
|
||||||
|
#[inline]
|
||||||
|
fn bitor(self, rhs: $Int) -> Self::Output {
|
||||||
|
// SAFETY: since `self` is nonzero, the result of the
|
||||||
|
// bitwise-or will be nonzero regardless of the value of
|
||||||
|
// `rhs`.
|
||||||
|
unsafe { $Ty::new_unchecked(self.get() | rhs) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl BitOr<$Ty> for $Int {
|
||||||
|
type Output = $Ty;
|
||||||
|
#[inline]
|
||||||
|
fn bitor(self, rhs: $Ty) -> Self::Output {
|
||||||
|
// SAFETY: since `rhs` is nonzero, the result of the
|
||||||
|
// bitwise-or will be nonzero regardless of the value of
|
||||||
|
// `self`.
|
||||||
|
unsafe { $Ty::new_unchecked(self | rhs.get()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl BitOrAssign for $Ty {
|
||||||
|
#[inline]
|
||||||
|
fn bitor_assign(&mut self, rhs: Self) {
|
||||||
|
*self = *self | rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl BitOrAssign<$Int> for $Ty {
|
||||||
|
#[inline]
|
||||||
|
fn bitor_assign(&mut self, rhs: $Int) {
|
||||||
|
*self = *self | rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_nonzero_fmt! {
|
||||||
|
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user