diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 2defca54aff24..3e20ec49f5710 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -980,43 +980,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_ty: Ty<'tcx>, ) -> bool { let tcx = self.tcx; - let (adt, unwrap) = match expected.kind() { + let (adt, substs, unwrap) = match expected.kind() { // In case Option is wanted, but * is provided, suggest calling new ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { - // Unwrap option - let ty::Adt(adt, _) = substs.type_at(0).kind() else { return false; }; - - (adt, "") + let nonzero_type = substs.type_at(0); // Unwrap option type. + let ty::Adt(adt, substs) = nonzero_type.kind() else { return false; }; + (adt, substs, "") } - // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types - ty::Adt(adt, _) => (adt, ".unwrap()"), + // In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types. + ty::Adt(adt, substs) => (adt, substs, ".unwrap()"), _ => return false, }; - let map = [ - (sym::NonZeroU8, tcx.types.u8), - (sym::NonZeroU16, tcx.types.u16), - (sym::NonZeroU32, tcx.types.u32), - (sym::NonZeroU64, tcx.types.u64), - (sym::NonZeroU128, tcx.types.u128), - (sym::NonZeroI8, tcx.types.i8), - (sym::NonZeroI16, tcx.types.i16), - (sym::NonZeroI32, tcx.types.i32), - (sym::NonZeroI64, tcx.types.i64), - (sym::NonZeroI128, tcx.types.i128), + if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) { + return false; + } + + 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 Some((s, _)) = map + let int_type = substs.type_at(0); + + let Some(nonzero_alias) = coercable_types .iter() - .find(|&&(s, t)| self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t)) + .find_map(|(nonzero_alias, t)| { + if *t == int_type && self.can_coerce(expr_ty, *t) { + Some(nonzero_alias) + } else { + None + } + }) else { return false; }; - let path = self.tcx.def_path_str(adt.non_enum_variant().def_id); - err.multipart_suggestion( - format!("consider calling `{s}::new`"), + format!("consider calling `{nonzero_alias}::new`"), vec![ - (expr.span.shrink_to_lo(), format!("{path}::new(")), + (expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")), (expr.span.shrink_to_hi(), format!("){unwrap}")), ], Applicability::MaybeIncorrect, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 60efcb768cb07..04630a5e8aa83 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -226,16 +226,7 @@ symbols! { Mutex, MutexGuard, N, - NonZeroI128, - NonZeroI16, - NonZeroI32, - NonZeroI64, - NonZeroI8, - NonZeroU128, - NonZeroU16, - NonZeroU32, - NonZeroU64, - NonZeroU8, + NonZero, None, Ok, Option, diff --git a/library/core/src/cmp/bytewise.rs b/library/core/src/cmp/bytewise.rs index 2548d9e24c9db..e51096230f9fe 100644 --- a/library/core/src/cmp/bytewise.rs +++ b/library/core/src/cmp/bytewise.rs @@ -1,5 +1,4 @@ -use crate::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize}; -use crate::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; +use crate::num::NonZero; /// Types where `==` & `!=` are equivalent to comparing their underlying bytes. /// @@ -36,18 +35,18 @@ is_bytewise_comparable!(bool, char, super::Ordering); // SAFETY: Similarly, the non-zero types have a niche, but no undef and no pointers, // and they compare like their underlying numeric type. is_bytewise_comparable!( - NonZeroU8, - NonZeroU16, - NonZeroU32, - NonZeroU64, - NonZeroU128, - NonZeroUsize, - NonZeroI8, - NonZeroI16, - NonZeroI32, - NonZeroI64, - NonZeroI128, - NonZeroIsize, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, + NonZero, ); // SAFETY: The NonZero types have the "null" optimization guaranteed, and thus @@ -55,18 +54,18 @@ is_bytewise_comparable!( // The way `PartialOrd` is defined for `Option` means that this wouldn't work // for `<` or `>` on the signed types, but since we only do `==` it's fine. is_bytewise_comparable!( - Option, - Option, - Option, - Option, - Option, - Option, - Option, - Option, - Option, - Option, - Option, - Option, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, + Option>, ); macro_rules! is_bytewise_comparable_array_length { diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 56ab63be27d37..bab6ce8095b7e 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -408,18 +408,7 @@ mod ptr_try_from_impls { } // Conversion traits for non-zero integer types -use crate::num::NonZeroI128; -use crate::num::NonZeroI16; -use crate::num::NonZeroI32; -use crate::num::NonZeroI64; -use crate::num::NonZeroI8; -use crate::num::NonZeroIsize; -use crate::num::NonZeroU128; -use crate::num::NonZeroU16; -use crate::num::NonZeroU32; -use crate::num::NonZeroU64; -use crate::num::NonZeroU8; -use crate::num::NonZeroUsize; +use crate::num::NonZero; macro_rules! nzint_impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { @@ -450,45 +439,45 @@ macro_rules! nzint_impl_from { } // Non-zero Unsigned -> Non-zero Unsigned -nzint_impl_from! { NonZeroU8, NonZeroU16, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroU32, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroU64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroUsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroU32, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroU64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroUsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU32, NonZeroU64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU32, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU64, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } // Non-zero Signed -> Non-zero Signed -nzint_impl_from! { NonZeroI8, NonZeroI16, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI8, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI8, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI8, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI8, NonZeroIsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI16, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI16, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI16, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI16, NonZeroIsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI32, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI32, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroI64, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } // NonZero UnSigned -> Non-zero Signed -nzint_impl_from! { NonZeroU8, NonZeroI16, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU8, NonZeroIsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU16, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU32, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU32, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } -nzint_impl_from! { NonZeroU64, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } +nzint_impl_from! { NonZero, NonZero, #[stable(feature = "nz_int_conv", since = "1.41.0")] } macro_rules! nzint_impl_try_from_int { ($Int: ty, $NonZeroInt: ty, #[$attr:meta], $doc: expr) => { @@ -518,18 +507,18 @@ macro_rules! nzint_impl_try_from_int { } // Int -> Non-zero Int -nzint_impl_try_from_int! { u8, NonZeroU8, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { u16, NonZeroU16, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { u32, NonZeroU32, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { u64, NonZeroU64, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { u128, NonZeroU128, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { usize, NonZeroUsize, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { i8, NonZeroI8, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { i16, NonZeroI16, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { i32, NonZeroI32, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { i64, NonZeroI64, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { i128, NonZeroI128, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } -nzint_impl_try_from_int! { isize, NonZeroIsize, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { u8, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { u16, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { u32, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { u64, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { u128, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { usize, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { i8, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { i16, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { i32, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { i64, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { i128, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } +nzint_impl_try_from_int! { isize, NonZero, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] } macro_rules! nzint_impl_try_from_nzint { ($From:ty => $To:ty, $doc: expr) => { @@ -564,17 +553,41 @@ macro_rules! nzint_impl_try_from_nzint { } // Non-zero int -> non-zero unsigned int -nzint_impl_try_from_nzint! { NonZeroU8: NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroU16: NonZeroI8, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroU32: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroU64: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroU128: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroUsize: NonZeroI8, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroIsize } +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} // Non-zero int -> non-zero signed int -nzint_impl_try_from_nzint! { NonZeroI8: NonZeroU8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroI16: NonZeroU16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroI32: NonZeroU32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroI64: NonZeroU64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroI128: NonZeroU128, NonZeroUsize, NonZeroIsize } -nzint_impl_try_from_nzint! { NonZeroIsize: NonZeroU16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize } +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero +} +nzint_impl_try_from_nzint! { + NonZero: NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero, NonZero +} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 26c51e8403522..26fe7d6fc8f8f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -189,6 +189,7 @@ #![feature(allow_internal_unstable)] #![feature(asm_const)] #![feature(associated_type_bounds)] +#![feature(associated_type_defaults)] #![feature(auto_traits)] #![feature(c_unwind)] #![feature(cfg_sanitize)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4913a6de91828..20fc2bd713a43 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1168,7 +1168,7 @@ impl fmt::Debug for Discriminant { /// [`as`]: ../../std/keyword.as.html /// [primitive representation]: ../../reference/type-layout.html#primitive-representations /// [default representation]: ../../reference/type-layout.html#the-default-representation -/// ``` +/// ```ignore (FIXME: *const _ cannot be resolved anymore for some reason.) /// #[repr(u8)] /// enum Enum { /// Unit, diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 08444421dca08..0292988a50ddf 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -61,11 +61,20 @@ pub use dec2flt::ParseFloatError; #[stable(feature = "rust1", since = "1.0.0")] pub use error::ParseIntError; -#[stable(feature = "nonzero", since = "1.28.0")] -pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; +#[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +pub use nonzero::ZeroablePrimitive; + +#[unstable(feature = "generic_nonzero", issue = "82363")] +pub use nonzero::NonZero; #[stable(feature = "signed_nonzero", since = "1.34.0")] pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize}; +#[stable(feature = "nonzero", since = "1.28.0")] +pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; #[stable(feature = "try_from", since = "1.34.0")] pub use error::TryFromIntError; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 74a325b89d442..2f7a221eec166 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,6 +1,9 @@ //! Definitions of integer that is known not to equal zero. +use crate::cmp::{Ord, Ordering, PartialEq, PartialOrd}; use crate::fmt; +use crate::hash::{Hash, Hasher}; +use crate::marker::{Destruct, StructuralPartialEq}; use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem}; use crate::str::FromStr; @@ -8,197 +11,479 @@ use super::from_str_radix; use super::{IntErrorKind, ParseIntError}; use crate::intrinsics; -macro_rules! impl_nonzero_fmt { - ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { +mod private { + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + #[const_trait] + pub trait Sealed {} +} + +/// A marker trait for primitive types which can be zero. +/// +/// This is an implementation detail for [`NonZero`](NonZero) which may disappear or be replaced at any time. +#[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +#[const_trait] +pub trait ZeroablePrimitive: Sized + Copy + private::Sealed { + /// Type from which a `NonZero` is constructed, usually also `T`. + type Input = Self; + + #[doc(hidden)] + fn input_is_zero(n: &Self::Input) -> bool; + #[doc(hidden)] + fn from_input(n: Self::Input) -> Self; +} + +macro_rules! impl_zeroable_primitive_int { + ($($Ty:ident,)*) => { $( - #[$stability] - impl fmt::$Trait for $Ty { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.get().fmt(f) + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + impl const private::Sealed for $Ty {} + + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + impl const ZeroablePrimitive for $Ty { + #[inline(always)] + fn input_is_zero(n: &Self::Input) -> bool { + *n == 0 + } + + #[inline(always)] + fn from_input(n: Self::Input) -> Self { + n } } )+ } } -macro_rules! nonzero_integers { - ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => { - $( - /// 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::>(), 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. - #[$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. - /// - /// # Safety - /// - /// The value must not be zero. - #[$stability] - #[$const_new_unchecked_stability] - #[must_use] - #[inline] - pub const unsafe fn new_unchecked(n: $Int) -> Self { - // SAFETY: this is guaranteed to be safe by the caller. - unsafe { - core::intrinsics::assert_unsafe_precondition!( - concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument"), - (n: $Int) => n != 0 - ); - Self(n) - } - } +impl_zeroable_primitive_int!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize,); + +#[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +impl const private::Sealed for *const T {} + +#[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +impl const ZeroablePrimitive for *const T { + type Input = *mut T; + + #[inline(always)] + fn input_is_zero(n: &Self::Input) -> bool { + n.is_null() + } - /// 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 { - if n != 0 { - // SAFETY: we just checked that there's no `0` - Some(unsafe { Self(n) }) - } else { - None - } - } + #[inline(always)] + fn from_input(n: Self::Input) -> Self { + n as *const T + } +} - /// 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 { - self.0 - } +/// A value that is known not to equal zero. +/// +/// This enables some memory layout optimization. +/// For example, `Option>` is the same size as `u32`: +/// +/// ```rust +/// #![feature(generic_nonzero)] +/// +/// use core::mem::size_of; +/// assert_eq!(size_of::>>(), size_of::()); +/// ``` +#[unstable(feature = "generic_nonzero", issue = "82363")] +#[derive(Copy, Eq)] +#[repr(transparent)] +#[rustc_layout_scalar_valid_range_start(1)] +#[rustc_nonnull_optimization_guaranteed] +#[rustc_diagnostic_item = "NonZero"] +pub struct NonZero(T); + +#[unstable(feature = "generic_nonzero", issue = "82363")] +impl Clone for NonZero +where + T: Clone, +{ + #[inline] + fn clone(&self) -> Self { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { Self(self.0) } + } +} - } +#[unstable(feature = "generic_nonzero", issue = "82363")] +impl PartialEq for NonZero +where + T: PartialEq, +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0 == other.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 { - nonzero.0 - } - } + #[inline] + fn ne(&self, other: &Self) -> bool { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0 != other.0 } + } +} - #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr for $Ty { - type Output = Self; - #[inline] - 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()) } - } - } +#[stable(feature = "nonzero", since = "1.28.0")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +impl StructuralPartialEq for NonZero {} + +#[unstable(feature = "generic_nonzero", issue = "82363")] +impl PartialOrd for NonZero +where + T: PartialOrd, +{ + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0.partial_cmp(&other.0) } + } - #[stable(feature = "nonzero_bitor", since = "1.45.0")] - 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) } - } - } + #[inline] + fn lt(&self, other: &Self) -> bool { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0 < other.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()) } - } - } + #[inline] + fn le(&self, other: &Self) -> bool { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0 <= other.0 } + } - #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOrAssign for $Ty { - #[inline] - fn bitor_assign(&mut self, rhs: Self) { - *self = *self | rhs; - } + #[inline] + fn gt(&self, other: &Self) -> bool { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0 > other.0 } + } + + #[inline] + fn ge(&self, other: &Self) -> bool { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0 >= other.0 } + } +} + +#[unstable(feature = "generic_nonzero", issue = "82363")] +impl Ord for NonZero +where + T: Ord, +{ + fn cmp(&self, other: &Self) -> Ordering { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0.cmp(&other.0) } + } + + fn max(self, other: Self) -> Self + where + T: ~const Destruct, + { + // SAFETY: The maximum of two non-zero values is still non-zero. + unsafe { Self(self.0.max(other.0)) } + } + + fn min(self, other: Self) -> Self + where + T: ~const Destruct, + { + // SAFETY: The minimum of two non-zero values is still non-zero. + unsafe { Self(self.0.min(other.0)) } + } + + fn clamp(self, min: Self, max: Self) -> Self + where + T: ~const Destruct + PartialOrd, + { + // SAFETY: A non-zero value clamped between two non-zero values is still non-zero. + unsafe { Self(self.0.clamp(min.0, max.0)) } + } +} + +#[unstable(feature = "generic_nonzero", issue = "82363")] +impl Hash for NonZero +where + T: Hash, +{ + #[inline] + fn hash(&self, state: &mut H) + where + H: Hasher, + { + // SAFETY: A `NonZero` is guaranteed to only contain non-zero values. + unsafe { self.0.hash(state) } + } +} + +impl NonZero { + /// Creates a non-zero without checking whether the value is non-zero. + /// This results in undefined behaviour if the value is zero. + /// + /// # Safety + /// + /// The value must not be zero. + #[stable(feature = "generic_nonzero_new", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "generic_nonzero_new", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_refs_to_cell)] + #[must_use] + #[inline] + pub const unsafe fn new_unchecked(v: T::Input) -> Self + where + T: ~const ZeroablePrimitive, + T::Input: ~const Destruct, + { + // SAFETY: This is guaranteed to be safe by the caller. + unsafe { + // FIXME: Make `assert_unsafe_precondition` work with `~const` bound. + #[cfg(debug_assertions)] + { + let is_zero = T::input_is_zero(&v); + core::intrinsics::assert_unsafe_precondition!( + "NonZero::new_unchecked requires a non-zero argument", + (is_zero: bool) => !is_zero + ); } - #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOrAssign<$Int> for $Ty { + Self(T::from_input(v)) + } + } + + /// Creates a non-zero if the given value is not zero. + #[stable(feature = "generic_nonzero_new", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "generic_nonzero_new", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_refs_to_cell)] + #[must_use] + #[inline] + pub const fn new(v: T::Input) -> Option + where + T: ~const ZeroablePrimitive, + T::Input: ~const Destruct, + { + if !T::input_is_zero(&v) { + // SAFETY: We just checked that `n` is not 0. + Some(unsafe { Self(T::from_input(v)) }) + } else { + None + } + } + + /// Returns the value as a primitive type. + #[stable(feature = "generic_nonzero_get", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "generic_nonzero_get", since = "CURRENT_RUSTC_VERSION")] + #[must_use] + #[inline] + pub const fn get(self) -> T { + self.0 + } +} + +#[stable(feature = "from_generic_nonzero", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] +impl From> for T { + /// Converts a `NonZero::` into a `T`. + #[inline] + fn from(nonzero: NonZero) -> Self { + nonzero.get() + } +} + +#[stable(feature = "generic_nonzero_bitor", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +impl BitOr for NonZero +where + T: BitOr, +{ + type Output = Self; + + #[inline] + fn bitor(self, rhs: T) -> Self::Output { + // SAFETY: Since `self` is non-zero, the result of the bitwise-or + // will be non-zero regardless of the value of `rhs`. + unsafe { Self(self.0 | rhs) } + } +} + +#[stable(feature = "generic_nonzero_bitor", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +impl BitOr for NonZero +where + T: BitOr, +{ + type Output = Self; + + #[inline] + fn bitor(self, rhs: Self) -> Self::Output { + self | rhs.0 + } +} + +#[stable(feature = "generic_nonzero_bitor", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +impl BitOr> for T +where + T: BitOr, +{ + type Output = NonZero; + + #[inline] + fn bitor(self, rhs: NonZero) -> Self::Output { + rhs | self + } +} + +#[stable(feature = "generic_nonzero_bitor", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +impl BitOrAssign for NonZero +where + T: BitOr, +{ + #[inline] + fn bitor_assign(&mut self, rhs: Self) { + *self = *self | rhs; + } +} + +#[stable(feature = "generic_nonzero_bitor", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +impl BitOrAssign for NonZero +where + T: BitOr, +{ + #[inline] + fn bitor_assign(&mut self, rhs: T) { + *self = *self | rhs; + } +} + +macro_rules! nonzero_fmt { + (#[$stability:meta] ($($Trait:ident),+)) => { + $( + #[$stability] + impl fmt::$Trait for NonZero + where + T: fmt::$Trait, + { #[inline] - fn bitor_assign(&mut self, rhs: $Int) { - *self = *self | rhs; + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::$Trait::fmt(&self.get(), f) } } + )+ + }; +} - impl_nonzero_fmt! { - #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty - } +nonzero_fmt!( + #[stable(feature = "generic_nonzero_fmt", since = "CURRENT_RUSTC_VERSION")] + (Debug, Display, Binary, Octal, LowerHex, UpperHex) +); + +macro_rules! nonzero_alias { + ($( + #[$stability: meta] #[$const_new_unchecked_stability: meta] + $( + $vis:vis type $Alias:ident = $Ty:ident<$Int:ident>; )+ + )+) => { + $($( + #[doc = concat!("An `", stringify!($Int), "` that is known not to equal zero.")] + /// + /// This enables some memory layout optimization. + #[doc = concat!("For example, `Option<", stringify!($Ty), "<", stringify!($Int), ">>` is the same size as `", stringify!($Int), "`:")] + /// + /// ```rust + /// use core::mem::size_of; + #[doc = concat!("assert_eq!(size_of::>(), size_of::<", stringify!($Int), ">());")] + /// ``` + /// + /// # Layout + /// + #[doc = concat!("`", stringify!($Ty), "<", stringify!($Int), ">` 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), "<", stringify!($Int), ">>` is guaranteed to be compatible with `", stringify!($Int), "`,")] + /// including in FFI. + #[$stability] + #[rustc_diagnostic_item = stringify!($Alias)] + $vis type $Alias = $Ty<$Int>; + )+)+ } } -nonzero_integers! { - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize); +nonzero_alias! { + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] + pub type NonZeroU8 = NonZero; + pub type NonZeroU16 = NonZero; + pub type NonZeroU32 = NonZero; + pub type NonZeroU64 = NonZero; + pub type NonZeroU128 = NonZero; + pub type NonZeroUsize = NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] + pub type NonZeroI8 = NonZero; + pub type NonZeroI16 = NonZero; + pub type NonZeroI32 = NonZero; + pub type NonZeroI64 = NonZero; + pub type NonZeroI128 = NonZero; + pub type NonZeroIsize = NonZero; } macro_rules! from_str_radix_nzint_impl { - ($($t:ty)*) => {$( - #[stable(feature = "nonzero_parse", since = "1.35.0")] - impl FromStr for $t { - type Err = ParseIntError; - fn from_str(src: &str) -> Result { - Self::new(from_str_radix(src, 10)?) - .ok_or(ParseIntError { - kind: IntErrorKind::Zero - }) + ($($Ty:ident<$Int:ident>;)*) => { + $( + #[stable(feature = "nonzero_parse", since = "1.35.0")] + impl FromStr for $Ty<$Int> { + type Err = ParseIntError; + + fn from_str(src: &str) -> Result { + Self::new(from_str_radix(src, 10)?) + .ok_or(ParseIntError { + kind: IntErrorKind::Zero + }) + } } - } - )*} + )* + } } -from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize -NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize } +from_str_radix_nzint_impl! { + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; +} macro_rules! nonzero_leading_trailing_zeros { - ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => { + ($($Ty:ident<$Int:ident>, $Uint:ident, $LeadingTestExpr:expr;)+) => { $( - impl $Ty { + impl $Ty<$Int> { /// Returns the number of leading zeros in the binary representation of `self`. /// /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided. @@ -208,7 +493,9 @@ macro_rules! nonzero_leading_trailing_zeros { /// Basic usage: /// /// ``` - #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("let n = core::num::", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($LeadingTestExpr), ").unwrap();")] /// /// assert_eq!(n.leading_zeros(), 0); /// ``` @@ -232,7 +519,9 @@ macro_rules! nonzero_leading_trailing_zeros { /// Basic usage: /// /// ``` - #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("let n = core::num::", stringify!($Ty), "::<", stringify!($Int), ">::new(0b0101000).unwrap();")] /// /// assert_eq!(n.trailing_zeros(), 3); /// ``` @@ -245,37 +534,36 @@ macro_rules! nonzero_leading_trailing_zeros { // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`. unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 } } - } )+ } } nonzero_leading_trailing_zeros! { - NonZeroU8(u8), u8::MAX; - NonZeroU16(u16), u16::MAX; - NonZeroU32(u32), u32::MAX; - NonZeroU64(u64), u64::MAX; - NonZeroU128(u128), u128::MAX; - NonZeroUsize(usize), usize::MAX; - NonZeroI8(u8), -1i8; - NonZeroI16(u16), -1i16; - NonZeroI32(u32), -1i32; - NonZeroI64(u64), -1i64; - NonZeroI128(u128), -1i128; - NonZeroIsize(usize), -1isize; + NonZero, u8, u8::MAX; + NonZero, u16, u16::MAX; + NonZero, u32, u32::MAX; + NonZero, u64, u64::MAX; + NonZero, u128, u128::MAX; + NonZero, usize, usize::MAX; + NonZero, u8, -1i8; + NonZero, u16, -1i16; + NonZero, u32, -1i32; + NonZero, u64, -1i64; + NonZero, u128, -1i128; + NonZero, usize, -1isize; } macro_rules! nonzero_integers_div { - ( $( $Ty: ident($Int: ty); )+ ) => { + ($($Ty:ident<$Int:ty>;)+) => { $( #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Div<$Ty> for $Int { + impl Div<$Ty<$Int>> for $Int { type Output = $Int; /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. #[inline] - fn div(self, other: $Ty) -> $Int { + fn div(self, other: $Ty<$Int>) -> $Int { // SAFETY: div by zero is checked because `other` is a nonzero, // and MIN/-1 is checked because `self` is an unsigned int. unsafe { crate::intrinsics::unchecked_div(self, other.get()) } @@ -283,11 +571,11 @@ macro_rules! nonzero_integers_div { } #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Rem<$Ty> for $Int { + impl Rem<$Ty<$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 { + fn rem(self, other: $Ty<$Int>) -> $Int { // SAFETY: rem by zero is checked because `other` is a nonzero, // and MIN/-1 is checked because `self` is an unsigned int. unsafe { crate::intrinsics::unchecked_rem(self, other.get()) } @@ -298,19 +586,19 @@ macro_rules! nonzero_integers_div { } nonzero_integers_div! { - NonZeroU8(u8); - NonZeroU16(u16); - NonZeroU32(u32); - NonZeroU64(u64); - NonZeroU128(u128); - NonZeroUsize(usize); + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; } // A bunch of methods for unsigned nonzero types only. macro_rules! nonzero_unsigned_operations { - ( $( $Ty: ident($Int: ident); )+ ) => { + ($($Ty:ident<$Int:ident>;)+) => { $( - impl $Ty { + impl $Ty<$Int> { /// Adds an unsigned integer to a non-zero value. /// Checks for overflow and returns [`None`] on overflow. /// As a consequence, the result cannot wrap to zero. @@ -319,13 +607,14 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let two = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(Some(two), one.checked_add(1)); /// assert_eq!(None, max.checked_add(1)); @@ -337,11 +626,11 @@ macro_rules! nonzero_unsigned_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_add(self, other: $Int) -> Option<$Ty> { + pub const fn checked_add(self, other: $Int) -> Option { if let Some(result) = self.get().checked_add(other) { // SAFETY: $Int::checked_add returns None on overflow // so the result cannot be zero. - Some(unsafe { $Ty::new_unchecked(result) }) + Some(unsafe { Self::new_unchecked(result) }) } else { None } @@ -353,13 +642,14 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let two = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(two, one.saturating_add(1)); /// assert_eq!(max, max.saturating_add(1)); @@ -371,10 +661,10 @@ macro_rules! nonzero_unsigned_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn saturating_add(self, other: $Int) -> $Ty { + pub const fn saturating_add(self, other: $Int) -> Self { // SAFETY: $Int::saturating_add returns $Int::MAX on overflow // so the result cannot be zero. - unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) } + unsafe { Self::new_unchecked(self.get().saturating_add(other)) } } /// Adds an unsigned integer to a non-zero value, @@ -388,12 +678,13 @@ macro_rules! nonzero_unsigned_operations { /// /// ``` /// #![feature(nonzero_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let two = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] /// /// assert_eq!(two, unsafe { one.unchecked_add(1) }); /// # Some(()) @@ -403,9 +694,9 @@ macro_rules! nonzero_unsigned_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty { + pub const unsafe fn unchecked_add(self, other: $Int) -> Self { // SAFETY: The caller ensures there is no overflow. - unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) } + unsafe { Self::new_unchecked(self.get().unchecked_add(other)) } } /// Returns the smallest power of two greater than or equal to n. @@ -416,14 +707,15 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] + #[doc = concat!("let three = ", stringify!($Ty), "::<", stringify!($Int), ">::new(3)?;")] + #[doc = concat!("let four = ", stringify!($Ty), "::<", stringify!($Int), ">::new(4)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(Some(two), two.checked_next_power_of_two() ); /// assert_eq!(Some(four), three.checked_next_power_of_two() ); @@ -436,11 +728,10 @@ macro_rules! nonzero_unsigned_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_next_power_of_two(self) -> Option<$Ty> { + pub const fn checked_next_power_of_two(self) -> Option { if let Some(nz) = self.get().checked_next_power_of_two() { - // SAFETY: The next power of two is positive - // and overflow is checked. - Some(unsafe { $Ty::new_unchecked(nz) }) + // SAFETY: The next power of two is positive and overflow is checked. + Some(unsafe { Self::new_unchecked(nz) }) } else { None } @@ -456,15 +747,16 @@ macro_rules! nonzero_unsigned_operations { /// # 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);")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::new(7).unwrap().ilog2(), 2);")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::new(8).unwrap().ilog2(), 3);")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::new(9).unwrap().ilog2(), 3);")] /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub const fn ilog2(self) -> u32 { Self::BITS - 1 - self.leading_zeros() @@ -480,15 +772,16 @@ macro_rules! nonzero_unsigned_operations { /// # 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);")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::new(99).unwrap().ilog10(), 1);")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::new(100).unwrap().ilog10(), 2);")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::new(101).unwrap().ilog10(), 2);")] /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub const fn ilog10(self) -> u32 { super::int_log10::$Int(self.0) @@ -499,19 +792,19 @@ macro_rules! nonzero_unsigned_operations { } nonzero_unsigned_operations! { - NonZeroU8(u8); - NonZeroU16(u16); - NonZeroU32(u32); - NonZeroU64(u64); - NonZeroU128(u128); - NonZeroUsize(usize); + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; } // A bunch of methods for signed nonzero types only. macro_rules! nonzero_signed_operations { - ( $( $Ty: ident($Int: ty) -> $Uty: ident($Uint: ty); )+ ) => { + ($($Ty:ident<$Int:ty> -> $Uty:ident<$Uint:ty>;)+) => { $( - impl $Ty { + impl $Ty<$Int> { /// Computes the absolute value of self. #[doc = concat!("See [`", stringify!($Int), "::abs`]")] /// for documentation on overflow behaviour. @@ -519,11 +812,13 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let neg = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-1)?;")] /// /// assert_eq!(pos, pos.abs()); /// assert_eq!(pos, neg.abs()); @@ -535,9 +830,9 @@ macro_rules! nonzero_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn abs(self) -> $Ty { + pub const fn abs(self) -> Self { // SAFETY: This cannot overflow to zero. - unsafe { $Ty::new_unchecked(self.get().abs()) } + unsafe { Self::new_unchecked(self.get().abs()) } } /// Checked absolute value. @@ -548,13 +843,14 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let neg = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-1)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(Some(pos), neg.checked_abs()); /// assert_eq!(None, min.checked_abs()); @@ -566,10 +862,10 @@ macro_rules! nonzero_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_abs(self) -> Option<$Ty> { + pub const fn checked_abs(self) -> Option { if let Some(nz) = self.get().checked_abs() { // SAFETY: absolute value of nonzero cannot yield zero values. - Some(unsafe { $Ty::new_unchecked(nz) }) + Some(unsafe { Self::new_unchecked(nz) }) } else { None } @@ -582,13 +878,14 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let neg = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-1)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!((pos, false), pos.overflowing_abs()); /// assert_eq!((pos, false), neg.overflowing_abs()); @@ -601,11 +898,11 @@ macro_rules! nonzero_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn overflowing_abs(self) -> ($Ty, bool) { + pub const fn overflowing_abs(self) -> (Self, bool) { let (nz, flag) = self.get().overflowing_abs(); ( // SAFETY: absolute value of nonzero cannot yield zero values. - unsafe { $Ty::new_unchecked(nz) }, + unsafe { Self::new_unchecked(nz) }, flag, ) } @@ -616,17 +913,16 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let neg = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-1)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let min_plus = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN + 1)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(pos, pos.saturating_abs()); /// assert_eq!(pos, neg.saturating_abs()); @@ -640,9 +936,9 @@ macro_rules! nonzero_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn saturating_abs(self) -> $Ty { + pub const fn saturating_abs(self) -> Self { // SAFETY: absolute value of nonzero cannot yield zero values. - unsafe { $Ty::new_unchecked(self.get().saturating_abs()) } + unsafe { Self::new_unchecked(self.get().saturating_abs()) } } /// Wrapping absolute value, see @@ -651,15 +947,15 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let neg = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-1)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(pos, pos.wrapping_abs()); /// assert_eq!(pos, neg.wrapping_abs()); @@ -673,9 +969,9 @@ macro_rules! nonzero_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn wrapping_abs(self) -> $Ty { + pub const fn wrapping_abs(self) -> Self { // SAFETY: absolute value of nonzero cannot yield zero values. - unsafe { $Ty::new_unchecked(self.get().wrapping_abs()) } + unsafe { Self::new_unchecked(self.get().wrapping_abs()) } } /// Computes the absolute value of self @@ -684,18 +980,16 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("# use std::num::", stringify!($Uty), ";")] + /// #![feature(generic_nonzero)] /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Uty), "::<", stringify!($Uint), ">::new(1)?;")] + #[doc = concat!("let i_pos = ", stringify!($Ty), "::<", stringify!($Int), ">::new(1)?;")] + #[doc = concat!("let i_neg = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-1)?;")] + #[doc = concat!("let i_min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let u_max = ", stringify!($Uty), "::<", stringify!($Uint), ">::new(", stringify!($Uint), "::MAX / 2 + 1)?;")] /// /// assert_eq!(u_pos, i_pos.unsigned_abs()); /// assert_eq!(u_pos, i_neg.unsigned_abs()); @@ -708,9 +1002,9 @@ macro_rules! nonzero_signed_operations { #[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) -> $Uty::<$Uint> { // SAFETY: absolute value of nonzero cannot yield zero values. - unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) } + unsafe { $Uty::<$Uint>::new_unchecked(self.get().unsigned_abs()) } } /// Returns `true` if `self` is positive and `false` if the @@ -720,12 +1014,13 @@ macro_rules! nonzero_signed_operations { /// /// ``` /// #![feature(nonzero_negation_ops)] + /// #![feature(generic_nonzero)] /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-5)?;")] /// /// assert!(pos_five.is_positive()); /// assert!(!neg_five.is_positive()); @@ -746,12 +1041,13 @@ macro_rules! nonzero_signed_operations { /// /// ``` /// #![feature(nonzero_negation_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-5)?;")] /// /// assert!(neg_five.is_negative()); /// assert!(!pos_five.is_negative()); @@ -771,14 +1067,14 @@ macro_rules! nonzero_signed_operations { /// /// ``` /// #![feature(nonzero_negation_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(pos_five.checked_neg(), Some(neg_five)); /// assert_eq!(min.checked_neg(), None); @@ -787,10 +1083,10 @@ macro_rules! nonzero_signed_operations { /// ``` #[inline] #[unstable(feature = "nonzero_negation_ops", issue = "102443")] - pub const fn checked_neg(self) -> Option<$Ty> { + pub const fn checked_neg(self) -> Option { if let Some(result) = self.get().checked_neg() { // SAFETY: negation of nonzero cannot yield zero values. - return Some(unsafe { $Ty::new_unchecked(result) }); + return Some(unsafe { Self::new_unchecked(result) }); } None } @@ -804,14 +1100,14 @@ macro_rules! nonzero_signed_operations { /// /// ``` /// #![feature(nonzero_negation_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false)); /// assert_eq!(min.overflowing_neg(), (min, true)); @@ -820,10 +1116,10 @@ macro_rules! nonzero_signed_operations { /// ``` #[inline] #[unstable(feature = "nonzero_negation_ops", issue = "102443")] - pub const fn overflowing_neg(self) -> ($Ty, bool) { + pub const fn overflowing_neg(self) -> (Self, bool) { let (result, overflow) = self.get().overflowing_neg(); // SAFETY: negation of nonzero cannot yield zero values. - ((unsafe { $Ty::new_unchecked(result) }), overflow) + (unsafe { Self::new_unchecked(result) }, overflow) } /// Saturating negation. Computes `-self`, returning `MAX` if @@ -833,18 +1129,16 @@ macro_rules! nonzero_signed_operations { /// /// ``` /// #![feature(nonzero_negation_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let min_plus_one = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN + 1)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(pos_five.saturating_neg(), neg_five); /// assert_eq!(min.saturating_neg(), max); @@ -854,11 +1148,11 @@ macro_rules! nonzero_signed_operations { /// ``` #[inline] #[unstable(feature = "nonzero_negation_ops", issue = "102443")] - pub const fn saturating_neg(self) -> $Ty { + pub const fn saturating_neg(self) -> Self { if let Some(result) = self.checked_neg() { return result; } - $Ty::MAX + Self::MAX } /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary @@ -871,14 +1165,14 @@ macro_rules! nonzero_signed_operations { /// /// ``` /// #![feature(nonzero_negation_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::<", stringify!($Int), ">::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(pos_five.wrapping_neg(), neg_five); /// assert_eq!(min.wrapping_neg(), min); @@ -887,44 +1181,54 @@ macro_rules! nonzero_signed_operations { /// ``` #[inline] #[unstable(feature = "nonzero_negation_ops", issue = "102443")] - pub const fn wrapping_neg(self) -> $Ty { + pub const fn wrapping_neg(self) -> Self { let result = self.get().wrapping_neg(); // SAFETY: negation of nonzero cannot yield zero values. - unsafe { $Ty::new_unchecked(result) } + unsafe { Self::new_unchecked(result) } } } #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] - impl Neg for $Ty { - type Output = $Ty; + impl Neg for $Ty<$Int> { + type Output = Self; #[inline] - fn neg(self) -> $Ty { + fn neg(self) -> Self { // SAFETY: negation of nonzero cannot yield zero values. - unsafe { $Ty::new_unchecked(self.get().neg()) } + unsafe { Self::new_unchecked(self.get().neg()) } } } - forward_ref_unop! { impl Neg, neg for $Ty, + forward_ref_unop! { impl Neg, neg for $Ty<$Int>, #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] } )+ } } nonzero_signed_operations! { - NonZeroI8(i8) -> NonZeroU8(u8); - NonZeroI16(i16) -> NonZeroU16(u16); - NonZeroI32(i32) -> NonZeroU32(u32); - NonZeroI64(i64) -> NonZeroU64(u64); - NonZeroI128(i128) -> NonZeroU128(u128); - NonZeroIsize(isize) -> NonZeroUsize(usize); + NonZero -> NonZero; + NonZero -> NonZero; + NonZero -> NonZero; + NonZero -> NonZero; + NonZero -> NonZero; + NonZero -> NonZero; +} + +// Use this when the generated code should differ between signed and unsigned types. +macro_rules! sign_dependent_expr { + (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => { + $signed_case + }; + (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => { + $unsigned_case + }; } // A bunch of methods for both signed and unsigned nonzero types. macro_rules! nonzero_unsigned_signed_operations { - ( $( $signedness:ident $Ty: ident($Int: ty); )+ ) => { + ( $( $signedness:ident $Ty:ident<$Int:ty>; )+ ) => { $( - impl $Ty { + impl $Ty<$Int> { /// Multiplies two non-zero integers together. /// Checks for overflow and returns [`None`] on overflow. /// As a consequence, the result cannot wrap to zero. @@ -932,13 +1236,14 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] + #[doc = concat!("let four = ", stringify!($Ty), "::<", stringify!($Int), ">::new(4)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(Some(four), two.checked_mul(two)); /// assert_eq!(None, max.checked_mul(two)); @@ -950,12 +1255,12 @@ macro_rules! nonzero_unsigned_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> { + pub const fn checked_mul(self, other: Self) -> Option { if let Some(result) = self.get().checked_mul(other.get()) { // SAFETY: checked_mul returns None on overflow // and `other` is also non-null // so the result cannot be zero. - Some(unsafe { $Ty::new_unchecked(result) }) + Some(unsafe { Self::new_unchecked(result) }) } else { None } @@ -967,13 +1272,14 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] + #[doc = concat!("let four = ", stringify!($Ty), "::<", stringify!($Int), ">::new(4)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(four, two.saturating_mul(two)); /// assert_eq!(max, four.saturating_mul(max)); @@ -985,11 +1291,10 @@ macro_rules! nonzero_unsigned_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn saturating_mul(self, other: $Ty) -> $Ty { - // SAFETY: saturating_mul returns u*::MAX on overflow - // and `other` is also non-null - // so the result cannot be zero. - unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) } + pub const fn saturating_mul(self, other: Self) -> Self { + // SAFETY: `saturating_mul` returns `u*::MAX` on overflow + // and `other` is also non-null, so the result cannot be zero. + unsafe { Self::new_unchecked(self.get().saturating_mul(other.get())) } } /// Multiplies two non-zero integers together, @@ -1012,12 +1317,13 @@ macro_rules! nonzero_unsigned_signed_operations { /// /// ``` /// #![feature(nonzero_ops)] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(2)?;")] + #[doc = concat!("let four = ", stringify!($Ty), "::<", stringify!($Int), ">::new(4)?;")] /// /// assert_eq!(four, unsafe { two.unchecked_mul(two) }); /// # Some(()) @@ -1027,9 +1333,9 @@ macro_rules! nonzero_unsigned_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty { + pub const unsafe fn unchecked_mul(self, other: Self) -> Self { // SAFETY: The caller ensures there is no overflow. - unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) } + unsafe { Self::new_unchecked(self.get().unchecked_mul(other.get())) } } /// Raises non-zero value to an integer power. @@ -1039,13 +1345,14 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(3)?;")] + #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::<", stringify!($Int), ">::new(27)?;")] + #[doc = concat!("let half_max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX / 2)?;")] /// /// assert_eq!(Some(twenty_seven), three.checked_pow(3)); /// assert_eq!(None, half_max.checked_pow(3)); @@ -1057,11 +1364,11 @@ macro_rules! nonzero_unsigned_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_pow(self, other: u32) -> Option<$Ty> { + pub const fn checked_pow(self, other: u32) -> Option { if let Some(result) = self.get().checked_pow(other) { // SAFETY: checked_pow returns None on overflow // so the result cannot be zero. - Some(unsafe { $Ty::new_unchecked(result) }) + Some(unsafe { Self::new_unchecked(result) }) } else { None } @@ -1082,13 +1389,14 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] /// # 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 = ", stringify!($Ty), "::<", stringify!($Int), ">::new(3)?;")] + #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::<", stringify!($Int), ">::new(27)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::<", stringify!($Int), ">::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(twenty_seven, three.saturating_pow(3)); /// assert_eq!(max, max.saturating_pow(3)); @@ -1100,46 +1408,35 @@ macro_rules! nonzero_unsigned_signed_operations { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn saturating_pow(self, other: u32) -> $Ty { + pub const fn saturating_pow(self, other: u32) -> Self { // SAFETY: saturating_pow returns u*::MAX on overflow // so the result cannot be zero. - unsafe { $Ty::new_unchecked(self.get().saturating_pow(other)) } + unsafe { Self::new_unchecked(self.get().saturating_pow(other)) } } } )+ } } -// Use this when the generated code should differ between signed and unsigned types. -macro_rules! sign_dependent_expr { - (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => { - $signed_case - }; - (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => { - $unsigned_case - }; -} - nonzero_unsigned_signed_operations! { - unsigned NonZeroU8(u8); - unsigned NonZeroU16(u16); - unsigned NonZeroU32(u32); - unsigned NonZeroU64(u64); - unsigned NonZeroU128(u128); - unsigned NonZeroUsize(usize); - signed NonZeroI8(i8); - signed NonZeroI16(i16); - signed NonZeroI32(i32); - signed NonZeroI64(i64); - signed NonZeroI128(i128); - signed NonZeroIsize(isize); + unsigned NonZero; + unsigned NonZero; + unsigned NonZero; + unsigned NonZero; + unsigned NonZero; + unsigned NonZero; + signed NonZero; + signed NonZero; + signed NonZero; + signed NonZero; + signed NonZero; + signed NonZero; } macro_rules! nonzero_unsigned_is_power_of_two { - ( $( $Ty: ident )+ ) => { + ($($Ty:ident<$Int:ident>;)+) => { $( - impl $Ty { - + impl $Ty<$Int> { /// Returns `true` if and only if `self == (1 << k)` for some `k`. /// /// On many architectures, this function can perform better than `is_power_of_two()` @@ -1150,9 +1447,11 @@ macro_rules! nonzero_unsigned_is_power_of_two { /// Basic usage: /// /// ``` - #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("let eight = core::num::", stringify!($Ty), "::<", stringify!($Int), ">::new(8).unwrap();")] /// assert!(eight.is_power_of_two()); - #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")] + #[doc = concat!("let ten = core::num::", stringify!($Ty), "::<", stringify!($Int), ">::new(10).unwrap();")] /// assert!(!ten.is_power_of_two()); /// ``` #[must_use] @@ -1167,26 +1466,34 @@ macro_rules! nonzero_unsigned_is_power_of_two { intrinsics::ctpop(self.get()) < 2 } - } )+ } } -nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize } +nonzero_unsigned_is_power_of_two! { + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; +} macro_rules! nonzero_min_max_unsigned { - ( $( $Ty: ident($Int: ident); )+ ) => { + ($($Ty:ident<$Int:ident>;)+) => { $( - impl $Ty { + impl $Ty<$Int> { /// The smallest value that can be represented by this non-zero /// integer type, 1. /// /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), 1", stringify!($Int), ");")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::MIN.get(), 1", stringify!($Int), ");")] /// ``` #[stable(feature = "nonzero_min_max", since = "1.70.0")] pub const MIN: Self = Self::new(1).unwrap(); @@ -1198,8 +1505,10 @@ macro_rules! nonzero_min_max_unsigned { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", 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(); @@ -1209,9 +1518,9 @@ macro_rules! nonzero_min_max_unsigned { } macro_rules! nonzero_min_max_signed { - ( $( $Ty: ident($Int: ident); )+ ) => { + ($($Ty:ident<$Int:ident>;)+) => { $( - impl $Ty { + impl $Ty<$Int> { /// The smallest value that can be represented by this non-zero /// integer type, #[doc = concat!("equal to [`", stringify!($Int), "::MIN`].")] @@ -1223,8 +1532,10 @@ macro_rules! nonzero_min_max_signed { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), ", stringify!($Int), "::MIN);")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", 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(); @@ -1240,8 +1551,10 @@ macro_rules! nonzero_min_max_signed { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")] + /// #![feature(generic_nonzero)] + /// + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", 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(); @@ -1251,27 +1564,27 @@ macro_rules! nonzero_min_max_signed { } nonzero_min_max_unsigned! { - NonZeroU8(u8); - NonZeroU16(u16); - NonZeroU32(u32); - NonZeroU64(u64); - NonZeroU128(u128); - NonZeroUsize(usize); + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; } nonzero_min_max_signed! { - NonZeroI8(i8); - NonZeroI16(i16); - NonZeroI32(i32); - NonZeroI64(i64); - NonZeroI128(i128); - NonZeroIsize(isize); + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; } macro_rules! nonzero_bits { - ( $( $Ty: ident($Int: ty); )+ ) => { + ($($Ty:ident<$Int:ty>;)+) => { $( - impl $Ty { + impl $Ty<$Int> { /// The size of this non-zero integer type in bits. /// #[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")] @@ -1279,9 +1592,10 @@ macro_rules! nonzero_bits { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// #![feature(generic_nonzero)] /// - #[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")] + #[doc = concat!("# use core::num::", stringify!($Ty), ";")] + #[doc = concat!("assert_eq!(", stringify!($Ty), "::<", stringify!($Int), ">::BITS, ", stringify!($Int), "::BITS);")] /// ``` #[stable(feature = "nonzero_bits", since = "1.67.0")] pub const BITS: u32 = <$Int>::BITS; @@ -1291,16 +1605,16 @@ macro_rules! nonzero_bits { } nonzero_bits! { - NonZeroU8(u8); - NonZeroI8(i8); - NonZeroU16(u16); - NonZeroI16(i16); - NonZeroU32(u32); - NonZeroI32(i32); - NonZeroU64(u64); - NonZeroI64(i64); - NonZeroU128(u128); - NonZeroI128(i128); - NonZeroUsize(usize); - NonZeroIsize(isize); + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; + NonZero; } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index ec1ef3cf43d12..f84a21e4e74b6 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2132,18 +2132,18 @@ macro_rules! non_zero_option { } non_zero_option! { - #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU8; - #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU16; - #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU32; - #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU64; - #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU128; - #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroUsize; - #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI8; - #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI16; - #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI32; - #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI64; - #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI128; - #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroIsize; + #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero; } #[stable(feature = "nonnull", since = "1.25.0")] diff --git a/library/std/src/num.rs b/library/std/src/num.rs index 46064bd283770..8cd7b444663f6 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -19,6 +19,9 @@ pub use core::num::Wrapping; #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}; +#[unstable(feature = "generic_nonzero", issue = "82363")] +pub use core::num::NonZero; + #[stable(feature = "signed_nonzero", since = "1.34.0")] pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize}; #[stable(feature = "nonzero", since = "1.28.0")] diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs index 5503653253c55..47e10804d4ce8 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs @@ -4,10 +4,7 @@ use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::{ - query::Key, - ty::{self, Ty}, -}; +use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; /// Checks for `transmute_int_to_non_zero` lint. @@ -19,40 +16,53 @@ pub(super) fn check<'tcx>( to_ty: Ty<'tcx>, arg: &'tcx Expr<'_>, ) -> bool { - let (ty::Int(_) | ty::Uint(_), Some(to_ty_id)) = (&from_ty.kind(), to_ty.ty_adt_id()) else { + let tcx = cx.tcx; + + let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else { return false; }; - let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_id) else { + + if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) { return false; }; - if !matches!( - to_type_sym, - sym::NonZeroU8 - | sym::NonZeroU16 - | sym::NonZeroU32 - | sym::NonZeroU64 - | sym::NonZeroU128 - | sym::NonZeroI8 - | sym::NonZeroI16 - | sym::NonZeroI32 - | sym::NonZeroI64 - | sym::NonZeroI128 - ) { - return false; - } + 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 = substs.type_at(0); + + let Some(nonzero_alias) = coercable_types + .iter() + .find_map(|(nonzero_alias, t)| { + if *t == int_type && *t == from_ty { + Some(nonzero_alias) + } else { + None + } + }) + else { return false; }; span_lint_and_then( cx, TRANSMUTE_INT_TO_NON_ZERO, e.span, - &format!("transmute from a `{from_ty}` to a `{to_type_sym}`"), + &format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"), |diag| { let arg = sugg::Sugg::hir(cx, arg, ".."); diag.span_suggestion( e.span, "consider using", - format!("{to_type_sym}::{}({arg})", sym::new_unchecked), + format!("{nonzero_alias}::{}({arg})", sym::new_unchecked), Applicability::Unspecified, ); }, diff --git a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff index c5907e7cf180e..b651b6ddd2c67 100644 --- a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff +++ b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff @@ -10,7 +10,7 @@ let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47 let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52 let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52 - let mut _14: std::option::Option; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58 + let mut _14: std::option::Option>; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58 let mut _16: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54 let mut _18: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54 let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47 @@ -99,10 +99,10 @@ StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53 StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 - _14 = Option::::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 + _14 = Option::>::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 // mir::Constant // + span: $DIR/combine_transmutes.rs:41:33: 41:57 - // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } + // + literal: Const { ty: NonZero, val: Unevaluated(NonZero::::MAX, [], None) } _13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59 StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59 StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 diff --git a/tests/ui/binop/issue-28837.rs b/tests/ui/binop/issue-28837.rs index 54c8838e48f11..ed15ec7b41d0b 100644 --- a/tests/ui/binop/issue-28837.rs +++ b/tests/ui/binop/issue-28837.rs @@ -15,7 +15,8 @@ fn main() { a & a; //~ ERROR no implementation for `A & A` - a | a; //~ ERROR no implementation for `A | A` + a | a; + //~^ ERROR no implementation for `A | A` a << a; //~ ERROR no implementation for `A << A` diff --git a/tests/ui/binop/issue-28837.stderr b/tests/ui/binop/issue-28837.stderr index 6c98edd3af8e8..e474ff63dc715 100644 --- a/tests/ui/binop/issue-28837.stderr +++ b/tests/ui/binop/issue-28837.stderr @@ -111,7 +111,7 @@ note: the trait `BitOr` must be implemented --> $SRC_DIR/core/src/ops/bit.rs:LL:COL error[E0369]: no implementation for `A << A` - --> $DIR/issue-28837.rs:20:7 + --> $DIR/issue-28837.rs:21:7 | LL | a << a; | - ^^ - A @@ -127,7 +127,7 @@ note: the trait `Shl` must be implemented --> $SRC_DIR/core/src/ops/bit.rs:LL:COL error[E0369]: no implementation for `A >> A` - --> $DIR/issue-28837.rs:22:7 + --> $DIR/issue-28837.rs:23:7 | LL | a >> a; | - ^^ - A @@ -143,7 +143,7 @@ note: the trait `Shr` must be implemented --> $SRC_DIR/core/src/ops/bit.rs:LL:COL error[E0369]: binary operation `==` cannot be applied to type `A` - --> $DIR/issue-28837.rs:24:7 + --> $DIR/issue-28837.rs:25:7 | LL | a == a; | - ^^ - A @@ -162,7 +162,7 @@ LL | struct A; | error[E0369]: binary operation `!=` cannot be applied to type `A` - --> $DIR/issue-28837.rs:26:7 + --> $DIR/issue-28837.rs:27:7 | LL | a != a; | - ^^ - A @@ -181,7 +181,7 @@ LL | struct A; | error[E0369]: binary operation `<` cannot be applied to type `A` - --> $DIR/issue-28837.rs:28:7 + --> $DIR/issue-28837.rs:29:7 | LL | a < a; | - ^ - A @@ -200,7 +200,7 @@ LL | struct A; | error[E0369]: binary operation `<=` cannot be applied to type `A` - --> $DIR/issue-28837.rs:30:7 + --> $DIR/issue-28837.rs:31:7 | LL | a <= a; | - ^^ - A @@ -219,7 +219,7 @@ LL | struct A; | error[E0369]: binary operation `>` cannot be applied to type `A` - --> $DIR/issue-28837.rs:32:7 + --> $DIR/issue-28837.rs:33:7 | LL | a > a; | - ^ - A @@ -238,7 +238,7 @@ LL | struct A; | error[E0369]: binary operation `>=` cannot be applied to type `A` - --> $DIR/issue-28837.rs:34:7 + --> $DIR/issue-28837.rs:35:7 | LL | a >= a; | - ^^ - A diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr index 55096e95df7e0..e9dc4bf9c24a2 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr @@ -147,7 +147,14 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:33:10 | LL | type H = Fn(u8) -> (u8)::Output; - | ^^^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use the fully-qualified path + | +LL | type H = <(dyn Fn(u8) -> u8 + 'static) as BitOr>::Output; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | type H = <(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:39:19 diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr index b0dddd3b1e8d0..ff80db87bf730 100644 --- a/tests/ui/fmt/ifmt-unimpl.stderr +++ b/tests/ui/fmt/ifmt-unimpl.stderr @@ -9,13 +9,13 @@ LL | format!("{:X}", "3"); = help: the following other types implement trait `UpperHex`: &T &mut T - NonZeroI128 - NonZeroI16 - NonZeroI32 - NonZeroI64 - NonZeroI8 - NonZeroIsize - and 20 others + NonZero + Saturating + Wrapping + i128 + i16 + i32 + and 9 others = note: required for `&str` to implement `UpperHex` note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL diff --git a/tests/ui/layout/zero-sized-array-enum-niche.rs b/tests/ui/layout/zero-sized-array-enum-niche.rs index 23bbbfbfc5881..9319f77428cb8 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.rs +++ b/tests/ui/layout/zero-sized-array-enum-niche.rs @@ -1,5 +1,5 @@ // normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" -#![feature(rustc_attrs)] +#![feature(rustc_attrs, generic_nonzero)] #![crate_type = "lib"] // Various tests around the behavior of zero-sized arrays and @@ -34,7 +34,7 @@ enum MultipleAlignments { //~ ERROR: layout_of struct Packed(T); #[rustc_layout(debug)] -type NicheLosesToTagged = Result<[u32; 0], Packed>; //~ ERROR: layout_of +type NicheLosesToTagged = Result<[u32; 0], Packed>>; //~ ERROR: layout_of // Should get tag_encoding: Direct, size == align == 4. #[repr(u16)] diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index a3e82070e0f52..26f3c9d439619 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -218,7 +218,7 @@ error: layout_of(MultipleAlignments) = Layout { LL | enum MultipleAlignments { | ^^^^^^^^^^^^^^^^^^^^^^^ -error: layout_of(std::result::Result<[u32; 0], Packed>) = Layout { +error: layout_of(std::result::Result<[u32; 0], Packed>>) = Layout { size: Size(4 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), @@ -314,7 +314,7 @@ error: layout_of(std::result::Result<[u32; 0], Packed>) = } --> $DIR/zero-sized-array-enum-niche.rs:37:1 | -LL | type NicheLosesToTagged = Result<[u32; 0], Packed>; +LL | type NicheLosesToTagged = Result<[u32; 0], Packed>>; | ^^^^^^^^^^^^^^^^^^^^^^^ error: layout_of(std::result::Result<[u32; 0], Packed>) = Layout { diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs index 09fda33dbec5c..b060e3cc24c34 100644 --- a/tests/ui/lint/clashing-extern-fn.rs +++ b/tests/ui/lint/clashing-extern-fn.rs @@ -1,5 +1,6 @@ // check-pass // aux-build:external_extern_fn.rs +#![feature(generic_nonzero)] #![crate_type = "lib"] #![warn(clashing_extern_declarations)] @@ -265,7 +266,7 @@ mod missing_return_type { mod non_zero_and_non_null { mod a { extern "C" { - fn non_zero_usize() -> core::num::NonZeroUsize; + fn non_zero_usize() -> core::num::NonZero; fn non_null_ptr() -> core::ptr::NonNull; } } @@ -285,36 +286,36 @@ mod non_zero_and_non_null { // See #75739 mod non_zero_transparent { mod a1 { - use std::num::NonZeroUsize; + use std::num::NonZero; extern "C" { - fn f1() -> NonZeroUsize; + fn f1() -> NonZero; } } mod b1 { #[repr(transparent)] - struct X(NonZeroUsize); - use std::num::NonZeroUsize; + struct X(NonZero); + use std::num::NonZero; extern "C" { fn f1() -> X; } } mod a2 { - use std::num::NonZeroUsize; + use std::num::NonZero; extern "C" { - fn f2() -> NonZeroUsize; + fn f2() -> NonZero; } } mod b2 { #[repr(transparent)] - struct X1(NonZeroUsize); + struct X1(NonZero); #[repr(transparent)] struct X(X1); - use std::num::NonZeroUsize; + use std::num::NonZero; extern "C" { // Same case as above, but with two layers of newtyping. fn f2() -> X; @@ -325,7 +326,7 @@ mod non_zero_transparent { #[repr(transparent)] struct X(core::ptr::NonNull); - use std::num::NonZeroUsize; + use std::num::NonZero; extern "C" { fn f3() -> X; } @@ -340,7 +341,7 @@ mod non_zero_transparent { mod a4 { #[repr(transparent)] enum E { - X(std::num::NonZeroUsize), + X(std::num::NonZero), } extern "C" { fn f4() -> E; @@ -349,7 +350,7 @@ mod non_zero_transparent { mod b4 { extern "C" { - fn f4() -> std::num::NonZeroUsize; + fn f4() -> std::num::NonZero; } } } @@ -369,8 +370,8 @@ mod null_optimised_enums { extern "C" { // This should be allowed, because these conversions are guaranteed to be FFI-safe (see // #60300) - fn option_non_zero_usize() -> Option; - fn option_non_zero_isize() -> Option; + fn option_non_zero_usize() -> Option>; + fn option_non_zero_isize() -> Option>; fn option_non_null_ptr() -> Option>; // However, these should be incorrect (note isize instead of usize) @@ -415,16 +416,16 @@ mod hidden_niche { } mod b { use std::cell::UnsafeCell; - use std::num::NonZeroUsize; + use std::num::NonZero; #[repr(transparent)] struct Transparent { - x: NonZeroUsize, + x: NonZero } #[repr(transparent)] struct TransparentNoNiche { - y: UnsafeCell, + y: UnsafeCell> } extern "C" { @@ -434,9 +435,9 @@ mod hidden_niche { //~^ WARN redeclared with a different signature //~| WARN block uses type `Option`, which is not FFI-safe - fn hidden_niche_unsafe_cell() -> Option>; + fn hidden_niche_unsafe_cell() -> Option>>; //~^ WARN redeclared with a different signature - //~| WARN block uses type `Option>`, which is not FFI-safe + //~| WARN block uses type `Option>>`, which is not FFI-safe } } } diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr index 5d457ba0ec763..ea5bf373148fe 100644 --- a/tests/ui/lint/clashing-extern-fn.stderr +++ b/tests/ui/lint/clashing-extern-fn.stderr @@ -1,5 +1,5 @@ warning: `clash` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:14:13 + --> $DIR/clashing-extern-fn.rs:15:13 | LL | fn clash(x: u8); | ---------------- `clash` previously declared here @@ -10,13 +10,13 @@ LL | fn clash(x: u64); = note: expected `unsafe extern "C" fn(u8)` found `unsafe extern "C" fn(u64)` note: the lint level is defined here - --> $DIR/clashing-extern-fn.rs:4:9 + --> $DIR/clashing-extern-fn.rs:5:9 | LL | #![warn(clashing_extern_declarations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `extern_link_name` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:52:9 + --> $DIR/clashing-extern-fn.rs:53:9 | LL | / #[link_name = "extern_link_name"] LL | | fn some_new_name(x: i16); @@ -29,7 +29,7 @@ LL | fn extern_link_name(x: u32); found `unsafe extern "C" fn(u32)` warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature - --> $DIR/clashing-extern-fn.rs:55:9 + --> $DIR/clashing-extern-fn.rs:56:9 | LL | fn some_other_new_name(x: i16); | ------------------------------- `some_other_new_name` previously declared here @@ -43,7 +43,7 @@ LL | | fn some_other_extern_link_name(x: u32); found `unsafe extern "C" fn(u32)` warning: `other_both_names_different` redeclares `link_name_same` with a different signature - --> $DIR/clashing-extern-fn.rs:59:9 + --> $DIR/clashing-extern-fn.rs:60:9 | LL | / #[link_name = "link_name_same"] LL | | fn both_names_different(x: i16); @@ -58,7 +58,7 @@ LL | | fn other_both_names_different(x: u32); found `unsafe extern "C" fn(u32)` warning: `different_mod` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:72:9 + --> $DIR/clashing-extern-fn.rs:73:9 | LL | fn different_mod(x: u8); | ------------------------ `different_mod` previously declared here @@ -70,7 +70,7 @@ LL | fn different_mod(x: u64); found `unsafe extern "C" fn(u64)` warning: `variadic_decl` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:82:9 + --> $DIR/clashing-extern-fn.rs:83:9 | LL | fn variadic_decl(x: u8, ...); | ----------------------------- `variadic_decl` previously declared here @@ -82,7 +82,7 @@ LL | fn variadic_decl(x: u8); found `unsafe extern "C" fn(u8)` warning: `weigh_banana` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:142:13 + --> $DIR/clashing-extern-fn.rs:143:13 | LL | fn weigh_banana(count: *const Banana) -> u64; | --------------------------------------------- `weigh_banana` previously declared here @@ -94,7 +94,7 @@ LL | fn weigh_banana(count: *const Banana) -> u64; found `unsafe extern "C" fn(*const three::Banana) -> u64` warning: `draw_point` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:171:13 + --> $DIR/clashing-extern-fn.rs:172:13 | LL | fn draw_point(p: Point); | ------------------------ `draw_point` previously declared here @@ -106,7 +106,7 @@ LL | fn draw_point(p: Point); found `unsafe extern "C" fn(sameish_members::b::Point)` warning: `origin` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:197:13 + --> $DIR/clashing-extern-fn.rs:198:13 | LL | fn origin() -> Point3; | ---------------------- `origin` previously declared here @@ -118,7 +118,7 @@ LL | fn origin() -> Point3; found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3` warning: `transparent_incorrect` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:220:13 + --> $DIR/clashing-extern-fn.rs:221:13 | LL | fn transparent_incorrect() -> T; | -------------------------------- `transparent_incorrect` previously declared here @@ -130,7 +130,7 @@ LL | fn transparent_incorrect() -> isize; found `unsafe extern "C" fn() -> isize` warning: `missing_return_type` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:259:13 + --> $DIR/clashing-extern-fn.rs:260:13 | LL | fn missing_return_type() -> usize; | ---------------------------------- `missing_return_type` previously declared here @@ -142,19 +142,19 @@ LL | fn missing_return_type(); found `unsafe extern "C" fn()` warning: `non_zero_usize` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:277:13 + --> $DIR/clashing-extern-fn.rs:278:13 | -LL | fn non_zero_usize() -> core::num::NonZeroUsize; - | ----------------------------------------------- `non_zero_usize` previously declared here +LL | fn non_zero_usize() -> core::num::NonZero; + | ------------------------------------------------- `non_zero_usize` previously declared here ... LL | fn non_zero_usize() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | - = note: expected `unsafe extern "C" fn() -> NonZeroUsize` + = note: expected `unsafe extern "C" fn() -> NonZero` found `unsafe extern "C" fn() -> usize` warning: `non_null_ptr` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:279:13 + --> $DIR/clashing-extern-fn.rs:280:13 | LL | fn non_null_ptr() -> core::ptr::NonNull; | ----------------------------------------------- `non_null_ptr` previously declared here @@ -166,7 +166,7 @@ LL | fn non_null_ptr() -> *const usize; found `unsafe extern "C" fn() -> *const usize` warning: `option_non_zero_usize_incorrect` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:377:13 + --> $DIR/clashing-extern-fn.rs:378:13 | LL | fn option_non_zero_usize_incorrect() -> usize; | ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here @@ -178,7 +178,7 @@ LL | fn option_non_zero_usize_incorrect() -> isize; found `unsafe extern "C" fn() -> isize` warning: `option_non_null_ptr_incorrect` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:379:13 + --> $DIR/clashing-extern-fn.rs:380:13 | LL | fn option_non_null_ptr_incorrect() -> *const usize; | --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here @@ -190,7 +190,7 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize; found `unsafe extern "C" fn() -> *const isize` warning: `hidden_niche_transparent_no_niche` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:433:13 + --> $DIR/clashing-extern-fn.rs:434:13 | LL | fn hidden_niche_transparent_no_niche() -> usize; | ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here @@ -202,19 +202,19 @@ LL | fn hidden_niche_transparent_no_niche() -> Option Option` warning: `hidden_niche_unsafe_cell` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:437:13 + --> $DIR/clashing-extern-fn.rs:438:13 | LL | fn hidden_niche_unsafe_cell() -> usize; | --------------------------------------- `hidden_niche_unsafe_cell` previously declared here ... -LL | fn hidden_niche_unsafe_cell() -> Option>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration +LL | fn hidden_niche_unsafe_cell() -> Option>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> usize` - found `unsafe extern "C" fn() -> Option>` + found `unsafe extern "C" fn() -> Option>>` warning: `extern` block uses type `Option`, which is not FFI-safe - --> $DIR/clashing-extern-fn.rs:433:55 + --> $DIR/clashing-extern-fn.rs:434:55 | LL | fn hidden_niche_transparent_no_niche() -> Option; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -223,11 +223,11 @@ LL | fn hidden_niche_transparent_no_niche() -> Option>`, which is not FFI-safe - --> $DIR/clashing-extern-fn.rs:437:46 +warning: `extern` block uses type `Option>>`, which is not FFI-safe + --> $DIR/clashing-extern-fn.rs:438:46 | -LL | fn hidden_niche_unsafe_cell() -> Option>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn hidden_niche_unsafe_cell() -> Option>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint diff --git a/tests/ui/lint/invalid_value.rs b/tests/ui/lint/invalid_value.rs index 57d8cbe7c9341..f09edaad0d117 100644 --- a/tests/ui/lint/invalid_value.rs +++ b/tests/ui/lint/invalid_value.rs @@ -1,13 +1,13 @@ // This test checks that calling `mem::{uninitialized,zeroed}` with certain types results // in a lint. -#![feature(never_type, rustc_attrs)] +#![feature(never_type, rustc_attrs, generic_nonzero)] #![allow(deprecated)] #![deny(invalid_value)] use std::mem::{self, MaybeUninit}; use std::ptr::NonNull; -use std::num::NonZeroU32; +use std::num::NonZero; enum Void {} @@ -36,7 +36,7 @@ enum OneFruit { enum OneFruitNonZero { Apple(!), - Banana(NonZeroU32), + Banana(NonZero), } enum TwoUninhabited { @@ -92,8 +92,8 @@ fn main() { let _val: NonNull = mem::zeroed(); //~ ERROR: does not permit zero-initialization let _val: NonNull = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized - let _val: (NonZeroU32, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: (NonZeroU32, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: (NonZero, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: (NonZero, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized @@ -151,7 +151,7 @@ fn main() { // Transmute-from-0 let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization - let _val: NonZeroU32 = mem::transmute(0); //~ ERROR: does not permit zero-initialization + let _val: NonZero = mem::transmute(0); //~ ERROR: does not permit zero-initialization // `MaybeUninit` cases let _val: NonNull = MaybeUninit::zeroed().assume_init(); //~ ERROR: does not permit zero-initialization diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr index 57531b0968f1e..f22d8ada424d3 100644 --- a/tests/ui/lint/invalid_value.stderr +++ b/tests/ui/lint/invalid_value.stderr @@ -316,27 +316,27 @@ LL | let _val: NonNull = mem::uninitialized(); = note: `std::ptr::NonNull` must be non-null = note: raw pointers must be initialized -error: the type `(NonZeroU32, i32)` does not permit zero-initialization - --> $DIR/invalid_value.rs:95:39 +error: the type `(NonZero, i32)` does not permit zero-initialization + --> $DIR/invalid_value.rs:95:41 | -LL | let _val: (NonZeroU32, i32) = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done +LL | let _val: (NonZero, i32) = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: `std::num::NonZeroU32` must be non-null + = note: `std::num::NonZero` must be non-null -error: the type `(NonZeroU32, i32)` does not permit being left uninitialized - --> $DIR/invalid_value.rs:96:39 +error: the type `(NonZero, i32)` does not permit being left uninitialized + --> $DIR/invalid_value.rs:96:41 | -LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done +LL | let _val: (NonZero, i32) = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: `std::num::NonZeroU32` must be non-null + = note: `std::num::NonZero` must be non-null = note: integers must be initialized error: the type `*const dyn Send` does not permit zero-initialization @@ -417,11 +417,11 @@ LL | let _val: OneFruitNonZero = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | = note: `OneFruitNonZero` must be non-null -note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant) +note: because `std::num::NonZero` must be non-null (in this field of the only potentially inhabited enum variant) --> $DIR/invalid_value.rs:39:12 | -LL | Banana(NonZeroU32), - | ^^^^^^^^^^ +LL | Banana(NonZero), + | ^^^^^^^^^^^^ error: the type `OneFruitNonZero` does not permit being left uninitialized --> $DIR/invalid_value.rs:108:37 @@ -433,11 +433,11 @@ LL | let _val: OneFruitNonZero = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | = note: `OneFruitNonZero` must be non-null -note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant) +note: because `std::num::NonZero` must be non-null (in this field of the only potentially inhabited enum variant) --> $DIR/invalid_value.rs:39:12 | -LL | Banana(NonZeroU32), - | ^^^^^^^^^^ +LL | Banana(NonZero), + | ^^^^^^^^^^^^ = note: integers must be initialized error: the type `bool` does not permit being left uninitialized @@ -603,16 +603,16 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | = note: references must be non-null -error: the type `NonZeroU32` does not permit zero-initialization - --> $DIR/invalid_value.rs:154:32 +error: the type `NonZero` does not permit zero-initialization + --> $DIR/invalid_value.rs:154:34 | -LL | let _val: NonZeroU32 = mem::transmute(0); - | ^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done +LL | let _val: NonZero = mem::transmute(0); + | ^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: `std::num::NonZeroU32` must be non-null + = note: `std::num::NonZero` must be non-null error: the type `NonNull` does not permit zero-initialization --> $DIR/invalid_value.rs:157:34 diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index 7c20608059398..24d80de541dcc 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -1,9 +1,9 @@ #![feature(transparent_unions)] -#![feature(ptr_internals)] +#![feature(ptr_internals, generic_nonzero)] #![deny(improper_ctypes)] #![allow(dead_code)] -use std::num; +use std::num::NonZero; enum Z {} enum U { @@ -67,26 +67,26 @@ extern "C" { fn option_fn(x: Option); fn nonnull(x: Option>); fn unique(x: Option>); - fn nonzero_u8(x: Option); - fn nonzero_u16(x: Option); - fn nonzero_u32(x: Option); - fn nonzero_u64(x: Option); - fn nonzero_u128(x: Option); + fn nonzero_u8(x: Option>); + fn nonzero_u16(x: Option>); + fn nonzero_u32(x: Option>); + fn nonzero_u64(x: Option>); + fn nonzero_u128(x: Option>); //~^ ERROR `extern` block uses type `u128` - fn nonzero_usize(x: Option); - fn nonzero_i8(x: Option); - fn nonzero_i16(x: Option); - fn nonzero_i32(x: Option); - fn nonzero_i64(x: Option); - fn nonzero_i128(x: Option); + fn nonzero_usize(x: Option>); + fn nonzero_i8(x: Option>); + fn nonzero_i16(x: Option>); + fn nonzero_i32(x: Option>); + fn nonzero_i64(x: Option>); + fn nonzero_i128(x: Option>); //~^ ERROR `extern` block uses type `i128` - fn nonzero_isize(x: Option); - fn transparent_struct(x: Option>); - fn transparent_enum(x: Option>); - fn transparent_union(x: Option>); + fn nonzero_isize(x: Option>); + fn transparent_struct(x: Option>>); + fn transparent_enum(x: Option>>); + fn transparent_union(x: Option>>); //~^ ERROR `extern` block uses type - fn repr_rust(x: Option>); //~ ERROR `extern` block uses type - fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR `extern` block uses type + fn repr_rust(x: Option>>); //~ ERROR `extern` block uses type + fn no_result(x: Result<(), NonZero>); //~ ERROR `extern` block uses type } pub fn main() {} diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index 8554e261778e7..9a6f95ae83f05 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -48,42 +48,42 @@ LL | enum T { error: `extern` block uses type `u128`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:74:23 | -LL | fn nonzero_u128(x: Option); - | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn nonzero_u128(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:81:23 | -LL | fn nonzero_i128(x: Option); - | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn nonzero_i128(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: 128-bit integers don't currently have a known stable ABI -error: `extern` block uses type `Option>`, which is not FFI-safe +error: `extern` block uses type `Option>>`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:86:28 | -LL | fn transparent_union(x: Option>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn transparent_union(x: Option>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: `extern` block uses type `Option>`, which is not FFI-safe +error: `extern` block uses type `Option>>`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:88:20 | -LL | fn repr_rust(x: Option>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn repr_rust(x: Option>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: `extern` block uses type `Result<(), NonZeroI32>`, which is not FFI-safe +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:89:20 | -LL | fn no_result(x: Result<(), num::NonZeroI32>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn no_result(x: Result<(), NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.stderr b/tests/ui/mismatched_types/non_zero_assigned_something.stderr index 57db71f889cf7..f8e86905ab9bb 100644 --- a/tests/ui/mismatched_types/non_zero_assigned_something.stderr +++ b/tests/ui/mismatched_types/non_zero_assigned_something.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/non_zero_assigned_something.rs:2:35 | LL | let _: std::num::NonZeroU64 = 1; - | -------------------- ^ expected `NonZeroU64`, found integer + | -------------------- ^ expected `NonZero`, found integer | | | expected due to this | + = note: expected struct `NonZero` + found type `{integer}` help: consider calling `NonZeroU64::new` | LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap(); @@ -15,11 +17,11 @@ error[E0308]: mismatched types --> $DIR/non_zero_assigned_something.rs:6:43 | LL | let _: Option = 1; - | ---------------------------- ^ expected `Option`, found integer + | ---------------------------- ^ expected `Option>`, found integer | | | expected due to this | - = note: expected enum `Option` + = note: expected enum `Option>` found type `{integer}` help: consider calling `NonZeroU64::new` | diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr index 8f0eef237cfe2..14685a3f9371a 100644 --- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr @@ -126,7 +126,7 @@ LL | x / 100.0 <&'a u8 as Div> <&u8 as Div<&u8>> > - > + >> error[E0277]: cannot divide `f64` by `&str` diff --git a/tests/ui/or-patterns/or-patterns-syntactic-fail.rs b/tests/ui/or-patterns/or-patterns-syntactic-fail.rs index 23dbb57cbcf0f..b05309e1232bf 100644 --- a/tests/ui/or-patterns/or-patterns-syntactic-fail.rs +++ b/tests/ui/or-patterns/or-patterns-syntactic-fail.rs @@ -9,7 +9,7 @@ use E::*; fn no_top_level_or_patterns() { // We do *not* allow or-patterns at the top level of lambdas... let _ = |A | B: E| (); - //~^ ERROR expected identifier, found + //~^ ERROR expected identifier, found `:` // -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`. } diff --git a/tests/ui/print_type_sizes/niche-filling.rs b/tests/ui/print_type_sizes/niche-filling.rs index 5e620f248b65d..5559fd8a68622 100644 --- a/tests/ui/print_type_sizes/niche-filling.rs +++ b/tests/ui/print_type_sizes/niche-filling.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z print-type-sizes --crate-type=lib +// compile-flags: --crate-type=lib // build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. @@ -7,17 +7,17 @@ // This file illustrates how niche-filling enums are handled, // modelled after cases like `Option<&u32>`, `Option` and such. // -// It uses NonZeroU32 rather than `&_` or `Unique<_>`, because +// It uses NonZero rather than `&_` or `Unique<_>`, because // the test is not set up to deal with target-dependent pointer width. // // It avoids using u64/i64 because on some targets that is only 4-byte // aligned (while on most it is 8-byte aligned) and so the resulting // padding and overall computed sizes can be quite different. -#![feature(rustc_attrs)] +#![feature(rustc_attrs, generic_nonzero)] #![allow(dead_code)] -use std::num::NonZeroU32; +use std::num::NonZero; pub enum MyOption { None, Some(T) } @@ -33,7 +33,7 @@ impl Default for MyOption { pub enum EmbeddedDiscr { None, - Record { pre: u8, val: NonZeroU32, post: u16 }, + Record { pre: u8, val: NonZero, post: u16 }, } impl Default for EmbeddedDiscr { @@ -49,13 +49,13 @@ pub struct IndirectNonZero { pub struct NestedNonZero { pre: u8, - val: NonZeroU32, + val: NonZero, post: u16, } impl Default for NestedNonZero { fn default() -> Self { - NestedNonZero { pre: 0, val: unsafe { NonZeroU32::new_unchecked(1) }, post: 0 } + NestedNonZero { pre: 0, val: unsafe { NonZero::new_unchecked(1) }, post: 0 } } } @@ -76,7 +76,7 @@ pub union Union2 { } pub fn test() { - let _x: MyOption = Default::default(); + let _x: MyOption> = Default::default(); let _y: EmbeddedDiscr = Default::default(); let _z: MyOption = Default::default(); let _a: MyOption = Default::default(); @@ -89,9 +89,9 @@ pub fn test() { let _h: MyOption = Default::default(); // Unions do not currently participate in niche filling. - let _i: MyOption> = Default::default(); + let _i: MyOption, u32>> = Default::default(); // ...even when theoretically possible. - let _j: MyOption> = Default::default(); - let _k: MyOption> = Default::default(); + let _j: MyOption>> = Default::default(); + let _k: MyOption, NonZero>> = Default::default(); } diff --git a/tests/ui/print_type_sizes/niche-filling.stdout b/tests/ui/print_type_sizes/niche-filling.stdout deleted file mode 100644 index d1753c26ca83b..0000000000000 --- a/tests/ui/print_type_sizes/niche-filling.stdout +++ /dev/null @@ -1,112 +0,0 @@ -print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes -print-type-size field `.nested`: 8 bytes -print-type-size field `.post`: 2 bytes -print-type-size field `.pre`: 1 bytes -print-type-size end padding: 1 bytes -print-type-size type: `MyOption`: 12 bytes, alignment: 4 bytes -print-type-size variant `Some`: 12 bytes -print-type-size field `.0`: 12 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `EmbeddedDiscr`: 8 bytes, alignment: 4 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `Record`: 7 bytes -print-type-size field `.pre`: 1 bytes -print-type-size field `.post`: 2 bytes -print-type-size field `.val`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes -print-type-size discriminant: 4 bytes -print-type-size variant `Some`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes -print-type-size discriminant: 4 bytes -print-type-size variant `Some`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes -print-type-size discriminant: 4 bytes -print-type-size variant `Some`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes -print-type-size field `.val`: 4 bytes -print-type-size field `.post`: 2 bytes -print-type-size field `.pre`: 1 bytes -print-type-size end padding: 1 bytes -print-type-size type: `Enum4<(), char, (), ()>`: 4 bytes, alignment: 4 bytes -print-type-size variant `Two`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `One`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size variant `Three`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size variant `Four`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size type: `MyNotNegativeOne`: 4 bytes, alignment: 4 bytes -print-type-size field `._i`: 4 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes -print-type-size variant `Some`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes -print-type-size variant `Some`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes -print-type-size variant `Some`: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `Union1`: 4 bytes, alignment: 4 bytes -print-type-size variant `Union1`: 4 bytes -print-type-size field `.a`: 4 bytes -print-type-size type: `Union2`: 4 bytes, alignment: 4 bytes -print-type-size variant `Union2`: 4 bytes -print-type-size field `.a`: 4 bytes -print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes -print-type-size type: `Union2`: 4 bytes, alignment: 4 bytes -print-type-size variant `Union2`: 4 bytes -print-type-size field `.a`: 4 bytes -print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes -print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes -print-type-size field `.0`: 4 bytes -print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes -print-type-size variant `Four`: 2 bytes -print-type-size field `.0`: 2 bytes -print-type-size variant `One`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size variant `Two`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size variant `Three`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size type: `MyOption>`: 2 bytes, alignment: 1 bytes -print-type-size variant `Some`: 2 bytes -print-type-size field `.0`: 2 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption`: 2 bytes, alignment: 1 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `Some`: 1 bytes -print-type-size field `.0`: 1 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `Enum4<(), (), bool, ()>`: 1 bytes, alignment: 1 bytes -print-type-size variant `Three`: 1 bytes -print-type-size field `.0`: 1 bytes -print-type-size variant `One`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size variant `Two`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size variant `Four`: 0 bytes -print-type-size field `.0`: 0 bytes -print-type-size type: `MyOption`: 1 bytes, alignment: 1 bytes -print-type-size variant `Some`: 1 bytes -print-type-size field `.0`: 1 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption`: 1 bytes, alignment: 1 bytes -print-type-size variant `Some`: 1 bytes -print-type-size field `.0`: 1 bytes -print-type-size variant `None`: 0 bytes -print-type-size type: `std::cmp::Ordering`: 1 bytes, alignment: 1 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `Less`: 0 bytes -print-type-size variant `Equal`: 0 bytes -print-type-size variant `Greater`: 0 bytes diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index d4fea05fe4bc1..0d6f7fe661316 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -45,12 +45,13 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( | = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate: - impl From for u32; - - impl From for u32; - impl From for u32; - impl From for u32; - impl From for u32; - impl From for u32; - impl From for T; + - impl From> for T + where T: core::num::nonzero::ZeroablePrimitive; - impl From for T; help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/traits/new-solver/specialization-transmute.rs b/tests/ui/traits/new-solver/specialization-transmute.rs index a54701df4ef7e..b5a17aa92aeed 100644 --- a/tests/ui/traits/new-solver/specialization-transmute.rs +++ b/tests/ui/traits/new-solver/specialization-transmute.rs @@ -1,6 +1,6 @@ // compile-flags: -Ztrait-solver=next -#![feature(specialization)] +#![feature(generic_nonzero, specialization)] //~^ WARN the feature `specialization` is incomplete trait Default { @@ -22,9 +22,9 @@ fn transmute, U: Copy>(t: T) -> U { *t.intu() } -use std::num::NonZeroU8; +use std::num::NonZero; fn main() { - let s = transmute::>(0); - //~^ ERROR cannot satisfy `::Id == Option + let s = transmute::>>(0); + //~^ ERROR cannot satisfy `::Id == Option> assert_eq!(s, None); } diff --git a/tests/ui/traits/new-solver/specialization-transmute.stderr b/tests/ui/traits/new-solver/specialization-transmute.stderr index e67c56afc0d0c..834fd6b9d9800 100644 --- a/tests/ui/traits/new-solver/specialization-transmute.stderr +++ b/tests/ui/traits/new-solver/specialization-transmute.stderr @@ -1,8 +1,8 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-transmute.rs:3:12 + --> $DIR/specialization-transmute.rs:3:29 | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ +LL | #![feature(generic_nonzero, specialization)] + | ^^^^^^^^^^^^^^ | = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete @@ -14,11 +14,11 @@ error[E0284]: type annotations needed: cannot satisfy `T <: ::Id` LL | self | ^^^^ cannot satisfy `T <: ::Id` -error[E0284]: type annotations needed: cannot satisfy `::Id == Option` +error[E0284]: type annotations needed: cannot satisfy `::Id == Option>` --> $DIR/specialization-transmute.rs:27:13 | -LL | let s = transmute::>(0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Id == Option` +LL | let s = transmute::>>(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Id == Option>` | note: required by a bound in `transmute` --> $DIR/specialization-transmute.rs:21:25 diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index a49630adb9538..8d72e456782ec 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -7,9 +7,7 @@ LL | Ok(Err(123_i32)?) | ^ the trait `From` is not implemented for `u8` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the following other types implement trait `From`: - > - > + = help: the trait `From` is implemented for `u8` = note: required for `Result` to implement `FromResidual>` error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`