Rollup merge of #124587 - reitermarkus:use-generic-nonzero, r=dtolnay

Generic `NonZero` post-stabilization changes.

Tracking issue: https://github.com/rust-lang/rust/issues/120257

r? ``@dtolnay``
This commit is contained in:
Matthias Krüger 2024-05-08 23:33:25 +02:00 committed by GitHub
commit d8a3a69ad1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 399 additions and 440 deletions

View File

@ -2,6 +2,7 @@ use std::borrow::{Borrow, Cow};
use std::cmp;
use std::fmt::{self, Write};
use std::iter;
use std::num::NonZero;
use std::ops::Bound;
use std::ops::Deref;
@ -10,8 +11,8 @@ use tracing::debug;
use crate::{
Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche,
NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout,
Variants, WrappingRange,
Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout, Variants,
WrappingRange,
};
// A variant is absent if it's uninhabited and only has ZST fields.
@ -327,7 +328,7 @@ pub trait LayoutCalculator {
Some(LayoutS {
variants: Variants::Single { index: VariantIdx::new(0) },
fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?),
fields: FieldsShape::Union(NonZero::new(only_variant.len())?),
abi,
largest_niche: None,
align,

View File

@ -4,7 +4,7 @@
#![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
use std::fmt;
use std::num::{NonZeroUsize, ParseIntError};
use std::num::{NonZero, ParseIntError};
use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
use std::str::FromStr;
@ -1149,7 +1149,7 @@ pub enum FieldsShape<FieldIdx: Idx> {
Primitive,
/// All fields start at no offset. The `usize` is the field count.
Union(NonZeroUsize),
Union(NonZero<usize>),
/// Array/vector-like placement, with all fields of identical types.
Array { stride: Size, count: u64 },

View File

@ -2164,7 +2164,7 @@ pub enum TyKind {
MacCall(P<MacCall>),
/// Placeholder for a `va_list`.
CVarArgs,
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZeroU32`,
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
/// just as part of the type system.
Pat(P<Ty>, P<Pat>),
/// Sometimes we need a dummy value when no error has occurred.

View File

@ -2227,7 +2227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> bool {
let tcx = self.tcx;
let (adt, args, unwrap) = match expected.kind() {
// In case Option<NonZero*> is wanted, but * is provided, suggest calling new
// In case `Option<NonZero<T>>` is wanted, but `T` is provided, suggest calling `new`.
ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
let nonzero_type = args.type_at(0); // Unwrap option type.
let ty::Adt(adt, args) = nonzero_type.kind() else {
@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
(adt, args, "")
}
// In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
// In case `NonZero<T>` is wanted but `T` is provided, also add `.unwrap()` to satisfy types.
ty::Adt(adt, args) => (adt, args, ".unwrap()"),
_ => return false,
};
@ -2244,32 +2244,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false;
}
// FIXME: This can be simplified once `NonZero<T>` is stable.
let coercable_types = [
("NonZeroU8", tcx.types.u8),
("NonZeroU16", tcx.types.u16),
("NonZeroU32", tcx.types.u32),
("NonZeroU64", tcx.types.u64),
("NonZeroU128", tcx.types.u128),
("NonZeroI8", tcx.types.i8),
("NonZeroI16", tcx.types.i16),
("NonZeroI32", tcx.types.i32),
("NonZeroI64", tcx.types.i64),
("NonZeroI128", tcx.types.i128),
];
let int_type = args.type_at(0);
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }
}) else {
if !self.can_coerce(expr_ty, int_type) {
return false;
};
}
err.multipart_suggestion(
format!("consider calling `{nonzero_alias}::new`"),
format!("consider calling `{}::new`", sym::NonZero),
vec![
(expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")),
(expr.span.shrink_to_lo(), format!("{}::new(", sym::NonZero)),
(expr.span.shrink_to_hi(), format!("){unwrap}")),
],
Applicability::MaybeIncorrect,

View File

@ -6,7 +6,7 @@ use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
use crate::Error;
use crate::Opaque;
use std::fmt::{self, Debug};
use std::num::NonZeroUsize;
use std::num::NonZero;
use std::ops::RangeInclusive;
/// A function ABI definition.
@ -133,7 +133,7 @@ pub enum FieldsShape {
Primitive,
/// All fields start at no offset. The `usize` is the field count.
Union(NonZeroUsize),
Union(NonZero<usize>),
/// Array/vector-like placement, with all fields of identical types.
Array { stride: Size, count: u64 },

View File

@ -1,7 +1,7 @@
use crate::{
intrinsics,
iter::{from_fn, TrustedLen, TrustedRandomAccess},
num::NonZeroUsize,
num::NonZero,
ops::{Range, Try},
};
@ -42,10 +42,10 @@ impl<I> StepBy<I> {
/// The `step` that was originally passed to `Iterator::step_by(step)`,
/// aka `self.step_minus_one + 1`.
#[inline]
fn original_step(&self) -> NonZeroUsize {
fn original_step(&self) -> NonZero<usize> {
// SAFETY: By type invariant, `step_minus_one` cannot be `MAX`, which
// means the addition cannot overflow and the result cannot be zero.
unsafe { NonZeroUsize::new_unchecked(intrinsics::unchecked_add(self.step_minus_one, 1)) }
unsafe { NonZero::new_unchecked(intrinsics::unchecked_add(self.step_minus_one, 1)) }
}
}
@ -231,12 +231,12 @@ unsafe impl<I: Iterator> StepByImpl<I> for StepBy<I> {
#[inline]
default fn spec_size_hint(&self) -> (usize, Option<usize>) {
#[inline]
fn first_size(step: NonZeroUsize) -> impl Fn(usize) -> usize {
fn first_size(step: NonZero<usize>) -> impl Fn(usize) -> usize {
move |n| if n == 0 { 0 } else { 1 + (n - 1) / step }
}
#[inline]
fn other_size(step: NonZeroUsize) -> impl Fn(usize) -> usize {
fn other_size(step: NonZero<usize>) -> impl Fn(usize) -> usize {
move |n| n / step
}

View File

@ -453,8 +453,7 @@ macro_rules! nonzero_integer {
#[$stability:meta]
Self = $Ty:ident,
Primitive = $signedness:ident $Int:ident,
$(UnsignedNonZero = $UnsignedNonZero:ident,)?
UnsignedPrimitive = $UnsignedPrimitive:ty,
UnsignedPrimitive = $Uint:ty,
// Used in doc comments.
leading_zeros_test = $leading_zeros_test:expr,
@ -492,7 +491,7 @@ macro_rules! nonzero_integer {
#[$stability]
pub type $Ty = NonZero<$Int>;
impl $Ty {
impl NonZero<$Int> {
/// The size of this non-zero integer type in bits.
///
#[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")]
@ -500,9 +499,9 @@ macro_rules! nonzero_integer {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
#[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::BITS, ", stringify!($Int), "::BITS);")]
/// ```
#[stable(feature = "nonzero_bits", since = "1.67.0")]
pub const BITS: u32 = <$Int>::BITS;
@ -516,7 +515,9 @@ macro_rules! nonzero_integer {
/// Basic usage:
///
/// ```
#[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", $leading_zeros_test, ").unwrap();")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(", $leading_zeros_test, ").unwrap();")]
///
/// assert_eq!(n.leading_zeros(), 0);
/// ```
@ -528,7 +529,7 @@ macro_rules! nonzero_integer {
pub const fn leading_zeros(self) -> u32 {
// SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
unsafe {
intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive)
intrinsics::ctlz_nonzero(self.get() as $Uint)
}
}
@ -542,7 +543,9 @@ macro_rules! nonzero_integer {
/// Basic usage:
///
/// ```
#[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(0b0101000).unwrap();")]
///
/// assert_eq!(n.trailing_zeros(), 3);
/// ```
@ -554,7 +557,7 @@ macro_rules! nonzero_integer {
pub const fn trailing_zeros(self) -> u32 {
// SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
unsafe {
intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive)
intrinsics::cttz_nonzero(self.get() as $Uint)
}
}
@ -567,10 +570,10 @@ macro_rules! nonzero_integer {
/// ```
/// #![feature(non_zero_count_ones)]
///
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
/// # use std::num::*;
/// #
#[doc = concat!("let a = NonZero::<", stringify!($Int), ">::new(0b100_0000)?;")]
#[doc = concat!("let b = NonZero::<", stringify!($Int), ">::new(0b100_0011)?;")]
///
@ -597,8 +600,7 @@ macro_rules! nonzero_integer {
nonzero_integer_signedness_dependent_methods! {
Self = $Ty,
Primitive = $signedness $Int,
$(UnsignedNonZero = $UnsignedNonZero,)?
UnsignedPrimitive = $UnsignedPrimitive,
UnsignedPrimitive = $Uint,
}
/// Multiplies two non-zero integers together.
@ -608,13 +610,13 @@ macro_rules! nonzero_integer {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(Some(four), two.checked_mul(two));
/// assert_eq!(None, max.checked_mul(two));
@ -642,18 +644,18 @@ macro_rules! nonzero_integer {
}
/// Multiplies two non-zero integers together.
#[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
#[doc = concat!("Return [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.")]
///
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(four, two.saturating_mul(two));
/// assert_eq!(max, four.saturating_mul(max));
@ -698,11 +700,12 @@ macro_rules! nonzero_integer {
/// ```
/// #![feature(nonzero_ops)]
///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")]
///
/// assert_eq!(four, unsafe { two.unchecked_mul(two) });
/// # Some(())
@ -724,13 +727,13 @@ macro_rules! nonzero_integer {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
#[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
#[doc = concat!("let half_max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX / 2)?;")]
#[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")]
#[doc = concat!("let twenty_seven = NonZero::new(27", stringify!($Int), ")?;")]
#[doc = concat!("let half_max = NonZero::new(", stringify!($Int), "::MAX / 2)?;")]
///
/// assert_eq!(Some(twenty_seven), three.checked_pow(3));
/// assert_eq!(None, half_max.checked_pow(3));
@ -761,24 +764,24 @@ macro_rules! nonzero_integer {
#[doc = sign_dependent_expr!{
$signedness ?
if signed {
concat!("Return [`", stringify!($Ty), "::MIN`] ",
"or [`", stringify!($Ty), "::MAX`] on overflow.")
concat!("Return [`NonZero::<", stringify!($Int), ">::MIN`] ",
"or [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.")
}
if unsigned {
concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")
concat!("Return [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.")
}
}]
///
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
#[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")]
#[doc = concat!("let twenty_seven = NonZero::new(27", stringify!($Int), ")?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(twenty_seven, three.saturating_pow(3));
/// assert_eq!(max, max.saturating_pow(3));
@ -804,7 +807,7 @@ macro_rules! nonzero_integer {
}
#[stable(feature = "nonzero_parse", since = "1.35.0")]
impl FromStr for $Ty {
impl FromStr for NonZero<$Int> {
type Err = ParseIntError;
fn from_str(src: &str) -> Result<Self, Self::Err> {
Self::new(<$Int>::from_str_radix(src, 10)?)
@ -842,56 +845,55 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
// Impls for unsigned nonzero types only.
($Ty:ident unsigned $Int:ty) => {
#[stable(feature = "nonzero_div", since = "1.51.0")]
impl Div<$Ty> for $Int {
impl Div<NonZero<$Int>> for $Int {
type Output = $Int;
/// This operation rounds towards zero,
/// truncating any fractional part of the exact result, and cannot panic.
/// This operation rounds towards zero, truncating any fractional
/// part of the exact result, and cannot panic.
#[inline]
fn div(self, other: $Ty) -> $Int {
// SAFETY: div by zero is checked because `other` is a nonzero,
fn div(self, other: NonZero<$Int>) -> $Int {
// SAFETY: Division by zero is checked because `other` is non-zero,
// and MIN/-1 is checked because `self` is an unsigned int.
unsafe { intrinsics::unchecked_div(self, other.get()) }
}
}
#[stable(feature = "nonzero_div_assign", since = "1.79.0")]
impl DivAssign<$Ty> for $Int {
/// This operation rounds towards zero,
/// truncating any fractional part of the exact result, and cannot panic.
impl DivAssign<NonZero<$Int>> for $Int {
/// This operation rounds towards zero, truncating any fractional
/// part of the exact result, and cannot panic.
#[inline]
fn div_assign(&mut self, other: $Ty) {
fn div_assign(&mut self, other: NonZero<$Int>) {
*self = *self / other;
}
}
#[stable(feature = "nonzero_div", since = "1.51.0")]
impl Rem<$Ty> for $Int {
impl Rem<NonZero<$Int>> for $Int {
type Output = $Int;
/// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
#[inline]
fn rem(self, other: $Ty) -> $Int {
// SAFETY: rem by zero is checked because `other` is a nonzero,
fn rem(self, other: NonZero<$Int>) -> $Int {
// SAFETY: Remainder by zero is checked because `other` is non-zero,
// and MIN/-1 is checked because `self` is an unsigned int.
unsafe { intrinsics::unchecked_rem(self, other.get()) }
}
}
#[stable(feature = "nonzero_div_assign", since = "1.79.0")]
impl RemAssign<$Ty> for $Int {
impl RemAssign<NonZero<$Int>> for $Int {
/// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
#[inline]
fn rem_assign(&mut self, other: $Ty) {
fn rem_assign(&mut self, other: NonZero<$Int>) {
*self = *self % other;
}
}
};
// Impls for signed nonzero types only.
($Ty:ident signed $Int:ty) => {
#[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
impl Neg for $Ty {
impl Neg for NonZero<$Int> {
type Output = Self;
#[inline]
@ -901,7 +903,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
}
}
forward_ref_unop! { impl Neg, neg for $Ty,
forward_ref_unop! { impl Neg, neg for NonZero<$Int>,
#[stable(feature = "signed_nonzero_neg", since = "1.71.0")] }
};
}
@ -920,8 +922,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), 1", stringify!($Int), ");")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MIN.get(), 1", stringify!($Int), ");")]
/// ```
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
pub const MIN: Self = Self::new(1).unwrap();
@ -933,8 +936,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MAX.get(), ", stringify!($Int), "::MAX);")]
/// ```
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
@ -947,13 +951,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(Some(two), one.checked_add(1));
/// assert_eq!(None, max.checked_add(1));
@ -981,18 +985,18 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
}
/// Adds an unsigned integer to a non-zero value.
#[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
#[doc = concat!("Return [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.")]
///
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(two, one.saturating_add(1));
/// assert_eq!(max, max.saturating_add(1));
@ -1027,11 +1031,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// ```
/// #![feature(nonzero_ops)]
///
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
///
/// assert_eq!(two, unsafe { one.unchecked_add(1) });
/// # Some(())
@ -1054,14 +1059,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
#[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")]
#[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(Some(two), two.checked_next_power_of_two() );
/// assert_eq!(Some(four), three.checked_next_power_of_two() );
@ -1094,10 +1099,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().ilog2(), 2);")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().ilog2(), 3);")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().ilog2(), 3);")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::new(7", stringify!($Int), ").unwrap().ilog2(), 2);")]
#[doc = concat!("assert_eq!(NonZero::new(8", stringify!($Int), ").unwrap().ilog2(), 3);")]
#[doc = concat!("assert_eq!(NonZero::new(9", stringify!($Int), ").unwrap().ilog2(), 3);")]
/// ```
#[stable(feature = "int_log", since = "1.67.0")]
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
@ -1118,10 +1124,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().ilog10(), 1);")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().ilog10(), 2);")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().ilog10(), 2);")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::new(99", stringify!($Int), ").unwrap().ilog10(), 1);")]
#[doc = concat!("assert_eq!(NonZero::new(100", stringify!($Int), ").unwrap().ilog10(), 2);")]
#[doc = concat!("assert_eq!(NonZero::new(101", stringify!($Int), ").unwrap().ilog10(), 2);")]
/// ```
#[stable(feature = "int_log", since = "1.67.0")]
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
@ -1142,13 +1149,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
///
/// ```
/// #![feature(num_midpoint)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
#[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
#[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")]
#[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")]
///
/// assert_eq!(one.midpoint(four), two);
/// assert_eq!(four.midpoint(one), two);
@ -1179,9 +1187,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// Basic usage:
///
/// ```
#[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
#[doc = concat!("let eight = std::num::NonZero::new(8", stringify!($Int), ").unwrap();")]
/// assert!(eight.is_power_of_two());
#[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
#[doc = concat!("let ten = std::num::NonZero::new(10", stringify!($Int), ").unwrap();")]
/// assert!(!ten.is_power_of_two());
/// ```
#[must_use]
@ -1202,7 +1210,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
(
Self = $Ty:ident,
Primitive = signed $Int:ident,
UnsignedNonZero = $Uty:ident,
UnsignedPrimitive = $Uint:ty,
) => {
/// The smallest value that can be represented by this non-zero
@ -1216,8 +1223,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), ", stringify!($Int), "::MIN);")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MIN.get(), ", stringify!($Int), "::MIN);")]
/// ```
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
pub const MIN: Self = Self::new(<$Int>::MIN).unwrap();
@ -1233,8 +1241,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Examples
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
/// # use std::num::NonZero;
/// #
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MAX.get(), ", stringify!($Int), "::MAX);")]
/// ```
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
@ -1246,11 +1255,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
#[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")]
///
/// assert_eq!(pos, pos.abs());
/// assert_eq!(pos, neg.abs());
@ -1269,19 +1279,19 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// Checked absolute value.
/// Checks for overflow and returns [`None`] if
#[doc = concat!("`self == ", stringify!($Ty), "::MIN`.")]
#[doc = concat!("`self == NonZero::<", stringify!($Int), ">::MIN`.")]
/// The result cannot be zero.
///
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
///
/// assert_eq!(Some(pos), neg.checked_abs());
/// assert_eq!(None, min.checked_abs());
@ -1309,13 +1319,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
///
/// assert_eq!((pos, false), pos.overflowing_abs());
/// assert_eq!((pos, false), neg.overflowing_abs());
@ -1343,17 +1353,15 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let min_plus = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN + 1)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
#[doc = concat!("let min_plus = NonZero::new(", stringify!($Int), "::MIN + 1)?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(pos, pos.saturating_abs());
/// assert_eq!(pos, neg.saturating_abs());
@ -1378,15 +1386,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("# let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
#[doc = concat!("# let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(pos, pos.wrapping_abs());
/// assert_eq!(pos, neg.wrapping_abs());
@ -1411,18 +1418,15 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("# use std::num::", stringify!($Uty), ";")]
///
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let u_pos = ", stringify!($Uty), "::new(1)?;")]
#[doc = concat!("let i_pos = ", stringify!($Ty), "::new(1)?;")]
#[doc = concat!("let i_neg = ", stringify!($Ty), "::new(-1)?;")]
#[doc = concat!("let i_min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let u_max = ", stringify!($Uty), "::new(",
stringify!($Uint), "::MAX / 2 + 1)?;")]
#[doc = concat!("let u_pos = NonZero::new(1", stringify!($Uint), ")?;")]
#[doc = concat!("let i_pos = NonZero::new(1", stringify!($Int), ")?;")]
#[doc = concat!("let i_neg = NonZero::new(-1", stringify!($Int), ")?;")]
#[doc = concat!("let i_min = NonZero::new(", stringify!($Int), "::MIN)?;")]
#[doc = concat!("let u_max = NonZero::new(", stringify!($Uint), "::MAX / 2 + 1)?;")]
///
/// assert_eq!(u_pos, i_pos.unsigned_abs());
/// assert_eq!(u_pos, i_neg.unsigned_abs());
@ -1435,9 +1439,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn unsigned_abs(self) -> $Uty {
pub const fn unsigned_abs(self) -> NonZero<$Uint> {
// SAFETY: absolute value of nonzero cannot yield zero values.
unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
unsafe { NonZero::new_unchecked(self.get().unsigned_abs()) }
}
/// Returns `true` if `self` is positive and `false` if the
@ -1446,11 +1450,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
#[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")]
#[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")]
///
/// assert!(pos_five.is_positive());
/// assert!(!neg_five.is_positive());
@ -1471,11 +1476,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
#[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")]
#[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")]
///
/// assert!(neg_five.is_negative());
/// assert!(!pos_five.is_negative());
@ -1491,18 +1497,18 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
}
/// Checked negation. Computes `-self`,
#[doc = concat!("returning `None` if `self == ", stringify!($Ty), "::MIN`.")]
#[doc = concat!("returning `None` if `self == NonZero::<", stringify!($Int), ">::MIN`.")]
///
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")]
#[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
///
/// assert_eq!(pos_five.checked_neg(), Some(neg_five));
/// assert_eq!(min.checked_neg(), None);
@ -1528,13 +1534,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")]
#[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
///
/// assert_eq!(pos_five.overflowing_neg(), (neg_five, false));
/// assert_eq!(min.overflowing_neg(), (min, true));
@ -1551,24 +1557,22 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
}
/// Saturating negation. Computes `-self`,
#[doc = concat!("returning [`", stringify!($Ty), "::MAX`]")]
#[doc = concat!("if `self == ", stringify!($Ty), "::MIN`")]
#[doc = concat!("returning [`NonZero::<", stringify!($Int), ">::MAX`]")]
#[doc = concat!("if `self == NonZero::<", stringify!($Int), ">::MIN`")]
/// instead of overflowing.
///
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN + 1)?;")]
#[doc = concat!("let max = ", stringify!($Ty), "::new(",
stringify!($Int), "::MAX)?;")]
#[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")]
#[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
#[doc = concat!("let min_plus_one = NonZero::new(", stringify!($Int), "::MIN + 1)?;")]
#[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")]
///
/// assert_eq!(pos_five.saturating_neg(), neg_five);
/// assert_eq!(min.saturating_neg(), max);
@ -1595,13 +1599,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
/// # Example
///
/// ```
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
#[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
#[doc = concat!("let min = ", stringify!($Ty), "::new(",
stringify!($Int), "::MIN)?;")]
#[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")]
#[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")]
#[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")]
///
/// assert_eq!(pos_five.wrapping_neg(), neg_five);
/// assert_eq!(min.wrapping_neg(), min);
@ -1662,41 +1666,35 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroI8,
Primitive = signed i8,
UnsignedNonZero = NonZeroU8,
UnsignedPrimitive = u8,
}
nonzero_integer! {
Self = NonZeroI16,
Primitive = signed i16,
UnsignedNonZero = NonZeroU16,
UnsignedPrimitive = u16,
}
nonzero_integer! {
Self = NonZeroI32,
Primitive = signed i32,
UnsignedNonZero = NonZeroU32,
UnsignedPrimitive = u32,
}
nonzero_integer! {
Self = NonZeroI64,
Primitive = signed i64,
UnsignedNonZero = NonZeroU64,
UnsignedPrimitive = u64,
}
nonzero_integer! {
Self = NonZeroI128,
Primitive = signed i128,
UnsignedNonZero = NonZeroU128,
UnsignedPrimitive = u128,
}
nonzero_integer! {
Self = NonZeroIsize,
Primitive = signed isize,
UnsignedNonZero = NonZeroUsize,
UnsignedPrimitive = usize,
}

View File

@ -236,7 +236,7 @@ fn main() {
let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") {
num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS")
} else {
std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get)
std::thread::available_parallelism().map_or(1, std::num::NonZero::get)
};
rayon::ThreadPoolBuilder::new()
.num_threads(num_threads)

View File

@ -87,7 +87,7 @@ pub(super) fn check<'tcx>(
&& is_normalizable(cx, cx.param_env, from_ty)
&& is_normalizable(cx, cx.param_env, to_ty)
// we only want to lint if the target type has a niche that is larger than the one of the source type
// e.g. `u8` to `NonZeroU8` should lint, but `NonZeroU8` to `u8` should not
// e.g. `u8` to `NonZero<u8>` should lint, but `NonZero<u8>` to `u8` should not
&& let Ok(from_layout) = cx.tcx.layout_of(cx.param_env.and(from_ty))
&& let Ok(to_layout) = cx.tcx.layout_of(cx.param_env.and(to_ty))
&& match (from_layout.largest_niche, to_layout.largest_niche) {

View File

@ -257,7 +257,7 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
/// Checks for transmutes from integers to `NonZero*` types, and suggests their `new_unchecked`
/// Checks for transmutes from `T` to `NonZero<T>`, and suggests the `new_unchecked`
/// method instead.
///
/// ### Why is this bad?
@ -266,13 +266,13 @@ declare_clippy_lint! {
///
/// ### Example
/// ```no_run
/// # use core::num::NonZeroU32;
/// let _non_zero: NonZeroU32 = unsafe { std::mem::transmute(123) };
/// # use core::num::NonZero;
/// let _: NonZero<u32> = unsafe { std::mem::transmute(123) };
/// ```
/// Use instead:
/// ```no_run
/// # use core::num::NonZeroU32;
/// let _non_zero = unsafe { NonZeroU32::new_unchecked(123) };
/// # use core::num::NonZero;
/// let _: NonZero<u32> = unsafe { NonZero::new_unchecked(123) };
/// ```
#[clippy::version = "1.69.0"]
pub TRANSMUTE_INT_TO_NON_ZERO,

View File

@ -26,45 +26,22 @@ pub(super) fn check<'tcx>(
return false;
};
// FIXME: This can be simplified once `NonZero<T>` is stable.
let coercible_types = [
("NonZeroU8", tcx.types.u8),
("NonZeroU16", tcx.types.u16),
("NonZeroU32", tcx.types.u32),
("NonZeroU64", tcx.types.u64),
("NonZeroU128", tcx.types.u128),
("NonZeroUsize", tcx.types.usize),
("NonZeroI8", tcx.types.i8),
("NonZeroI16", tcx.types.i16),
("NonZeroI32", tcx.types.i32),
("NonZeroI64", tcx.types.i64),
("NonZeroI128", tcx.types.i128),
("NonZeroIsize", tcx.types.isize),
];
let int_type = substs.type_at(0);
let Some(nonzero_alias) = coercible_types.iter().find_map(|(nonzero_alias, t)| {
if *t == int_type && *t == from_ty {
Some(nonzero_alias)
} else {
None
}
}) else {
return false;
};
let int_ty = substs.type_at(0);
if from_ty != int_ty {
return false;
}
span_lint_and_then(
cx,
TRANSMUTE_INT_TO_NON_ZERO,
e.span,
format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
format!("transmute from a `{from_ty}` to a `{}<{int_ty}>`", sym::NonZero),
|diag| {
let arg = sugg::Sugg::hir(cx, arg, "..");
diag.span_suggestion(
e.span,
"consider using",
format!("{nonzero_alias}::{}({arg})", sym::new_unchecked),
format!("{}::{}({arg})", sym::NonZero, sym::new_unchecked),
Applicability::Unspecified,
);
},

View File

@ -1,5 +1,5 @@
use clap::Parser;
use std::num::NonZeroUsize;
use std::num::NonZero;
use std::path::PathBuf;
#[derive(Clone, Debug, Parser)]
@ -61,7 +61,7 @@ impl LintcheckConfig {
config.max_jobs = if config.fix || config.recursive {
1
} else {
std::thread::available_parallelism().map_or(1, NonZeroUsize::get)
std::thread::available_parallelism().map_or(1, NonZero::get)
};
};

View File

@ -15,7 +15,7 @@
extern crate proc_macro_derive;
use core::num::{NonZeroUsize, Saturating, Wrapping};
use core::num::{NonZero, Saturating, Wrapping};
const ONE: i32 = 1;
const ZERO: i32 = 0;
@ -494,15 +494,15 @@ pub fn issue_11262() {
}
pub fn issue_11392() {
fn example_div(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize {
fn example_div(unsigned: usize, nonzero_unsigned: NonZero<usize>) -> usize {
unsigned / nonzero_unsigned
}
fn example_rem(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize {
fn example_rem(unsigned: usize, nonzero_unsigned: NonZero<usize>) -> usize {
unsigned % nonzero_unsigned
}
let (unsigned, nonzero_unsigned) = (0, NonZeroUsize::new(1).unwrap());
let (unsigned, nonzero_unsigned) = (0, NonZero::new(1).unwrap());
example_div(unsigned, nonzero_unsigned);
example_rem(unsigned, nonzero_unsigned);
}

View File

@ -2,7 +2,7 @@
#![warn(clippy::eager_transmute)]
#![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)]
use std::num::NonZeroU8;
use std::num::NonZero;
#[repr(u8)]
enum Opcode {
@ -85,21 +85,21 @@ macro_rules! impls {
}
impls!(NonMaxU8, NonZeroNonMaxU8);
fn niche_tests(v1: u8, v2: NonZeroU8, v3: NonZeroNonMaxU8) {
// u8 -> NonZeroU8, do lint
let _: Option<NonZeroU8> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });
fn niche_tests(v1: u8, v2: NonZero<u8>, v3: NonZeroNonMaxU8) {
// u8 -> NonZero<u8>, do lint
let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });
// NonZeroU8 -> u8, don't lint, target type has no niche and therefore a higher validity range
let _: Option<u8> = (v2 > NonZeroU8::new(1).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZero<u8> -> u8, don't lint, target type has no niche and therefore a higher validity range
let _: Option<u8> = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZeroU8 -> NonMaxU8, do lint, different niche
let _: Option<NonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
// NonZero<u8> -> NonMaxU8, do lint, different niche
let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
// NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity
let _: Option<NonMaxU8> = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) });
// NonZeroU8 -> NonZeroNonMaxU8, do lint, target type has less validity
let _: Option<NonZeroNonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
// NonZero<u8> -> NonZeroNonMaxU8, do lint, target type has less validity
let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
}
fn main() {}

View File

@ -2,7 +2,7 @@
#![warn(clippy::eager_transmute)]
#![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)]
use std::num::NonZeroU8;
use std::num::NonZero;
#[repr(u8)]
enum Opcode {
@ -85,21 +85,21 @@ macro_rules! impls {
}
impls!(NonMaxU8, NonZeroNonMaxU8);
fn niche_tests(v1: u8, v2: NonZeroU8, v3: NonZeroNonMaxU8) {
// u8 -> NonZeroU8, do lint
let _: Option<NonZeroU8> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });
fn niche_tests(v1: u8, v2: NonZero<u8>, v3: NonZeroNonMaxU8) {
// u8 -> NonZero<u8>, do lint
let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });
// NonZeroU8 -> u8, don't lint, target type has no niche and therefore a higher validity range
let _: Option<u8> = (v2 > NonZeroU8::new(1).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZero<u8> -> u8, don't lint, target type has no niche and therefore a higher validity range
let _: Option<u8> = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZeroU8 -> NonMaxU8, do lint, different niche
let _: Option<NonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZero<u8> -> NonMaxU8, do lint, different niche
let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity
let _: Option<NonMaxU8> = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) });
// NonZeroU8 -> NonZeroNonMaxU8, do lint, target type has less validity
let _: Option<NonZeroNonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
// NonZero<u8> -> NonZeroNonMaxU8, do lint, target type has less validity
let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
}
fn main() {}

View File

@ -155,36 +155,36 @@ LL | (op < 4).then(|| std::mem::transmute::<_, Opcode>(op));
| ~~~~ ++
error: this transmute is always evaluated eagerly, even if the condition is false
--> tests/ui/eager_transmute.rs:90:60
--> tests/ui/eager_transmute.rs:90:62
|
LL | let _: Option<NonZeroU8> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });
| ^^^^^^^^^^^^^^^^^^^^^^^
LL | let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider using `bool::then` to only transmute if the condition holds
|
LL | let _: Option<NonZeroU8> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });
| ~~~~ ++
LL | let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });
| ~~~~ ++
error: this transmute is always evaluated eagerly, even if the condition is false
--> tests/ui/eager_transmute.rs:96:86
|
LL | let _: Option<NonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
LL | let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider using `bool::then` to only transmute if the condition holds
|
LL | let _: Option<NonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
LL | let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
| ~~~~ ++
error: this transmute is always evaluated eagerly, even if the condition is false
--> tests/ui/eager_transmute.rs:102:93
|
LL | let _: Option<NonZeroNonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
LL | let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider using `bool::then` to only transmute if the condition holds
|
LL | let _: Option<NonZeroNonMaxU8> = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
LL | let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
| ~~~~ ++
error: aborting due to 17 previous errors

View File

@ -1,7 +1,7 @@
#![warn(clippy::transmute_int_to_non_zero)]
#![allow(clippy::missing_transmute_annotations)]
use core::num::*;
use core::num::NonZero;
fn main() {
let int_u8: u8 = 1;
@ -16,38 +16,38 @@ fn main() {
let int_i64: i64 = 1;
let int_i128: i128 = 1;
let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) };
//~^ ERROR: transmute from a `u8` to a `NonZeroU8`
let _: NonZero<u8> = unsafe { NonZero::new_unchecked(int_u8) };
//~^ ERROR: transmute from a `u8` to a `NonZero<u8>`
//~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`
let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) };
//~^ ERROR: transmute from a `u16` to a `NonZeroU16`
let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) };
//~^ ERROR: transmute from a `u32` to a `NonZeroU32`
let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) };
//~^ ERROR: transmute from a `u64` to a `NonZeroU64`
let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) };
//~^ ERROR: transmute from a `u128` to a `NonZeroU128`
let _: NonZero<u16> = unsafe { NonZero::new_unchecked(int_u16) };
//~^ ERROR: transmute from a `u16` to a `NonZero<u16>`
let _: NonZero<u32> = unsafe { NonZero::new_unchecked(int_u32) };
//~^ ERROR: transmute from a `u32` to a `NonZero<u32>`
let _: NonZero<u64> = unsafe { NonZero::new_unchecked(int_u64) };
//~^ ERROR: transmute from a `u64` to a `NonZero<u64>`
let _: NonZero<u128> = unsafe { NonZero::new_unchecked(int_u128) };
//~^ ERROR: transmute from a `u128` to a `NonZero<u128>`
let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) };
//~^ ERROR: transmute from a `i8` to a `NonZeroI8`
let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) };
//~^ ERROR: transmute from a `i16` to a `NonZeroI16`
let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) };
//~^ ERROR: transmute from a `i32` to a `NonZeroI32`
let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) };
//~^ ERROR: transmute from a `i64` to a `NonZeroI64`
let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) };
//~^ ERROR: transmute from a `i128` to a `NonZeroI128`
let _: NonZero<i8> = unsafe { NonZero::new_unchecked(int_i8) };
//~^ ERROR: transmute from a `i8` to a `NonZero<i8>`
let _: NonZero<i16> = unsafe { NonZero::new_unchecked(int_i16) };
//~^ ERROR: transmute from a `i16` to a `NonZero<i16>`
let _: NonZero<i32> = unsafe { NonZero::new_unchecked(int_i32) };
//~^ ERROR: transmute from a `i32` to a `NonZero<i32>`
let _: NonZero<i64> = unsafe { NonZero::new_unchecked(int_i64) };
//~^ ERROR: transmute from a `i64` to a `NonZero<i64>`
let _: NonZero<i128> = unsafe { NonZero::new_unchecked(int_i128) };
//~^ ERROR: transmute from a `i128` to a `NonZero<i128>`
let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) };
let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) };
let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) };
let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) };
let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) };
let _: NonZero<u8> = unsafe { NonZero::new_unchecked(int_u8) };
let _: NonZero<u16> = unsafe { NonZero::new_unchecked(int_u16) };
let _: NonZero<u32> = unsafe { NonZero::new_unchecked(int_u32) };
let _: NonZero<u64> = unsafe { NonZero::new_unchecked(int_u64) };
let _: NonZero<u128> = unsafe { NonZero::new_unchecked(int_u128) };
let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) };
let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) };
let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) };
let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) };
let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) };
let _: NonZero<i8> = unsafe { NonZero::new_unchecked(int_i8) };
let _: NonZero<i16> = unsafe { NonZero::new_unchecked(int_i16) };
let _: NonZero<i32> = unsafe { NonZero::new_unchecked(int_i32) };
let _: NonZero<i64> = unsafe { NonZero::new_unchecked(int_i64) };
let _: NonZero<i128> = unsafe { NonZero::new_unchecked(int_i128) };
}

View File

@ -1,7 +1,7 @@
#![warn(clippy::transmute_int_to_non_zero)]
#![allow(clippy::missing_transmute_annotations)]
use core::num::*;
use core::num::NonZero;
fn main() {
let int_u8: u8 = 1;
@ -16,38 +16,38 @@ fn main() {
let int_i64: i64 = 1;
let int_i128: i128 = 1;
let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) };
//~^ ERROR: transmute from a `u8` to a `NonZeroU8`
let _: NonZero<u8> = unsafe { std::mem::transmute(int_u8) };
//~^ ERROR: transmute from a `u8` to a `NonZero<u8>`
//~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`
let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) };
//~^ ERROR: transmute from a `u16` to a `NonZeroU16`
let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) };
//~^ ERROR: transmute from a `u32` to a `NonZeroU32`
let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) };
//~^ ERROR: transmute from a `u64` to a `NonZeroU64`
let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) };
//~^ ERROR: transmute from a `u128` to a `NonZeroU128`
let _: NonZero<u16> = unsafe { std::mem::transmute(int_u16) };
//~^ ERROR: transmute from a `u16` to a `NonZero<u16>`
let _: NonZero<u32> = unsafe { std::mem::transmute(int_u32) };
//~^ ERROR: transmute from a `u32` to a `NonZero<u32>`
let _: NonZero<u64> = unsafe { std::mem::transmute(int_u64) };
//~^ ERROR: transmute from a `u64` to a `NonZero<u64>`
let _: NonZero<u128> = unsafe { std::mem::transmute(int_u128) };
//~^ ERROR: transmute from a `u128` to a `NonZero<u128>`
let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) };
//~^ ERROR: transmute from a `i8` to a `NonZeroI8`
let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) };
//~^ ERROR: transmute from a `i16` to a `NonZeroI16`
let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) };
//~^ ERROR: transmute from a `i32` to a `NonZeroI32`
let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) };
//~^ ERROR: transmute from a `i64` to a `NonZeroI64`
let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) };
//~^ ERROR: transmute from a `i128` to a `NonZeroI128`
let _: NonZero<i8> = unsafe { std::mem::transmute(int_i8) };
//~^ ERROR: transmute from a `i8` to a `NonZero<i8>`
let _: NonZero<i16> = unsafe { std::mem::transmute(int_i16) };
//~^ ERROR: transmute from a `i16` to a `NonZero<i16>`
let _: NonZero<i32> = unsafe { std::mem::transmute(int_i32) };
//~^ ERROR: transmute from a `i32` to a `NonZero<i32>`
let _: NonZero<i64> = unsafe { std::mem::transmute(int_i64) };
//~^ ERROR: transmute from a `i64` to a `NonZero<i64>`
let _: NonZero<i128> = unsafe { std::mem::transmute(int_i128) };
//~^ ERROR: transmute from a `i128` to a `NonZero<i128>`
let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) };
let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) };
let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) };
let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) };
let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) };
let _: NonZero<u8> = unsafe { NonZero::new_unchecked(int_u8) };
let _: NonZero<u16> = unsafe { NonZero::new_unchecked(int_u16) };
let _: NonZero<u32> = unsafe { NonZero::new_unchecked(int_u32) };
let _: NonZero<u64> = unsafe { NonZero::new_unchecked(int_u64) };
let _: NonZero<u128> = unsafe { NonZero::new_unchecked(int_u128) };
let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) };
let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) };
let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) };
let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) };
let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) };
let _: NonZero<i8> = unsafe { NonZero::new_unchecked(int_i8) };
let _: NonZero<i16> = unsafe { NonZero::new_unchecked(int_i16) };
let _: NonZero<i32> = unsafe { NonZero::new_unchecked(int_i32) };
let _: NonZero<i64> = unsafe { NonZero::new_unchecked(int_i64) };
let _: NonZero<i128> = unsafe { NonZero::new_unchecked(int_i128) };
}

View File

@ -1,65 +1,65 @@
error: transmute from a `u8` to a `NonZeroU8`
--> tests/ui/transmute_int_to_non_zero.rs:19:33
error: transmute from a `u8` to a `NonZero<u8>`
--> tests/ui/transmute_int_to_non_zero.rs:19:35
|
LL | let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU8::new_unchecked(int_u8)`
LL | let _: NonZero<u8> = unsafe { std::mem::transmute(int_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u8)`
|
= note: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]`
error: transmute from a `u16` to a `NonZeroU16`
--> tests/ui/transmute_int_to_non_zero.rs:22:34
error: transmute from a `u16` to a `NonZero<u16>`
--> tests/ui/transmute_int_to_non_zero.rs:22:36
|
LL | let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU16::new_unchecked(int_u16)`
LL | let _: NonZero<u16> = unsafe { std::mem::transmute(int_u16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u16)`
error: transmute from a `u32` to a `NonZeroU32`
--> tests/ui/transmute_int_to_non_zero.rs:24:34
error: transmute from a `u32` to a `NonZero<u32>`
--> tests/ui/transmute_int_to_non_zero.rs:24:36
|
LL | let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU32::new_unchecked(int_u32)`
LL | let _: NonZero<u32> = unsafe { std::mem::transmute(int_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u32)`
error: transmute from a `u64` to a `NonZeroU64`
--> tests/ui/transmute_int_to_non_zero.rs:26:34
error: transmute from a `u64` to a `NonZero<u64>`
--> tests/ui/transmute_int_to_non_zero.rs:26:36
|
LL | let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU64::new_unchecked(int_u64)`
LL | let _: NonZero<u64> = unsafe { std::mem::transmute(int_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u64)`
error: transmute from a `u128` to a `NonZeroU128`
--> tests/ui/transmute_int_to_non_zero.rs:28:35
error: transmute from a `u128` to a `NonZero<u128>`
--> tests/ui/transmute_int_to_non_zero.rs:28:37
|
LL | let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU128::new_unchecked(int_u128)`
LL | let _: NonZero<u128> = unsafe { std::mem::transmute(int_u128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u128)`
error: transmute from a `i8` to a `NonZeroI8`
--> tests/ui/transmute_int_to_non_zero.rs:31:33
error: transmute from a `i8` to a `NonZero<i8>`
--> tests/ui/transmute_int_to_non_zero.rs:31:35
|
LL | let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI8::new_unchecked(int_i8)`
LL | let _: NonZero<i8> = unsafe { std::mem::transmute(int_i8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i8)`
error: transmute from a `i16` to a `NonZeroI16`
--> tests/ui/transmute_int_to_non_zero.rs:33:34
error: transmute from a `i16` to a `NonZero<i16>`
--> tests/ui/transmute_int_to_non_zero.rs:33:36
|
LL | let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI16::new_unchecked(int_i16)`
LL | let _: NonZero<i16> = unsafe { std::mem::transmute(int_i16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i16)`
error: transmute from a `i32` to a `NonZeroI32`
--> tests/ui/transmute_int_to_non_zero.rs:35:34
error: transmute from a `i32` to a `NonZero<i32>`
--> tests/ui/transmute_int_to_non_zero.rs:35:36
|
LL | let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI32::new_unchecked(int_i32)`
LL | let _: NonZero<i32> = unsafe { std::mem::transmute(int_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i32)`
error: transmute from a `i64` to a `NonZeroI64`
--> tests/ui/transmute_int_to_non_zero.rs:37:34
error: transmute from a `i64` to a `NonZero<i64>`
--> tests/ui/transmute_int_to_non_zero.rs:37:36
|
LL | let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI64::new_unchecked(int_i64)`
LL | let _: NonZero<i64> = unsafe { std::mem::transmute(int_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i64)`
error: transmute from a `i128` to a `NonZeroI128`
--> tests/ui/transmute_int_to_non_zero.rs:39:35
error: transmute from a `i128` to a `NonZero<i128>`
--> tests/ui/transmute_int_to_non_zero.rs:39:37
|
LL | let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI128::new_unchecked(int_i128)`
LL | let _: NonZero<i128> = unsafe { std::mem::transmute(int_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i128)`
error: aborting due to 10 previous errors

View File

@ -2,7 +2,7 @@
#![feature(custom_mir)]
use std::intrinsics::mir::*;
use std::num::NonZeroI32;
use std::num::NonZero;
// We define our own option type so that we can control the variant indices.
#[allow(unused)]
@ -13,7 +13,7 @@ enum Option<T> {
use Option::*;
#[custom_mir(dialect = "runtime", phase = "optimized")]
fn set_discriminant(ptr: &mut Option<NonZeroI32>) {
fn set_discriminant(ptr: &mut Option<NonZero<i32>>) {
mir! {
{
// We set the discriminant to `Some`, which is a NOP since this is the niched variant.

View File

@ -1,7 +1,7 @@
use std::num::*;
use std::num::NonZero;
#[repr(C)]
struct S1(NonZeroI32);
struct S1(NonZero<i32>);
#[repr(C)]
struct S2(i32);
@ -11,6 +11,6 @@ fn callee(_s: S2) {}
fn main() {
let fnptr: fn(S2) = callee;
let fnptr: fn(S1) = unsafe { std::mem::transmute(fnptr) };
fnptr(S1(NonZeroI32::new(1).unwrap()));
fnptr(S1(NonZero::new(1).unwrap()));
//~^ ERROR: calling a function with argument of type S2 passing data of type S1
}

View File

@ -1,8 +1,8 @@
error: Undefined Behavior: calling a function with argument of type S2 passing data of type S1
--> $DIR/abi_mismatch_repr_C.rs:LL:CC
|
LL | fnptr(S1(NonZeroI32::new(1).unwrap()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a function with argument of type S2 passing data of type S1
LL | fnptr(S1(NonZero::new(1).unwrap()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a function with argument of type S2 passing data of type S1
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

View File

@ -2,15 +2,15 @@
#![feature(core_intrinsics, custom_mir)]
use std::intrinsics::mir::*;
use std::num::NonZeroU32;
use std::num::NonZero;
use std::ptr;
// This function supposedly returns a NonZeroU32, but actually returns something invalid in a way that
// never materializes a bad NonZeroU32 value: we take a pointer to the return place and cast the pointer
// This function supposedly returns a `NonZero<u32>`, but actually returns something invalid in a way that
// never materializes a bad `NonZero<u32>` value: we take a pointer to the return place and cast the pointer
// type. That way we never get an "invalid value constructed" error inside the function, it can
// only possibly be detected when the return value is passed to the caller.
#[custom_mir(dialect = "runtime", phase = "optimized")]
fn f() -> NonZeroU32 {
fn f() -> NonZero<u32> {
mir! {
{
let tmp = ptr::addr_of_mut!(RET);
@ -22,7 +22,7 @@ fn f() -> NonZeroU32 {
}
fn main() {
let f: fn() -> u32 = unsafe { std::mem::transmute(f as fn() -> NonZeroU32) };
// There's a NonZeroU32-to-u32 transmute happening here
let f: fn() -> u32 = unsafe { std::mem::transmute(f as fn() -> NonZero<u32>) };
// There's a `NonZero<u32>` to `u32` transmute happening here.
f(); //~ERROR: expected something greater or equal to 1
}

View File

@ -2,24 +2,24 @@
#![feature(core_intrinsics, custom_mir)]
use std::intrinsics::mir::*;
use std::num::NonZeroU32;
use std::num::NonZero;
use std::ptr;
fn f(c: u32) {
println!("{c}");
}
// Call that function in a bad way, with an invalid NonZeroU32, but without
// ever materializing this as a NonZeroU32 value outside the call itself.
// Call that function in a bad way, with an invalid `NonZero<u32>`, but without
// ever materializing this as a `NonZero<u32>` value outside the call itself.
#[custom_mir(dialect = "runtime", phase = "optimized")]
fn call(f: fn(NonZeroU32)) {
fn call(f: fn(NonZero<u32>)) {
mir! {
let _res: ();
{
let c = 0;
let tmp = ptr::addr_of!(c);
let ptr = tmp as *const NonZeroU32;
// The call site now is a NonZeroU32-to-u32 transmute.
let ptr = tmp as *const NonZero<u32>;
// The call site now is a `NonZero<u32>` to `u32` transmute.
Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) //~ERROR: expected something greater or equal to 1
}
retblock = {
@ -29,6 +29,6 @@ fn call(f: fn(NonZeroU32)) {
}
fn main() {
let f: fn(NonZeroU32) = unsafe { std::mem::transmute(f as fn(u32)) };
let f: fn(NonZero<u32>) = unsafe { std::mem::transmute(f as fn(u32)) };
call(f);
}

View File

@ -70,7 +70,7 @@ fn main() {
test_abi_compat(0usize, 0u64);
test_abi_compat(0isize, 0i64);
}
test_abi_compat(42u32, num::NonZeroU32::new(1).unwrap());
test_abi_compat(42u32, num::NonZero::new(1u32).unwrap());
// - `char` and `u32`.
test_abi_compat(42u32, 'x');
// - Reference/pointer types with the same pointee.
@ -86,9 +86,9 @@ fn main() {
// - Guaranteed null-pointer-optimizations (RFC 3391).
test_abi_compat(&0u32 as *const u32, Some(&0u32));
test_abi_compat(main as fn(), Some(main as fn()));
test_abi_compat(0u32, Some(num::NonZeroU32::new(1).unwrap()));
test_abi_compat(0u32, Some(num::NonZero::new(1u32).unwrap()));
test_abi_compat(&0u32 as *const u32, Some(Wrapper(&0u32)));
test_abi_compat(0u32, Some(Wrapper(num::NonZeroU32::new(1).unwrap())));
test_abi_compat(0u32, Some(Wrapper(num::NonZero::new(1u32).unwrap())));
// These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible
// with the wrapped field.
@ -102,7 +102,7 @@ fn main() {
test_abi_newtype::<[u32; 2]>();
test_abi_newtype::<[u32; 32]>();
test_abi_newtype::<Option<i32>>();
test_abi_newtype::<Option<num::NonZeroU32>>();
test_abi_newtype::<Option<num::NonZero<u32>>>();
// Extra test for assumptions made by arbitrary-self-dyn-receivers.
// This is interesting since these types are not `repr(transparent)`. So this is not part of our

View File

@ -1,8 +1,8 @@
//@compile-flags: -Zmiri-num-cpus=1024
use std::num::NonZeroUsize;
use std::num::NonZero;
use std::thread::available_parallelism;
fn main() {
assert_eq!(available_parallelism().unwrap(), NonZeroUsize::new(1024).unwrap());
assert_eq!(available_parallelism().unwrap(), NonZero::new(1024).unwrap());
}

View File

@ -1,5 +1,5 @@
use std::ffi::OsString;
use std::num::NonZeroUsize;
use std::num::NonZero;
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use std::{env, process::Command};
@ -76,7 +76,7 @@ fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
edition: Some("2021".into()), // keep in sync with `./miri run`
threads: std::env::var("MIRI_TEST_THREADS")
.ok()
.map(|threads| NonZeroUsize::new(threads.parse().unwrap()).unwrap()),
.map(|threads| NonZero::new(threads.parse().unwrap()).unwrap()),
..Config::rustc(path)
};

View File

@ -99,7 +99,7 @@ fn check_result(abi: &ArgAbi) {
assert_matches!(layout.variants, VariantsShape::Multiple { .. })
}
/// Check the niche information about: `NonZeroU8`
/// Checks the niche information about `NonZero<u8>`.
fn check_niche(abi: &ArgAbi) {
assert!(abi.ty.kind().is_struct());
assert_matches!(abi.mode, PassMode::Direct { .. });
@ -150,12 +150,12 @@ fn generate_input(path: &str) -> std::io::Result<()> {
#![feature(c_variadic)]
#![allow(unused_variables)]
use std::num::NonZeroU8;
use std::num::NonZero;
pub fn fn_abi(
ignore: [u8; 0],
primitive: char,
niche: NonZeroU8,
niche: NonZero<u8>,
) -> Result<usize, &'static str> {{
// We only care about the signature.
todo!()

View File

@ -1,9 +1,9 @@
fn main() {
let _: std::num::NonZeroU64 = 1;
let _: std::num::NonZero<u64> = 1;
//~^ ERROR mismatched types
//~| HELP consider calling `NonZeroU64::new`
//~| HELP consider calling `NonZero::new`
let _: Option<std::num::NonZeroU64> = 1;
let _: Option<std::num::NonZero<u64>> = 1;
//~^ ERROR mismatched types
//~| HELP consider calling `NonZeroU64::new`
//~| HELP consider calling `NonZero::new`
}

View File

@ -1,32 +1,32 @@
error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:2:35
--> $DIR/non_zero_assigned_something.rs:2:37
|
LL | let _: std::num::NonZeroU64 = 1;
| -------------------- ^ expected `NonZero<u64>`, found integer
LL | let _: std::num::NonZero<u64> = 1;
| ---------------------- ^ expected `NonZero<u64>`, found integer
| |
| expected due to this
|
= note: expected struct `NonZero<u64>`
found type `{integer}`
help: consider calling `NonZeroU64::new`
help: consider calling `NonZero::new`
|
LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap();
| ++++++++++++++++ ++++++++++
LL | let _: std::num::NonZero<u64> = NonZero::new(1).unwrap();
| +++++++++++++ ++++++++++
error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:6:43
--> $DIR/non_zero_assigned_something.rs:6:45
|
LL | let _: Option<std::num::NonZeroU64> = 1;
| ---------------------------- ^ expected `Option<NonZero<u64>>`, found integer
LL | let _: Option<std::num::NonZero<u64>> = 1;
| ------------------------------ ^ expected `Option<NonZero<u64>>`, found integer
| |
| expected due to this
|
= note: expected enum `Option<NonZero<u64>>`
found type `{integer}`
help: consider calling `NonZeroU64::new`
help: consider calling `NonZero::new`
|
LL | let _: Option<std::num::NonZeroU64> = NonZeroU64::new(1);
| ++++++++++++++++ +
LL | let _: Option<std::num::NonZero<u64>> = NonZero::new(1);
| +++++++++++++ +
error: aborting due to 2 previous errors

View File

@ -8,7 +8,7 @@
use std::pat::pattern_type;
type X = std::num::NonZeroU32;
type X = std::num::NonZero<u32>;
type Y = pattern_type!(u32 is 1..);
type Z = Option<pattern_type!(u32 is 1..)>;
struct NonZeroU32New(pattern_type!(u32 is 1..));