about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_attr/src/builtin.rs6
-rw-r--r--compiler/rustc_attr/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs4
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/stable_hasher.rs5
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs6
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy.rs9
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs5
-rw-r--r--compiler/rustc_feature/src/lib.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_interface/src/lib.rs1
-rw-r--r--compiler/rustc_interface/src/tests.rs4
-rw-r--r--compiler/rustc_interface/src/util.rs2
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs5
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs14
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs20
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs6
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs8
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs8
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs6
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs27
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_passes/src/stability.rs4
-rw-r--r--compiler/rustc_query_impl/src/lib.rs1
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs4
-rw-r--r--compiler/rustc_query_system/src/lib.rs1
-rw-r--r--compiler/rustc_query_system/src/query/job.rs4
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--compiler/rustc_serialize/src/serialize.rs7
-rw-r--r--compiler/rustc_session/src/config.rs4
-rw-r--r--compiler/rustc_session/src/errors.rs4
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/options.rs13
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs10
-rw-r--r--library/alloc/src/collections/vec_deque/into_iter.rs10
-rw-r--r--library/alloc/src/collections/vec_deque/iter.rs6
-rw-r--r--library/alloc/src/collections/vec_deque/iter_mut.rs6
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/vec/in_place_collect.rs6
-rw-r--r--library/alloc/src/vec/into_iter.rs14
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/vec.rs8
-rw-r--r--library/alloc/tests/vec_deque.rs6
-rw-r--r--library/core/src/array/iter.rs10
-rw-r--r--library/core/src/ascii.rs6
-rw-r--r--library/core/src/char/mod.rs6
-rw-r--r--library/core/src/cmp/bytewise.rs4
-rw-r--r--library/core/src/escape.rs6
-rw-r--r--library/core/src/iter/adapters/array_chunks.rs8
-rw-r--r--library/core/src/iter/adapters/by_ref_sized.rs6
-rw-r--r--library/core/src/iter/adapters/chain.rs10
-rw-r--r--library/core/src/iter/adapters/cloned.rs6
-rw-r--r--library/core/src/iter/adapters/copied.rs10
-rw-r--r--library/core/src/iter/adapters/cycle.rs6
-rw-r--r--library/core/src/iter/adapters/enumerate.rs10
-rw-r--r--library/core/src/iter/adapters/filter.rs6
-rw-r--r--library/core/src/iter/adapters/filter_map.rs6
-rw-r--r--library/core/src/iter/adapters/flatten.rs46
-rw-r--r--library/core/src/iter/adapters/inspect.rs6
-rw-r--r--library/core/src/iter/adapters/map.rs6
-rw-r--r--library/core/src/iter/adapters/map_while.rs6
-rw-r--r--library/core/src/iter/adapters/mod.rs6
-rw-r--r--library/core/src/iter/adapters/rev.rs6
-rw-r--r--library/core/src/iter/adapters/scan.rs6
-rw-r--r--library/core/src/iter/adapters/skip.rs14
-rw-r--r--library/core/src/iter/adapters/skip_while.rs6
-rw-r--r--library/core/src/iter/adapters/take.rs14
-rw-r--r--library/core/src/iter/adapters/take_while.rs6
-rw-r--r--library/core/src/iter/adapters/zip.rs6
-rw-r--r--library/core/src/iter/range.rs26
-rw-r--r--library/core/src/iter/sources/repeat.rs6
-rw-r--r--library/core/src/iter/sources/repeat_n.rs8
-rw-r--r--library/core/src/iter/traits/double_ended.rs10
-rw-r--r--library/core/src/iter/traits/iterator.rs10
-rw-r--r--library/core/src/iter/traits/marker.rs6
-rw-r--r--library/core/src/num/nonzero.rs10
-rw-r--r--library/core/src/ops/index_range.rs10
-rw-r--r--library/core/src/ptr/alignment.rs4
-rw-r--r--library/core/src/ptr/non_null.rs4
-rw-r--r--library/core/src/slice/iter.rs2
-rw-r--r--library/core/src/slice/iter/macros.rs8
-rw-r--r--library/core/src/slice/mod.rs4
-rw-r--r--library/core/src/str/iter.rs4
-rw-r--r--library/core/tests/array.rs10
-rw-r--r--library/core/tests/iter/adapters/chain.rs17
-rw-r--r--library/core/tests/iter/adapters/enumerate.rs4
-rw-r--r--library/core/tests/iter/adapters/flatten.rs6
-rw-r--r--library/core/tests/iter/adapters/skip.rs8
-rw-r--r--library/core/tests/iter/adapters/take.rs16
-rw-r--r--library/core/tests/iter/range.rs4
-rw-r--r--library/core/tests/iter/traits/iterator.rs27
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/nonzero.rs265
-rw-r--r--library/core/tests/ptr.rs6
-rw-r--r--library/core/tests/result.rs13
-rw-r--r--library/core/tests/slice.rs6
-rw-r--r--library/proc_macro/src/bridge/handle.rs6
-rw-r--r--library/proc_macro/src/bridge/rpc.rs6
-rw-r--r--library/proc_macro/src/bridge/symbol.rs8
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs6
-rw-r--r--library/std/src/sys/pal/itron/thread.rs3
-rw-r--r--library/std/src/sys/pal/sgx/abi/tls/mod.rs8
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/raw.rs17
-rw-r--r--library/std/src/sys/pal/sgx/rwlock.rs14
-rw-r--r--library/std/src/sys/pal/sgx/thread.rs4
-rw-r--r--library/std/src/sys/pal/sgx/waitqueue/mod.rs6
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs4
-rw-r--r--library/std/src/sys/pal/uefi/thread.rs6
-rw-r--r--library/std/src/sys/pal/unix/process/process_common/tests.rs4
-rw-r--r--library/std/src/sys/pal/unix/process/process_fuchsia.rs8
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs4
-rw-r--r--library/std/src/sys/pal/unix/process/process_unsupported.rs4
-rw-r--r--library/std/src/sys/pal/unix/process/process_vxworks.rs4
-rw-r--r--library/std/src/sys/pal/unix/thread.rs18
-rw-r--r--library/std/src/sys/pal/unsupported/process.rs4
-rw-r--r--library/std/src/sys/pal/unsupported/thread.rs4
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs4
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs4
-rw-r--r--library/std/src/sys/pal/windows/args.rs16
-rw-r--r--library/std/src/sys/pal/windows/process.rs4
-rw-r--r--library/std/src/sys/pal/windows/thread.rs6
-rw-r--r--library/std/src/sys/pal/xous/thread.rs6
-rw-r--r--library/std/src/sys_common/wstr.rs13
-rw-r--r--library/std/src/thread/mod.rs9
-rw-r--r--src/tools/miri/src/bin/miri.rs5
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs14
-rw-r--r--src/tools/miri/src/concurrency/init_once.rs1
-rw-r--r--src/tools/miri/src/concurrency/sync.rs9
-rw-r--r--src/tools/miri/src/diagnostics.rs4
-rw-r--r--src/tools/miri/src/helpers.rs4
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs2
144 files changed, 658 insertions, 609 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index a3783db5f80..f414ff746bb 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -13,7 +13,7 @@ use rustc_session::parse::feature_err;
 use rustc_session::{RustcVersion, Session};
 use rustc_span::hygiene::Transparency;
 use rustc_span::{symbol::sym, symbol::Symbol, Span};
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
 
@@ -113,7 +113,7 @@ pub enum StabilityLevel {
         /// Reason for the current stability level.
         reason: UnstableReason,
         /// Relevant `rust-lang/rust` issue.
-        issue: Option<NonZeroU32>,
+        issue: Option<NonZero<u32>>,
         is_soft: bool,
         /// If part of a feature is stabilized and a new feature is added for the remaining parts,
         /// then the `implied_by` attribute is used to indicate which now-stable feature previously
@@ -442,7 +442,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
                 // is a name/value pair string literal.
                 issue_num = match issue.unwrap().as_str() {
                     "none" => None,
-                    issue => match issue.parse::<NonZeroU32>() {
+                    issue => match issue.parse::<NonZero<u32>>() {
                         Ok(num) => Some(num),
                         Err(err) => {
                             sess.dcx().emit_err(
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index dd87a5c4dc3..fada69c4e6d 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -7,6 +7,7 @@
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
+#![feature(generic_nonzero)]
 #![feature(let_chains)]
 
 #[macro_use]
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index eb9f3fee165..d9edcf6ea97 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -5,7 +5,7 @@
 //! to be const-safe.
 
 use std::fmt::Write;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 
 use either::{Left, Right};
 
@@ -782,7 +782,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
     fn visit_union(
         &mut self,
         op: &OpTy<'tcx, M::Provenance>,
-        _fields: NonZeroUsize,
+        _fields: NonZero<usize>,
     ) -> InterpResult<'tcx> {
         // Special check for CTFE validation, preventing `UnsafeCell` inside unions in immutable memory.
         if self.ctfe_mode.is_some_and(|c| !c.allow_immutable_unsafe_cell()) {
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index 340a496a689..b200ecbf73a 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -7,7 +7,7 @@ use rustc_middle::ty;
 use rustc_target::abi::FieldIdx;
 use rustc_target::abi::{FieldsShape, VariantIdx, Variants};
 
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 
 use super::{InterpCx, MPlaceTy, Machine, Projectable};
 
@@ -43,7 +43,7 @@ pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized {
     }
     /// Visits the given value as a union. No automatic recursion can happen here.
     #[inline(always)]
-    fn visit_union(&mut self, _v: &Self::V, _fields: NonZeroUsize) -> InterpResult<'tcx> {
+    fn visit_union(&mut self, _v: &Self::V, _fields: NonZero<usize>) -> InterpResult<'tcx> {
         Ok(())
     }
     /// Visits the given value as the pointer of a `Box`. There is nothing to recurse into.
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 839cfd8d85a..fd8be45e25d 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -11,6 +11,7 @@ Rust MIR: a lowered representation of Rust.
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
+#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(slice_ptr_get)]
 #![feature(never_type)]
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 2b799d6f5d3..b82a9a909e6 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -20,6 +20,7 @@
 #![feature(cfg_match)]
 #![feature(core_intrinsics)]
 #![feature(extend_one)]
+#![feature(generic_nonzero)]
 #![feature(hash_raw_entry)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(lazy_cell)]
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index 52304c72a2f..15691804a94 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -6,6 +6,7 @@ use std::fmt;
 use std::hash::{BuildHasher, Hash, Hasher};
 use std::marker::PhantomData;
 use std::mem;
+use std::num::NonZero;
 
 #[cfg(test)]
 mod tests;
@@ -338,14 +339,14 @@ impl<CTX, T> HashStable<CTX> for PhantomData<T> {
     fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {}
 }
 
-impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
+impl<CTX> HashStable<CTX> for NonZero<u32> {
     #[inline]
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         self.get().hash_stable(ctx, hasher)
     }
 }
 
-impl<CTX> HashStable<CTX> for ::std::num::NonZeroUsize {
+impl<CTX> HashStable<CTX> for NonZero<usize> {
     #[inline]
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         self.get().hash_stable(ctx, hasher)
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index b34d3dd9044..50a614a1b02 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -1,7 +1,7 @@
 use parking_lot::Mutex;
 use std::cell::Cell;
 use std::cell::OnceCell;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::ops::Deref;
 use std::ptr;
 use std::sync::Arc;
@@ -31,7 +31,7 @@ impl RegistryId {
 }
 
 struct RegistryData {
-    thread_limit: NonZeroUsize,
+    thread_limit: NonZero<usize>,
     threads: Mutex<usize>,
 }
 
@@ -61,7 +61,7 @@ thread_local! {
 
 impl Registry {
     /// Creates a registry which can hold up to `thread_limit` threads.
-    pub fn new(thread_limit: NonZeroUsize) -> Self {
+    pub fn new(thread_limit: NonZero<usize>) -> Self {
         Registry(Arc::new(RegistryData { thread_limit, threads: Mutex::new(0) }))
     }
 
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
index e893a2c7813..8af4042ad87 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
@@ -4,7 +4,7 @@ use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::mem::ManuallyDrop;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::ops::{Deref, DerefMut};
 use std::ptr::NonNull;
 
@@ -134,7 +134,7 @@ where
 
         ptr.map_addr(|addr| {
             // Safety:
-            // - The pointer is `NonNull` => it's address is `NonZeroUsize`
+            // - The pointer is `NonNull` => it's address is `NonZero<usize>`
             // - `P::BITS` least significant bits are always zero (`Pointer` contract)
             // - `T::BITS <= P::BITS` (from `Self::ASSERTION`)
             //
@@ -143,14 +143,15 @@ where
             // `{non_zero} | packed_tag` can't make the value zero.
 
             let packed = (addr.get() >> T::BITS) | packed_tag;
-            unsafe { NonZeroUsize::new_unchecked(packed) }
+            unsafe { NonZero::<usize>::new_unchecked(packed) }
         })
     }
 
     /// Retrieves the original raw pointer from `self.packed`.
     #[inline]
     pub(super) fn pointer_raw(&self) -> NonNull<P::Target> {
-        self.packed.map_addr(|addr| unsafe { NonZeroUsize::new_unchecked(addr.get() << T::BITS) })
+        self.packed
+            .map_addr(|addr| unsafe { NonZero::<usize>::new_unchecked(addr.get() << T::BITS) })
     }
 
     /// This provides a reference to the `P` pointer itself, rather than the
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index e936ebc7185..eaf75539f59 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -79,7 +79,7 @@ into_diagnostic_arg_using_display!(
     ast::ParamKindOrd,
     std::io::Error,
     Box<dyn std::error::Error>,
-    std::num::NonZeroU32,
+    std::num::NonZero<u32>,
     hir::Target,
     Edition,
     Ident,
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index d876f28040d..9f8aee614d7 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -16,6 +16,7 @@
 #![feature(box_patterns)]
 #![feature(error_reporter)]
 #![feature(extract_if)]
+#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(negative_impls)]
 #![feature(never_type)]
@@ -77,7 +78,7 @@ use std::error::Report;
 use std::fmt;
 use std::hash::Hash;
 use std::io::Write;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::ops::DerefMut;
 use std::panic;
 use std::path::{Path, PathBuf};
@@ -545,7 +546,7 @@ pub struct DiagCtxtFlags {
     pub can_emit_warnings: bool,
     /// If Some, the Nth error-level diagnostic is upgraded to bug-level.
     /// (rustc: see `-Z treat-err-as-bug`)
-    pub treat_err_as_bug: Option<NonZeroUsize>,
+    pub treat_err_as_bug: Option<NonZero<usize>>,
     /// Eagerly emit delayed bugs as errors, so that the compiler debugger may
     /// see all of the errors being emitted at once.
     pub eagerly_emit_delayed_bugs: bool,
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index f1c8f2e2dde..02ce5d3534c 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -12,6 +12,7 @@
 //! symbol to the `accepted` or `removed` modules respectively.
 
 #![allow(internal_features)]
+#![feature(generic_nonzero)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![feature(lazy_cell)]
@@ -25,13 +26,13 @@ mod unstable;
 mod tests;
 
 use rustc_span::symbol::Symbol;
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 #[derive(Debug, Clone)]
 pub struct Feature {
     pub name: Symbol,
     pub since: &'static str,
-    issue: Option<NonZeroU32>,
+    issue: Option<NonZero<u32>>,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -85,7 +86,7 @@ impl UnstableFeatures {
     }
 }
 
-fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
+fn find_lang_feature_issue(feature: Symbol) -> Option<NonZero<u32>> {
     // Search in all the feature lists.
     if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| f.feature.name == feature) {
         return f.feature.issue;
@@ -99,21 +100,21 @@ fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
     panic!("feature `{feature}` is not declared anywhere");
 }
 
-const fn to_nonzero(n: Option<u32>) -> Option<NonZeroU32> {
-    // Can be replaced with `n.and_then(NonZeroU32::new)` if that is ever usable
+const fn to_nonzero(n: Option<u32>) -> Option<NonZero<u32>> {
+    // Can be replaced with `n.and_then(NonZero::new)` if that is ever usable
     // in const context. Requires https://github.com/rust-lang/rfcs/pull/2632.
     match n {
         None => None,
-        Some(n) => NonZeroU32::new(n),
+        Some(n) => NonZero::<u32>::new(n),
     }
 }
 
 pub enum GateIssue {
     Language,
-    Library(Option<NonZeroU32>),
+    Library(Option<NonZero<u32>>),
 }
 
-pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU32> {
+pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZero<u32>> {
     match issue {
         GateIssue::Language => find_lang_feature_issue(feature),
         GateIssue::Library(lib) => lib,
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 2f8e065df33..6b064b36cf1 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -74,7 +74,7 @@ pub mod wfcheck;
 
 pub use check::check_abi;
 
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::ErrorGuaranteed;
@@ -270,7 +270,7 @@ fn default_body_is_unstable(
     item_did: DefId,
     feature: Symbol,
     reason: Option<Symbol>,
-    issue: Option<NonZeroU32>,
+    issue: Option<NonZero<u32>>,
 ) {
     let missing_item_name = tcx.associated_item(item_did).name;
     let (mut some_note, mut none_note, mut reason_str) = (false, false, String::new());
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 1cd77050217..d507fb39e19 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
 #![feature(control_flow_enum)]
+#![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(is_sorted)]
 #![feature(iter_intersperse)]
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 7d69e49b209..24c2e290534 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,5 +1,6 @@
 #![feature(decl_macro)]
 #![feature(error_iter)]
+#![feature(generic_nonzero)]
 #![feature(lazy_cell)]
 #![feature(let_chains)]
 #![feature(thread_spawn_unchecked)]
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index bfc4fc07d4c..a9c614df7ad 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -20,7 +20,7 @@ use rustc_span::{FileName, SourceFileHashAlgorithm};
 use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
 use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
 use std::collections::{BTreeMap, BTreeSet};
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::path::{Path, PathBuf};
 use std::sync::Arc;
 
@@ -827,7 +827,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(tls_model, Some(TlsModel::GeneralDynamic));
     tracked!(translate_remapped_path_to_local_path, false);
     tracked!(trap_unreachable, Some(false));
-    tracked!(treat_err_as_bug, NonZeroUsize::new(1));
+    tracked!(treat_err_as_bug, NonZero::<usize>::new(1));
     tracked!(tune_cpu, Some(String::from("abc")));
     tracked!(uninit_const_chunk_threshold, 123);
     tracked!(unleash_the_miri_inside_of_you, true);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 76b9e8de75f..00cf84138ba 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -107,7 +107,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
     use rustc_query_impl::QueryCtxt;
     use rustc_query_system::query::{deadlock, QueryContext};
 
-    let registry = sync::Registry::new(std::num::NonZeroUsize::new(threads).unwrap());
+    let registry = sync::Registry::new(std::num::NonZero::<usize>::new(threads).unwrap());
 
     if !sync::is_dyn_thread_safe() {
         return run_in_thread_with_globals(edition, || {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 5f769e9ad8a..85f9d3bd63e 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -31,6 +31,7 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
+#![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(iter_order_by)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 7445e2e80b4..da59ffebdc5 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1,7 +1,6 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
-
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 use crate::errors::RequestedLevel;
 use crate::fluent_generated as fluent;
@@ -402,7 +401,7 @@ pub struct BuiltinIncompleteFeaturesHelp;
 #[derive(Subdiagnostic)]
 #[note(lint_note)]
 pub struct BuiltinFeatureIssueNote {
-    pub n: NonZeroU32,
+    pub n: NonZero<u32>,
 }
 
 pub struct BuiltinUnpermittedTypeInit<'a> {
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 2e7130f3565..70ad8598957 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -5,6 +5,7 @@
 #![feature(decl_macro)]
 #![feature(extract_if)]
 #![feature(coroutines)]
+#![feature(generic_nonzero)]
 #![feature(iter_from_coroutine)]
 #![feature(let_chains)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 72e9744295b..8a031e4f3a3 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -327,7 +327,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
     }
 
     #[inline]
-    fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZeroUsize) -> T) -> T {
+    fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZero<usize>) -> T) -> T {
         let distance = self.read_usize();
         let position = match self.lazy_state {
             LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
@@ -338,7 +338,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
             }
             LazyState::Previous(last_pos) => last_pos.get() + distance,
         };
-        let position = NonZeroUsize::new(position).unwrap();
+        let position = NonZero::<usize>::new(position).unwrap();
         self.lazy_state = LazyState::Previous(position);
         f(position)
     }
@@ -685,15 +685,17 @@ impl MetadataBlob {
     }
 
     pub(crate) fn get_rustc_version(&self) -> String {
-        LazyValue::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 8).unwrap())
-            .decode(self)
+        LazyValue::<String>::from_position(
+            NonZero::<usize>::new(METADATA_HEADER.len() + 8).unwrap(),
+        )
+        .decode(self)
     }
 
-    fn root_pos(&self) -> NonZeroUsize {
+    fn root_pos(&self) -> NonZero<usize> {
         let offset = METADATA_HEADER.len();
         let pos_bytes = self.blob()[offset..][..8].try_into().unwrap();
         let pos = u64::from_le_bytes(pos_bytes);
-        NonZeroUsize::new(pos as usize).unwrap()
+        NonZero::<usize>::new(pos as usize).unwrap()
     }
 
     pub(crate) fn get_header(&self) -> CrateHeader {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 4a24c038f7a..51d747efdd3 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -421,7 +421,7 @@ macro_rules! record_defaulted_array {
 }
 
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
-    fn emit_lazy_distance(&mut self, position: NonZeroUsize) {
+    fn emit_lazy_distance(&mut self, position: NonZero<usize>) {
         let pos = position.get();
         let distance = match self.lazy_state {
             LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"),
@@ -439,7 +439,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 position.get() - last_pos.get()
             }
         };
-        self.lazy_state = LazyState::Previous(NonZeroUsize::new(pos).unwrap());
+        self.lazy_state = LazyState::Previous(NonZero::<usize>::new(pos).unwrap());
         self.emit_usize(distance);
     }
 
@@ -447,7 +447,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     where
         T::Value<'tcx>: Encodable<EncodeContext<'a, 'tcx>>,
     {
-        let pos = NonZeroUsize::new(self.position()).unwrap();
+        let pos = NonZero::<usize>::new(self.position()).unwrap();
 
         assert_eq!(self.lazy_state, LazyState::NoNode);
         self.lazy_state = LazyState::NodeStart(pos);
@@ -466,7 +466,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     where
         T::Value<'tcx>: Encodable<EncodeContext<'a, 'tcx>>,
     {
-        let pos = NonZeroUsize::new(self.position()).unwrap();
+        let pos = NonZero::<usize>::new(self.position()).unwrap();
 
         assert_eq!(self.lazy_state, LazyState::NoNode);
         self.lazy_state = LazyState::NodeStart(pos);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 4d0a6cb60ee..81d834e0456 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -37,7 +37,7 @@ use rustc_target::abi::{FieldIdx, VariantIdx};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 
 use std::marker::PhantomData;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 
 use decoder::DecodeContext;
 pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
@@ -83,7 +83,7 @@ pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_V
 /// order than they were encoded in.
 #[must_use]
 struct LazyValue<T> {
-    position: NonZeroUsize,
+    position: NonZero<usize>,
     _marker: PhantomData<fn() -> T>,
 }
 
@@ -92,7 +92,7 @@ impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyValue<T> {
 }
 
 impl<T> LazyValue<T> {
-    fn from_position(position: NonZeroUsize) -> LazyValue<T> {
+    fn from_position(position: NonZero<usize>) -> LazyValue<T> {
         LazyValue { position, _marker: PhantomData }
     }
 }
@@ -108,7 +108,7 @@ impl<T> LazyValue<T> {
 /// the minimal distance the length of the sequence, i.e.
 /// it's assumed there's no 0-byte element in the sequence.
 struct LazyArray<T> {
-    position: NonZeroUsize,
+    position: NonZero<usize>,
     num_elems: usize,
     _marker: PhantomData<fn() -> T>,
 }
@@ -119,12 +119,12 @@ impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyArray<T> {
 
 impl<T> Default for LazyArray<T> {
     fn default() -> LazyArray<T> {
-        LazyArray::from_position_and_num_elems(NonZeroUsize::new(1).unwrap(), 0)
+        LazyArray::from_position_and_num_elems(NonZero::<usize>::new(1).unwrap(), 0)
     }
 }
 
 impl<T> LazyArray<T> {
-    fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray<T> {
+    fn from_position_and_num_elems(position: NonZero<usize>, num_elems: usize) -> LazyArray<T> {
         LazyArray { position, num_elems, _marker: PhantomData }
     }
 }
@@ -135,7 +135,7 @@ impl<T> LazyArray<T> {
 /// `LazyArray<T>`, but without requiring encoding or decoding all the values
 /// eagerly and in-order.
 struct LazyTable<I, T> {
-    position: NonZeroUsize,
+    position: NonZero<usize>,
     /// The encoded size of the elements of a table is selected at runtime to drop
     /// trailing zeroes. This is the number of bytes used for each table element.
     width: usize,
@@ -150,7 +150,7 @@ impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for LazyTable<I,
 
 impl<I, T> LazyTable<I, T> {
     fn from_position_and_encoded_size(
-        position: NonZeroUsize,
+        position: NonZero<usize>,
         width: usize,
         len: usize,
     ) -> LazyTable<I, T> {
@@ -187,11 +187,11 @@ enum LazyState {
 
     /// Inside a metadata node, and before any `Lazy`s.
     /// The position is that of the node itself.
-    NodeStart(NonZeroUsize),
+    NodeStart(NonZero<usize>),
 
     /// Inside a metadata node, with a previous `Lazy`s.
     /// The position is where that previous `Lazy` would start.
-    Previous(NonZeroUsize),
+    Previous(NonZero<usize>),
 }
 
 type SyntaxContextTable = LazyTable<u32, Option<LazyValue<SyntaxContextData>>>;
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 306bf07a976..00752ad15a3 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -339,7 +339,7 @@ impl<T> FixedSizeEncoding for Option<LazyValue<T>> {
 
     #[inline]
     fn from_bytes(b: &[u8; 8]) -> Self {
-        let position = NonZeroUsize::new(u64::from_bytes(b) as usize)?;
+        let position = NonZero::<usize>::new(u64::from_bytes(b) as usize)?;
         Some(LazyValue::from_position(position))
     }
 
@@ -366,7 +366,7 @@ impl<T> LazyArray<T> {
     }
 
     fn from_bytes_impl(position: &[u8; 8], meta: &[u8; 8]) -> Option<LazyArray<T>> {
-        let position = NonZeroUsize::new(u64::from_bytes(position) as usize)?;
+        let position = NonZero::<usize>::new(u64::from_bytes(position) as usize)?;
         let len = u64::from_bytes(meta) as usize;
         Some(LazyArray::from_position_and_num_elems(position, len))
     }
@@ -497,7 +497,7 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui
         }
 
         LazyTable::from_position_and_encoded_size(
-            NonZeroUsize::new(pos).unwrap(),
+            NonZero::<usize>::new(pos).unwrap(),
             width,
             self.blocks.len(),
         )
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 2aaece1060a..9c0846e9fb1 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -34,6 +34,7 @@
 #![feature(discriminant_kind)]
 #![feature(exhaustive_patterns)]
 #![feature(coroutines)]
+#![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(inline_const)]
 #![feature(iter_from_coroutine)]
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index afb6937b43b..15ef00629b9 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -21,7 +21,7 @@ use rustc_session::parse::feature_err_issue;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 #[derive(PartialEq, Clone, Copy, Debug)]
 pub enum StabilityLevel {
@@ -102,7 +102,7 @@ pub fn report_unstable(
     sess: &Session,
     feature: Symbol,
     reason: Option<Symbol>,
-    issue: Option<NonZeroU32>,
+    issue: Option<NonZero<u32>>,
     suggestion: Option<(Span, String, String, Applicability)>,
     is_soft: bool,
     span: Span,
@@ -235,7 +235,7 @@ pub enum EvalResult {
     Deny {
         feature: Symbol,
         reason: Option<Symbol>,
-        issue: Option<NonZeroU32>,
+        issue: Option<NonZero<u32>>,
         suggestion: Option<(Span, String, String, Applicability)>,
         is_soft: bool,
     },
@@ -433,7 +433,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 // the `-Z force-unstable-if-unmarked` flag present (we're
                 // compiling a compiler crate), then let this missing feature
                 // annotation slide.
-                if feature == sym::rustc_private && issue == NonZeroU32::new(27812) {
+                if feature == sym::rustc_private && issue == NonZero::<u32>::new(27812) {
                     if self.sess.opts.unstable_opts.force_unstable_if_unmarked {
                         return EvalResult::Allow;
                     }
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 0da3524e055..4ef02a86e30 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -122,7 +122,7 @@ mod value;
 use std::fmt;
 use std::io;
 use std::io::{Read, Write};
-use std::num::{NonZeroU32, NonZeroU64};
+use std::num::NonZero;
 use std::sync::atomic::{AtomicU32, Ordering};
 
 use rustc_ast::LitKind;
@@ -205,7 +205,7 @@ pub enum LitToConstError {
 }
 
 #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub struct AllocId(pub NonZeroU64);
+pub struct AllocId(pub NonZero<u64>);
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
 // all the Miri types.
@@ -260,7 +260,7 @@ pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>>(
 }
 
 // Used to avoid infinite recursion when decoding cyclic allocations.
-type DecodingSessionId = NonZeroU32;
+type DecodingSessionId = NonZero<u32>;
 
 #[derive(Clone)]
 enum State {
@@ -500,7 +500,7 @@ impl<'tcx> AllocMap<'tcx> {
         AllocMap {
             alloc_map: Default::default(),
             dedup: Default::default(),
-            next_id: AllocId(NonZeroU64::new(1).unwrap()),
+            next_id: AllocId(NonZero::<u64>::new(1).unwrap()),
         }
     }
     fn reserve(&mut self) -> AllocId {
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index dabf6297aa9..15e12c45679 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -3,7 +3,7 @@ use super::{AllocId, InterpResult};
 use rustc_macros::HashStable;
 use rustc_target::abi::{HasDataLayout, Size};
 
-use std::{fmt, num::NonZeroU64};
+use std::{fmt, num::NonZero};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Pointer arithmetic
@@ -129,7 +129,7 @@ pub trait Provenance: Copy + fmt::Debug + 'static {
 /// The type of provenance in the compile-time interpreter.
 /// This is a packed representation of an `AllocId` and an `immutable: bool`.
 #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub struct CtfeProvenance(NonZeroU64);
+pub struct CtfeProvenance(NonZero<u64>);
 
 impl From<AllocId> for CtfeProvenance {
     fn from(value: AllocId) -> Self {
@@ -155,7 +155,7 @@ impl CtfeProvenance {
     /// Returns the `AllocId` of this provenance.
     #[inline(always)]
     pub fn alloc_id(self) -> AllocId {
-        AllocId(NonZeroU64::new(self.0.get() & !IMMUTABLE_MASK).unwrap())
+        AllocId(NonZero::<u64>::new(self.0.get() & !IMMUTABLE_MASK).unwrap())
     }
 
     /// Returns whether this provenance is immutable.
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 515d564e81d..15f69d2333c 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -4,7 +4,7 @@ use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_target::abi::Size;
 use std::fmt;
-use std::num::NonZeroU8;
+use std::num::NonZero;
 
 use crate::ty::TyCtxt;
 
@@ -132,7 +132,7 @@ pub struct ScalarInt {
     /// The first `size` bytes of `data` are the value.
     /// Do not try to read less or more bytes than that. The remaining bytes must be 0.
     data: u128,
-    size: NonZeroU8,
+    size: NonZero<u8>,
 }
 
 // Cannot derive these, as the derives take references to the fields, and we
@@ -161,14 +161,14 @@ impl<D: Decoder> Decodable<D> for ScalarInt {
         let mut data = [0u8; 16];
         let size = d.read_u8();
         data[..size as usize].copy_from_slice(d.read_raw_bytes(size as usize));
-        ScalarInt { data: u128::from_le_bytes(data), size: NonZeroU8::new(size).unwrap() }
+        ScalarInt { data: u128::from_le_bytes(data), size: NonZero::<u8>::new(size).unwrap() }
     }
 }
 
 impl ScalarInt {
-    pub const TRUE: ScalarInt = ScalarInt { data: 1_u128, size: NonZeroU8::new(1).unwrap() };
+    pub const TRUE: ScalarInt = ScalarInt { data: 1_u128, size: NonZero::<u8>::new(1).unwrap() };
 
-    pub const FALSE: ScalarInt = ScalarInt { data: 0_u128, size: NonZeroU8::new(1).unwrap() };
+    pub const FALSE: ScalarInt = ScalarInt { data: 0_u128, size: NonZero::<u8>::new(1).unwrap() };
 
     #[inline]
     pub fn size(self) -> Size {
@@ -196,7 +196,7 @@ impl ScalarInt {
 
     #[inline]
     pub fn null(size: Size) -> Self {
-        Self { data: 0, size: NonZeroU8::new(size.bytes() as u8).unwrap() }
+        Self { data: 0, size: NonZero::<u8>::new(size.bytes() as u8).unwrap() }
     }
 
     #[inline]
@@ -208,7 +208,7 @@ impl ScalarInt {
     pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
         let data = i.into();
         if size.truncate(data) == data {
-            Some(Self { data, size: NonZeroU8::new(size.bytes() as u8).unwrap() })
+            Some(Self { data, size: NonZero::<u8>::new(size.bytes() as u8).unwrap() })
         } else {
             None
         }
@@ -220,7 +220,7 @@ impl ScalarInt {
         // `into` performed sign extension, we have to truncate
         let truncated = size.truncate(i as u128);
         if size.sign_extend(truncated) as i128 == i {
-            Some(Self { data: truncated, size: NonZeroU8::new(size.bytes() as u8).unwrap() })
+            Some(Self { data: truncated, size: NonZero::<u8>::new(size.bytes() as u8).unwrap() })
         } else {
             None
         }
@@ -388,7 +388,7 @@ macro_rules! from {
                 fn from(u: $ty) -> Self {
                     Self {
                         data: u128::from(u),
-                        size: NonZeroU8::new(std::mem::size_of::<$ty>() as u8).unwrap(),
+                        size: NonZero::<u8>::new(std::mem::size_of::<$ty>() as u8).unwrap(),
                     }
                 }
             }
@@ -427,7 +427,10 @@ impl TryFrom<ScalarInt> for bool {
 impl From<char> for ScalarInt {
     #[inline]
     fn from(c: char) -> Self {
-        Self { data: c as u128, size: NonZeroU8::new(std::mem::size_of::<char>() as u8).unwrap() }
+        Self {
+            data: c as u128,
+            size: NonZero::<u8>::new(std::mem::size_of::<char>() as u8).unwrap(),
+        }
     }
 }
 
@@ -454,7 +457,7 @@ impl From<Single> for ScalarInt {
     #[inline]
     fn from(f: Single) -> Self {
         // We trust apfloat to give us properly truncated data.
-        Self { data: f.to_bits(), size: NonZeroU8::new((Single::BITS / 8) as u8).unwrap() }
+        Self { data: f.to_bits(), size: NonZero::<u8>::new((Single::BITS / 8) as u8).unwrap() }
     }
 }
 
@@ -470,7 +473,7 @@ impl From<Double> for ScalarInt {
     #[inline]
     fn from(f: Double) -> Self {
         // We trust apfloat to give us properly truncated data.
-        Self { data: f.to_bits(), size: NonZeroU8::new((Double::BITS / 8) as u8).unwrap() }
+        Self { data: f.to_bits(), size: NonZero::<u8>::new((Double::BITS / 8) as u8).unwrap() }
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 84de12b23a0..c931c2064b0 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -18,7 +18,7 @@ use core::intrinsics;
 use std::cmp::Ordering;
 use std::marker::PhantomData;
 use std::mem;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::ops::{ControlFlow, Deref};
 use std::ptr::NonNull;
 
@@ -144,7 +144,7 @@ impl<'tcx> GenericArg<'tcx> {
     #[inline]
     pub fn unpack(self) -> GenericArgKind<'tcx> {
         let ptr = unsafe {
-            self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
+            self.ptr.map_addr(|addr| NonZero::<usize>::new_unchecked(addr.get() & !TAG_MASK))
         };
         // SAFETY: use of `Interned::new_unchecked` here is ok because these
         // pointers were originally created from `Interned` types in `pack()`,
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 8d8d06b7c0b..d9fa99535b1 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -20,7 +20,7 @@ use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Targ
 
 use std::cmp;
 use std::fmt;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::ops::Bound;
 
 pub trait IntegerExt {
@@ -761,7 +761,7 @@ where
                 };
                 tcx.mk_layout(LayoutS {
                     variants: Variants::Single { index: variant_index },
-                    fields: match NonZeroUsize::new(fields) {
+                    fields: match NonZero::<usize>::new(fields) {
                         Some(fields) => FieldsShape::Union(fields),
                         None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
                     },
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 15bddb2a64f..3eea0d428ee 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -61,7 +61,7 @@ use std::fmt::Debug;
 use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::mem;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::ops::ControlFlow;
 use std::ptr::NonNull;
 use std::{fmt, str};
@@ -618,7 +618,7 @@ impl<'tcx> Term<'tcx> {
     #[inline]
     pub fn unpack(self) -> TermKind<'tcx> {
         let ptr = unsafe {
-            self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
+            self.ptr.map_addr(|addr| NonZero::<usize>::new_unchecked(addr.get() & !TAG_MASK))
         };
         // SAFETY: use of `Interned::new_unchecked` here is ok because these
         // pointers were originally created from `Interned` types in `pack()`,
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index e795537e84a..7227b185f4d 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,6 +8,7 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
+#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(try_blocks)]
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 17ad08b0569..312a136c897 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -27,7 +27,7 @@ use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
 use std::mem::replace;
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 #[derive(PartialEq)]
 enum AnnotationKind {
@@ -645,7 +645,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
             let stability = Stability {
                 level: attr::StabilityLevel::Unstable {
                     reason: UnstableReason::Default,
-                    issue: NonZeroU32::new(27812),
+                    issue: NonZero::<u32>::new(27812),
                     is_soft: false,
                     implied_by: None,
                 },
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 0fe5b9c664a..33116737a42 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -3,6 +3,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![feature(generic_nonzero)]
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
 #![allow(rustc::potential_query_instability, unused_parens)]
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index a827717d9bb..8cbcce986a1 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -30,7 +30,7 @@ use rustc_serialize::Decodable;
 use rustc_serialize::Encodable;
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
-use std::num::NonZeroU64;
+use std::num::NonZero;
 use thin_vec::ThinVec;
 
 #[derive(Copy, Clone)]
@@ -68,7 +68,7 @@ impl QueryContext for QueryCtxt<'_> {
     #[inline]
     fn next_job_id(self) -> QueryJobId {
         QueryJobId(
-            NonZeroU64::new(
+            NonZero::<u64>::new(
                 self.query_system.jobs.fetch_add(1, std::sync::atomic::Ordering::Relaxed),
             )
             .unwrap(),
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 416f556f57d..6a959a99e5d 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -1,5 +1,6 @@
 #![feature(assert_matches)]
 #![feature(core_intrinsics)]
+#![feature(generic_nonzero)]
 #![feature(hash_raw_entry)]
 #![feature(min_specialization)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 8d7c0ca0144..bf89bc7f7c3 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -11,7 +11,7 @@ use rustc_span::Span;
 
 use std::hash::Hash;
 use std::io::Write;
-use std::num::NonZeroU64;
+use std::num::NonZero;
 
 #[cfg(parallel_compiler)]
 use {
@@ -36,7 +36,7 @@ pub type QueryMap = FxHashMap<QueryJobId, QueryJobInfo>;
 
 /// A value uniquely identifying an active query job.
 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
-pub struct QueryJobId(pub NonZeroU64);
+pub struct QueryJobId(pub NonZero<u64>);
 
 impl QueryJobId {
     fn query(self, map: &QueryMap) -> QueryStackFrame {
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 95833f532f4..bb822c611a1 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -11,6 +11,7 @@
 #![feature(associated_type_bounds)]
 #![feature(const_option)]
 #![feature(core_intrinsics)]
+#![feature(generic_nonzero)]
 #![feature(inline_const)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 287e317b10f..a38a4a916fb 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -6,6 +6,7 @@ use std::cell::{Cell, RefCell};
 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
 use std::hash::{BuildHasher, Hash};
 use std::marker::PhantomData;
+use std::num::NonZero;
 use std::path;
 use std::rc::Rc;
 use std::sync::Arc;
@@ -216,15 +217,15 @@ impl<D: Decoder> Decodable<D> for ! {
     }
 }
 
-impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
+impl<S: Encoder> Encodable<S> for NonZero<u32> {
     fn encode(&self, s: &mut S) {
         s.emit_u32(self.get());
     }
 }
 
-impl<D: Decoder> Decodable<D> for ::std::num::NonZeroU32 {
+impl<D: Decoder> Decodable<D> for NonZero<u32> {
     fn decode(d: &mut D) -> Self {
-        ::std::num::NonZeroU32::new(d.read_u32()).unwrap()
+        NonZero::<u32>::new(d.read_u32()).unwrap()
     }
 }
 
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d35f951e2ae..b89dfab2ca9 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3226,7 +3226,7 @@ pub(crate) mod dep_tracking {
     };
     use std::collections::BTreeMap;
     use std::hash::{DefaultHasher, Hash};
-    use std::num::NonZeroUsize;
+    use std::num::NonZero;
     use std::path::PathBuf;
 
     pub trait DepTrackingHash {
@@ -3268,7 +3268,7 @@ pub(crate) mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(
         bool,
         usize,
-        NonZeroUsize,
+        NonZero<usize>,
         u64,
         Hash64,
         String,
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index c36cec6f353..192dbb05530 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -1,4 +1,4 @@
-use std::num::NonZeroU32;
+use std::num::NonZero;
 
 use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
@@ -26,7 +26,7 @@ impl<'a> IntoDiagnostic<'a> for FeatureGateError {
 #[derive(Subdiagnostic)]
 #[note(session_feature_diagnostic_for_issue)]
 pub struct FeatureDiagnosticForIssue {
-    pub n: NonZeroU32,
+    pub n: NonZero<u32>,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 58e1394c090..c63af90a7f3 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,3 +1,4 @@
+#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(lazy_cell)]
 #![feature(option_get_or_insert_default)]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index ea93ac5841f..1a046667bd7 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -21,7 +21,7 @@ use rustc_span::SourceFileHashAlgorithm;
 use std::collections::BTreeMap;
 
 use std::hash::{DefaultHasher, Hasher};
-use std::num::{IntErrorKind, NonZeroUsize};
+use std::num::{IntErrorKind, NonZero};
 use std::path::PathBuf;
 use std::str;
 
@@ -617,7 +617,7 @@ mod parse {
     pub(crate) fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool {
         match v.and_then(|s| s.parse().ok()) {
             Some(0) => {
-                *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get);
+                *slot = std::thread::available_parallelism().map_or(1, NonZero::<usize>::get);
                 true
             }
             Some(i) => {
@@ -991,7 +991,10 @@ mod parse {
         true
     }
 
-    pub(crate) fn parse_treat_err_as_bug(slot: &mut Option<NonZeroUsize>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_treat_err_as_bug(
+        slot: &mut Option<NonZero<usize>>,
+        v: Option<&str>,
+    ) -> bool {
         match v {
             Some(s) => match s.parse() {
                 Ok(val) => {
@@ -1004,7 +1007,7 @@ mod parse {
                 }
             },
             None => {
-                *slot = NonZeroUsize::new(1);
+                *slot = NonZero::<usize>::new(1);
                 true
             }
         }
@@ -1950,7 +1953,7 @@ written to standard error output)"),
         "translate remapped paths into local paths when possible (default: yes)"),
     trap_unreachable: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)"),
-    treat_err_as_bug: Option<NonZeroUsize> = (None, parse_treat_err_as_bug, [TRACKED],
+    treat_err_as_bug: Option<NonZero<usize>> = (None, parse_treat_err_as_bug, [TRACKED],
         "treat the `val`th error that occurs as bug (default if not specified: 0 - don't treat errors as bugs. \
         default if specified without a value: 1 - treat the first error as bug)"),
     trim_diagnostic_paths: bool = (true, parse_bool, [UNTRACKED],
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 00a101541c5..3a82fb0df88 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -147,7 +147,7 @@ use core::alloc::Allocator;
 use core::fmt;
 use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen};
 use core::mem::{self, swap, ManuallyDrop};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::ops::{Deref, DerefMut};
 use core::ptr;
 
@@ -296,7 +296,7 @@ pub struct PeekMut<
     heap: &'a mut BinaryHeap<T, A>,
     // If a set_len + sift_down are required, this is Some. If a &mut T has not
     // yet been exposed to peek_mut()'s caller, it's None.
-    original_len: Option<NonZeroUsize>,
+    original_len: Option<NonZero<usize>>,
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
@@ -350,7 +350,7 @@ impl<T: Ord, A: Allocator> DerefMut for PeekMut<'_, T, A> {
             // the standard library as "leak amplification".
             unsafe {
                 // SAFETY: len > 1 so len != 0.
-                self.original_len = Some(NonZeroUsize::new_unchecked(len));
+                self.original_len = Some(NonZero::<usize>::new_unchecked(len));
                 // SAFETY: len > 1 so all this does for now is leak elements,
                 // which is safe.
                 self.heap.data.set_len(1);
@@ -1576,8 +1576,8 @@ unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
 #[unstable(issue = "none", feature = "inplace_iteration")]
 #[doc(hidden)]
 unsafe impl<I, A: Allocator> InPlaceIterable for IntoIter<I, A> {
-    const EXPAND_BY: Option<NonZeroUsize> = NonZeroUsize::new(1);
-    const MERGE_BY: Option<NonZeroUsize> = NonZeroUsize::new(1);
+    const EXPAND_BY: Option<NonZero<usize>> = NonZero::<usize>::new(1);
+    const MERGE_BY: Option<NonZero<usize>> = NonZero::<usize>::new(1);
 }
 
 unsafe impl<I> AsVecIntoIter for IntoIter<I> {
diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs
index d9e274df0f5..02ab3f79b06 100644
--- a/library/alloc/src/collections/vec_deque/into_iter.rs
+++ b/library/alloc/src/collections/vec_deque/into_iter.rs
@@ -1,5 +1,5 @@
 use core::iter::{FusedIterator, TrustedLen};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::{array, fmt, mem::MaybeUninit, ops::Try, ptr};
 
 use crate::alloc::{Allocator, Global};
@@ -54,7 +54,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let len = self.inner.len;
         let rem = if len < n {
             self.inner.clear();
@@ -63,7 +63,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
             self.inner.drain(..n);
             0
         };
-        NonZeroUsize::new(rem).map_or(Ok(()), Err)
+        NonZero::<usize>::new(rem).map_or(Ok(()), Err)
     }
 
     #[inline]
@@ -183,7 +183,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let len = self.inner.len;
         let rem = if len < n {
             self.inner.clear();
@@ -192,7 +192,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
             self.inner.truncate(len - n);
             0
         };
-        NonZeroUsize::new(rem).map_or(Ok(()), Err)
+        NonZero::<usize>::new(rem).map_or(Ok(()), Err)
     }
 
     fn try_rfold<B, F, R>(&mut self, mut init: B, mut f: F) -> R
diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs
index 646a2a991e7..5a5e7f70854 100644
--- a/library/alloc/src/collections/vec_deque/iter.rs
+++ b/library/alloc/src/collections/vec_deque/iter.rs
@@ -1,5 +1,5 @@
 use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::ops::Try;
 use core::{fmt, mem, slice};
 
@@ -56,7 +56,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
         }
     }
 
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let remaining = self.i1.advance_by(n);
         match remaining {
             Ok(()) => return Ok(()),
@@ -128,7 +128,7 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
         }
     }
 
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         match self.i2.advance_back_by(n) {
             Ok(()) => return Ok(()),
             Err(n) => {
diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs
index 7defbb1090f..5061931afb7 100644
--- a/library/alloc/src/collections/vec_deque/iter_mut.rs
+++ b/library/alloc/src/collections/vec_deque/iter_mut.rs
@@ -1,5 +1,5 @@
 use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::ops::Try;
 use core::{fmt, mem, slice};
 
@@ -48,7 +48,7 @@ impl<'a, T> Iterator for IterMut<'a, T> {
         }
     }
 
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         match self.i1.advance_by(n) {
             Ok(()) => return Ok(()),
             Err(remaining) => {
@@ -119,7 +119,7 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
         }
     }
 
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         match self.i2.advance_back_by(n) {
             Ok(()) => return Ok(()),
             Err(remaining) => {
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 3341b564d1f..b84273848ee 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -128,6 +128,7 @@
 #![feature(extend_one)]
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
+#![feature(generic_nonzero)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hint_assert_unchecked)]
 #![feature(inline_const)]
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs
index 5dc3c69e493..07eb91c9005 100644
--- a/library/alloc/src/vec/in_place_collect.rs
+++ b/library/alloc/src/vec/in_place_collect.rs
@@ -160,14 +160,14 @@ use core::alloc::Layout;
 use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
 use core::marker::PhantomData;
 use core::mem::{self, ManuallyDrop, SizedTypeProperties};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::ptr::{self, NonNull};
 
 use super::{InPlaceDrop, InPlaceDstDataSrcBufDrop, SpecFromIter, SpecFromIterNested, Vec};
 
 const fn in_place_collectible<DEST, SRC>(
-    step_merge: Option<NonZeroUsize>,
-    step_expand: Option<NonZeroUsize>,
+    step_merge: Option<NonZero<usize>>,
+    step_expand: Option<NonZero<usize>>,
 ) -> bool {
     // Require matching alignments because an alignment-changing realloc is inefficient on many
     // system allocators and better implementations would require the unstable Allocator trait.
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index 7800560da94..76d1b7b72a1 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -12,7 +12,7 @@ use core::iter::{
 };
 use core::marker::PhantomData;
 use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 #[cfg(not(no_global_oom_handling))]
 use core::ops::Deref;
 use core::ptr::{self, NonNull};
@@ -234,7 +234,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let step_size = self.len().min(n);
         let to_drop = ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), step_size);
         if T::IS_ZST {
@@ -248,7 +248,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
         unsafe {
             ptr::drop_in_place(to_drop);
         }
-        NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - step_size).map_or(Ok(()), Err)
     }
 
     #[inline]
@@ -336,7 +336,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let step_size = self.len().min(n);
         if T::IS_ZST {
             // SAFETY: same as for advance_by()
@@ -350,7 +350,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
         unsafe {
             ptr::drop_in_place(to_drop);
         }
-        NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - step_size).map_or(Ok(()), Err)
     }
 }
 
@@ -457,8 +457,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
 #[unstable(issue = "none", feature = "inplace_iteration")]
 #[doc(hidden)]
 unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {
-    const EXPAND_BY: Option<NonZeroUsize> = NonZeroUsize::new(1);
-    const MERGE_BY: Option<NonZeroUsize> = NonZeroUsize::new(1);
+    const EXPAND_BY: Option<NonZero<usize>> = NonZero::<usize>::new(1);
+    const MERGE_BY: Option<NonZero<usize>> = NonZero::<usize>::new(1);
 }
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index ca17dab55b0..c4e89a58a05 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -13,6 +13,7 @@
 #![feature(core_intrinsics)]
 #![feature(extract_if)]
 #![feature(exact_size_is_empty)]
+#![feature(generic_nonzero)]
 #![feature(linked_list_cursors)]
 #![feature(map_try_insert)]
 #![feature(new_uninit)]
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 38a68df79cc..e872ace883c 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1,5 +1,5 @@
 use core::alloc::{Allocator, Layout};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::ptr::NonNull;
 use core::{assert_eq, assert_ne};
 use std::alloc::System;
@@ -1089,9 +1089,9 @@ fn test_into_iter_advance_by() {
     assert_eq!(i.advance_back_by(1), Ok(()));
     assert_eq!(i.as_slice(), [2, 3, 4]);
 
-    assert_eq!(i.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 3).unwrap()));
+    assert_eq!(i.advance_back_by(usize::MAX), Err(NonZero::<usize>::new(usize::MAX - 3).unwrap()));
 
-    assert_eq!(i.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap()));
+    assert_eq!(i.advance_by(usize::MAX), Err(NonZero::<usize>::new(usize::MAX).unwrap()));
 
     assert_eq!(i.advance_by(0), Ok(()));
     assert_eq!(i.advance_back_by(0), Ok(()));
@@ -1192,7 +1192,7 @@ fn test_from_iter_specialization_with_iterator_adapters() {
         .map(|(a, b)| a + b)
         .map_while(Option::Some)
         .skip(1)
-        .map(|e| if e != usize::MAX { Ok(std::num::NonZeroUsize::new(e)) } else { Err(()) });
+        .map(|e| if e != usize::MAX { Ok(NonZero::<usize>::new(e)) } else { Err(()) });
     assert_in_place_trait(&iter);
     let sink = iter.collect::<Result<Vec<_>, _>>().unwrap();
     let sinkptr = sink.as_ptr();
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index f6fb1f73e5c..079750abd69 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -1,4 +1,4 @@
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use std::assert_matches::assert_matches;
 use std::collections::TryReserveErrorKind::*;
 use std::collections::{vec_deque::Drain, VecDeque};
@@ -445,9 +445,9 @@ fn test_into_iter() {
         assert_eq!(it.next_back(), Some(3));
 
         let mut it = VecDeque::from(vec![1, 2, 3, 4, 5]).into_iter();
-        assert_eq!(it.advance_by(10), Err(NonZeroUsize::new(5).unwrap()));
+        assert_eq!(it.advance_by(10), Err(NonZero::<usize>::new(5).unwrap()));
         let mut it = VecDeque::from(vec![1, 2, 3, 4, 5]).into_iter();
-        assert_eq!(it.advance_back_by(10), Err(NonZeroUsize::new(5).unwrap()));
+        assert_eq!(it.advance_back_by(10), Err(NonZero::<usize>::new(5).unwrap()));
     }
 }
 
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index 2b22488b8ff..e50ae1b0d70 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -1,6 +1,6 @@
 //! Defines the `IntoIter` owned iterator for arrays.
 
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::{
     fmt,
     intrinsics::transmute_unchecked,
@@ -280,7 +280,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
         self.next_back()
     }
 
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         // This also moves the start, which marks them as conceptually "dropped",
         // so if anything goes bad then our drop impl won't double-free them.
         let range_to_drop = self.alive.take_prefix(n);
@@ -292,7 +292,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
             ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
         }
 
-        NonZeroUsize::new(remaining).map_or(Ok(()), Err)
+        NonZero::<usize>::new(remaining).map_or(Ok(()), Err)
     }
 
     #[inline]
@@ -335,7 +335,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
         })
     }
 
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         // This also moves the end, which marks them as conceptually "dropped",
         // so if anything goes bad then our drop impl won't double-free them.
         let range_to_drop = self.alive.take_suffix(n);
@@ -347,7 +347,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
             ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
         }
 
-        NonZeroUsize::new(remaining).map_or(Ok(()), Err)
+        NonZero::<usize>::new(remaining).map_or(Ok(()), Err)
     }
 }
 
diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs
index 02867789b79..c29e5565d51 100644
--- a/library/core/src/ascii.rs
+++ b/library/core/src/ascii.rs
@@ -12,7 +12,7 @@
 use crate::escape;
 use crate::fmt;
 use crate::iter::FusedIterator;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 mod ascii_char;
 #[unstable(feature = "ascii_char", issue = "110998")]
@@ -133,7 +133,7 @@ impl Iterator for EscapeDefault {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.0.advance_by(n)
     }
 }
@@ -146,7 +146,7 @@ impl DoubleEndedIterator for EscapeDefault {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.0.advance_back_by(n)
     }
 }
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index 5c42912874c..12bca0b438c 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -43,7 +43,7 @@ use crate::error::Error;
 use crate::escape;
 use crate::fmt::{self, Write};
 use crate::iter::FusedIterator;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 pub(crate) use self::methods::EscapeDebugExtArgs;
 
@@ -185,7 +185,7 @@ impl Iterator for EscapeUnicode {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.0.advance_by(n)
     }
 }
@@ -260,7 +260,7 @@ impl Iterator for EscapeDefault {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.0.advance_by(n)
     }
 }
diff --git a/library/core/src/cmp/bytewise.rs b/library/core/src/cmp/bytewise.rs
index 2548d9e24c9..b19eef8e255 100644
--- a/library/core/src/cmp/bytewise.rs
+++ b/library/core/src/cmp/bytewise.rs
@@ -33,7 +33,7 @@ is_bytewise_comparable!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128,
 // so we can compare them directly.
 is_bytewise_comparable!(bool, char, super::Ordering);
 
-// SAFETY: Similarly, the non-zero types have a niche, but no undef and no pointers,
+// SAFETY: Similarly, the `NonZero` type has a niche, but no undef and no pointers,
 // and they compare like their underlying numeric type.
 is_bytewise_comparable!(
     NonZeroU8,
@@ -50,7 +50,7 @@ is_bytewise_comparable!(
     NonZeroIsize,
 );
 
-// SAFETY: The NonZero types have the "null" optimization guaranteed, and thus
+// SAFETY: The `NonZero` type has the "null" optimization guaranteed, and thus
 // are also safe to equality-compare bitwise inside an `Option`.
 // 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.
diff --git a/library/core/src/escape.rs b/library/core/src/escape.rs
index 60b5df752ca..143e277283e 100644
--- a/library/core/src/escape.rs
+++ b/library/core/src/escape.rs
@@ -1,7 +1,7 @@
 //! Helper code for character escaping.
 
 use crate::ascii;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Range;
 
 const HEX_DIGITS: [ascii::Char; 16] = *b"0123456789abcdef".as_ascii().unwrap();
@@ -106,11 +106,11 @@ impl<const N: usize> EscapeIterInner<N> {
         self.alive.next_back().map(|i| self.data[usize::from(i)].to_u8())
     }
 
-    pub fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    pub fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.alive.advance_by(n)
     }
 
-    pub fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    pub fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.alive.advance_back_by(n)
     }
 }
diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs
index 946d0051cce..2e437b41dce 100644
--- a/library/core/src/iter/adapters/array_chunks.rs
+++ b/library/core/src/iter/adapters/array_chunks.rs
@@ -3,7 +3,7 @@ use crate::iter::adapters::SourceIter;
 use crate::iter::{
     ByRefSized, FusedIterator, InPlaceIterable, TrustedFused, TrustedRandomAccessNoCoerce,
 };
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, NeverShortCircuit, Try};
 
 /// An iterator over `N` elements of the iterator at a time.
@@ -253,9 +253,9 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable + Iterator, const N: usize> InPlaceIterable for ArrayChunks<I, N> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = const {
-        match (I::MERGE_BY, NonZeroUsize::new(N)) {
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = const {
+        match (I::MERGE_BY, NonZero::<usize>::new(N)) {
             (Some(m), Some(n)) => m.checked_mul(n),
             _ => None,
         }
diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs
index 4e0e19ddc78..d084bede1eb 100644
--- a/library/core/src/iter/adapters/by_ref_sized.rs
+++ b/library/core/src/iter/adapters/by_ref_sized.rs
@@ -1,4 +1,4 @@
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{NeverShortCircuit, Try};
 
 /// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics.
@@ -27,7 +27,7 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         I::advance_by(self.0, n)
     }
 
@@ -63,7 +63,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         I::advance_back_by(self.0, n)
     }
 
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index c748336cd7f..7edfee7bf6c 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -1,5 +1,5 @@
 use crate::iter::{FusedIterator, TrustedLen};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 
 /// An iterator that links two iterators together, in a chain.
@@ -96,7 +96,7 @@ where
     }
 
     #[inline]
-    fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
         if let Some(ref mut a) = self.a {
             n = match a.advance_by(n) {
                 Ok(()) => return Ok(()),
@@ -110,7 +110,7 @@ where
             // we don't fuse the second iterator
         }
 
-        NonZeroUsize::new(n).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n).map_or(Ok(()), Err)
     }
 
     #[inline]
@@ -182,7 +182,7 @@ where
     }
 
     #[inline]
-    fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
         if let Some(ref mut b) = self.b {
             n = match b.advance_back_by(n) {
                 Ok(()) => return Ok(()),
@@ -196,7 +196,7 @@ where
             // we don't fuse the second iterator
         }
 
-        NonZeroUsize::new(n).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n).map_or(Ok(()), Err)
     }
 
     #[inline]
diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs
index 3de91267cf5..1a106ef9794 100644
--- a/library/core/src/iter/adapters/cloned.rs
+++ b/library/core/src/iter/adapters/cloned.rs
@@ -3,7 +3,7 @@ use crate::iter::adapters::{
 };
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
 use crate::ops::Try;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 /// An iterator that clones the elements of an underlying iterator.
 ///
@@ -185,6 +185,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable> InPlaceIterable for Cloned<I> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs
index 52a5add1132..6d82d1581f7 100644
--- a/library/core/src/iter/adapters/copied.rs
+++ b/library/core/src/iter/adapters/copied.rs
@@ -4,7 +4,7 @@ use crate::iter::adapters::{
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
 use crate::mem::MaybeUninit;
 use crate::mem::SizedTypeProperties;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 use crate::{array, ptr};
 
@@ -90,7 +90,7 @@ where
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.it.advance_by(n)
     }
 
@@ -131,7 +131,7 @@ where
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.it.advance_back_by(n)
     }
 }
@@ -272,6 +272,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable> InPlaceIterable for Copied<I> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/cycle.rs b/library/core/src/iter/adapters/cycle.rs
index 51bd09b6eff..7919c040dba 100644
--- a/library/core/src/iter/adapters/cycle.rs
+++ b/library/core/src/iter/adapters/cycle.rs
@@ -1,4 +1,4 @@
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::{iter::FusedIterator, ops::Try};
 
 /// An iterator that repeats endlessly.
@@ -82,7 +82,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let mut n = match self.iter.advance_by(n) {
             Ok(()) => return Ok(()),
             Err(rem) => rem.get(),
@@ -97,7 +97,7 @@ where
             };
         }
 
-        NonZeroUsize::new(n).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n).map_or(Ok(()), Err)
     }
 
     // No `fold` override, because `fold` doesn't make much sense for `Cycle`,
diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs
index 92f465ccdb4..ef46040f0a7 100644
--- a/library/core/src/iter/adapters/enumerate.rs
+++ b/library/core/src/iter/adapters/enumerate.rs
@@ -2,7 +2,7 @@ use crate::iter::adapters::{
     zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
 };
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 
 /// An iterator that yields the current count and the element during iteration.
@@ -115,7 +115,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let remaining = self.iter.advance_by(n);
         let advanced = match remaining {
             Ok(()) => n,
@@ -206,7 +206,7 @@ where
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         // we do not need to update the count since that only tallies the number of items
         // consumed from the front. consuming items from the back can never reduce that.
         self.iter.advance_back_by(n)
@@ -265,8 +265,8 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
 
 #[stable(feature = "default_iters", since = "1.70.0")]
diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs
index 882f3e3bc60..a7f1fde6975 100644
--- a/library/core/src/iter/adapters/filter.rs
+++ b/library/core/src/iter/adapters/filter.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedFused};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 use core::array;
 use core::mem::{ManuallyDrop, MaybeUninit};
@@ -209,6 +209,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs
index 81ac0eaa67e..64bd5b3e2b6 100644
--- a/library/core/src/iter/adapters/filter_map.rs
+++ b/library/core/src/iter/adapters/filter_map.rs
@@ -1,6 +1,6 @@
 use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedFused};
 use crate::mem::{ManuallyDrop, MaybeUninit};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 use crate::{array, fmt};
 
@@ -210,6 +210,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 7d6f746845e..42396157d86 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -4,7 +4,7 @@ use crate::iter::{
     TrustedLen,
 };
 use crate::iter::{Once, OnceWith};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 use crate::result;
 use crate::{array, fmt, option};
@@ -90,7 +90,7 @@ where
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.inner.advance_by(n)
     }
 
@@ -135,7 +135,7 @@ where
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.inner.advance_back_by(n)
     }
 }
@@ -165,13 +165,13 @@ where
     I: InPlaceIterable,
     U: BoundedSize + IntoIterator,
 {
-    const EXPAND_BY: Option<NonZeroUsize> = const {
+    const EXPAND_BY: Option<NonZero<usize>> = const {
         match (I::EXPAND_BY, U::UPPER_BOUND) {
             (Some(m), Some(n)) => m.checked_mul(n),
             _ => None,
         }
     };
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
@@ -200,7 +200,7 @@ where
 #[rustc_specialization_trait]
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe trait BoundedSize {
-    const UPPER_BOUND: Option<NonZeroUsize> = NonZeroUsize::new(1);
+    const UPPER_BOUND: Option<NonZero<usize>> = NonZero::<usize>::new(1);
 }
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
@@ -217,31 +217,31 @@ unsafe impl<T> BoundedSize for Once<T> {}
 unsafe impl<T> BoundedSize for OnceWith<T> {}
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<T, const N: usize> BoundedSize for [T; N] {
-    const UPPER_BOUND: Option<NonZeroUsize> = NonZeroUsize::new(N);
+    const UPPER_BOUND: Option<NonZero<usize>> = NonZero::<usize>::new(N);
 }
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<T, const N: usize> BoundedSize for array::IntoIter<T, N> {
-    const UPPER_BOUND: Option<NonZeroUsize> = NonZeroUsize::new(N);
+    const UPPER_BOUND: Option<NonZero<usize>> = NonZero::<usize>::new(N);
 }
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: BoundedSize, P> BoundedSize for Filter<I, P> {
-    const UPPER_BOUND: Option<NonZeroUsize> = I::UPPER_BOUND;
+    const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND;
 }
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: BoundedSize, P> BoundedSize for FilterMap<I, P> {
-    const UPPER_BOUND: Option<NonZeroUsize> = I::UPPER_BOUND;
+    const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND;
 }
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: BoundedSize, F> BoundedSize for Map<I, F> {
-    const UPPER_BOUND: Option<NonZeroUsize> = I::UPPER_BOUND;
+    const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND;
 }
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: BoundedSize> BoundedSize for Copied<I> {
-    const UPPER_BOUND: Option<NonZeroUsize> = I::UPPER_BOUND;
+    const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND;
 }
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: BoundedSize> BoundedSize for Cloned<I> {
-    const UPPER_BOUND: Option<NonZeroUsize> = I::UPPER_BOUND;
+    const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND;
 }
 
 /// An iterator that flattens one level of nesting in an iterator of things
@@ -322,7 +322,7 @@ where
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.inner.advance_by(n)
     }
 
@@ -367,7 +367,7 @@ where
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.inner.advance_back_by(n)
     }
 }
@@ -394,13 +394,13 @@ where
     I: InPlaceIterable + Iterator,
     <I as Iterator>::Item: IntoIterator + BoundedSize,
 {
-    const EXPAND_BY: Option<NonZeroUsize> = const {
+    const EXPAND_BY: Option<NonZero<usize>> = const {
         match (I::EXPAND_BY, I::Item::UPPER_BOUND) {
             (Some(m), Some(n)) => m.checked_mul(n),
             _ => None,
         }
     };
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
@@ -669,7 +669,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         #[inline]
         #[rustc_inherit_overflow_checks]
         fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
@@ -680,7 +680,9 @@ where
         }
 
         match self.iter_try_fold(n, advance) {
-            ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err),
+            ControlFlow::Continue(remaining) => {
+                NonZero::<usize>::new(remaining).map_or(Ok(()), Err)
+            }
             _ => Ok(()),
         }
     }
@@ -759,7 +761,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         #[inline]
         #[rustc_inherit_overflow_checks]
         fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
@@ -770,7 +772,9 @@ where
         }
 
         match self.iter_try_rfold(n, advance) {
-            ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err),
+            ControlFlow::Continue(remaining) => {
+                NonZero::<usize>::new(remaining).map_or(Ok(()), Err)
+            }
             _ => Ok(()),
         }
     }
diff --git a/library/core/src/iter/adapters/inspect.rs b/library/core/src/iter/adapters/inspect.rs
index fd2d830b693..1c4656a649a 100644
--- a/library/core/src/iter/adapters/inspect.rs
+++ b/library/core/src/iter/adapters/inspect.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedFused};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 
 /// An iterator that calls a function with a reference to each element before
@@ -168,6 +168,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs
index c882c9e7f3f..6e163e20d8e 100644
--- a/library/core/src/iter/adapters/map.rs
+++ b/library/core/src/iter/adapters/map.rs
@@ -3,7 +3,7 @@ use crate::iter::adapters::{
     zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
 };
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen, UncheckedIterator};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 
 /// An iterator that maps the values of `iter` with `f`.
@@ -237,6 +237,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Map<I, F> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/map_while.rs b/library/core/src/iter/adapters/map_while.rs
index bcae73cbe09..9ad50048c25 100644
--- a/library/core/src/iter/adapters/map_while.rs
+++ b/library/core/src/iter/adapters/map_while.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{adapters::SourceIter, InPlaceIterable};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator that only accepts elements while `predicate` returns `Some(_)`.
@@ -84,6 +84,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index 4037e2e2839..cc514bd914f 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -1,5 +1,5 @@
 use crate::iter::InPlaceIterable;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
 
 mod array_chunks;
@@ -234,6 +234,6 @@ unsafe impl<I, R> InPlaceIterable for GenericShunt<'_, I, R>
 where
     I: InPlaceIterable,
 {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs
index 4aaf7c61f50..06ab15d5e90 100644
--- a/library/core/src/iter/adapters/rev.rs
+++ b/library/core/src/iter/adapters/rev.rs
@@ -1,5 +1,5 @@
 use crate::iter::{FusedIterator, TrustedLen};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 
 /// A double-ended iterator with the direction inverted.
@@ -39,7 +39,7 @@ where
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.iter.advance_back_by(n)
     }
 
@@ -84,7 +84,7 @@ where
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.iter.advance_by(n)
     }
 
diff --git a/library/core/src/iter/adapters/scan.rs b/library/core/src/iter/adapters/scan.rs
index 635bad199ff..d261a535b18 100644
--- a/library/core/src/iter/adapters/scan.rs
+++ b/library/core/src/iter/adapters/scan.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{adapters::SourceIter, InPlaceIterable};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator to maintain state while iterating another iterator.
@@ -94,6 +94,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<St, F, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs
index f5188dd458d..20a3b616f81 100644
--- a/library/core/src/iter/adapters/skip.rs
+++ b/library/core/src/iter/adapters/skip.rs
@@ -5,7 +5,7 @@ use crate::iter::{
     adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen, TrustedRandomAccess,
     TrustedRandomAccessNoCoerce,
 };
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator that skips over `n` elements of `iter`.
@@ -134,7 +134,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
         let skip_inner = self.n;
         let skip_and_advance = skip_inner.saturating_add(n);
 
@@ -154,7 +154,7 @@ where
             }
         }
 
-        NonZeroUsize::new(n).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n).map_or(Ok(()), Err)
     }
 
     #[doc(hidden)]
@@ -234,11 +234,11 @@ where
     impl_fold_via_try_fold! { rfold -> try_rfold }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let min = crate::cmp::min(self.len(), n);
         let rem = self.iter.advance_back_by(min);
         assert!(rem.is_ok(), "ExactSizeIterator contract violation");
-        NonZeroUsize::new(n - min).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - min).map_or(Ok(()), Err)
     }
 }
 
@@ -264,8 +264,8 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable> InPlaceIterable for Skip<I> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
 
 #[doc(hidden)]
diff --git a/library/core/src/iter/adapters/skip_while.rs b/library/core/src/iter/adapters/skip_while.rs
index 3a661973e5f..8001e6e6471 100644
--- a/library/core/src/iter/adapters/skip_while.rs
+++ b/library/core/src/iter/adapters/skip_while.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedFused};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::Try;
 
 /// An iterator that rejects elements while `predicate` returns `true`.
@@ -124,6 +124,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs
index 80e06066d28..e668e662536 100644
--- a/library/core/src/iter/adapters/take.rs
+++ b/library/core/src/iter/adapters/take.rs
@@ -3,7 +3,7 @@ use crate::iter::{
     adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedFused, TrustedLen,
     TrustedRandomAccess,
 };
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator that only iterates over the first `n` iterations of `iter`.
@@ -117,7 +117,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let min = self.n.min(n);
         let rem = match self.iter.advance_by(min) {
             Ok(()) => 0,
@@ -125,7 +125,7 @@ where
         };
         let advanced = min - rem;
         self.n -= advanced;
-        NonZeroUsize::new(n - advanced).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - advanced).map_or(Ok(()), Err)
     }
 }
 
@@ -145,8 +145,8 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
 
 #[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
@@ -219,7 +219,7 @@ where
 
     #[inline]
     #[rustc_inherit_overflow_checks]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         // The amount by which the inner iterator needs to be shortened for it to be
         // at most as long as the take() amount.
         let trim_inner = self.iter.len().saturating_sub(self.n);
@@ -235,7 +235,7 @@ where
         let advanced_by_inner = advance_by - remainder;
         let advanced_by = advanced_by_inner - trim_inner;
         self.n -= advanced_by;
-        NonZeroUsize::new(n - advanced_by).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - advanced_by).map_or(Ok(()), Err)
     }
 }
 
diff --git a/library/core/src/iter/adapters/take_while.rs b/library/core/src/iter/adapters/take_while.rs
index e55d55a6d23..d3f09ab356a 100644
--- a/library/core/src/iter/adapters/take_while.rs
+++ b/library/core/src/iter/adapters/take_while.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedFused};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator that only accepts elements while `predicate` returns `true`.
@@ -125,6 +125,6 @@ where
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> {
-    const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
 }
diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs
index b33400fab47..2e885f06b52 100644
--- a/library/core/src/iter/adapters/zip.rs
+++ b/library/core/src/iter/adapters/zip.rs
@@ -2,7 +2,7 @@ use crate::cmp;
 use crate::fmt::{self, Debug};
 use crate::iter::{FusedIterator, TrustedFused};
 use crate::iter::{InPlaceIterable, SourceIter, TrustedLen, UncheckedIterator};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 /// An iterator that iterates two other iterators simultaneously.
 ///
@@ -489,8 +489,8 @@ where
 // Since SourceIter forwards the left hand side we do the same here
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<A: InPlaceIterable, B> InPlaceIterable for Zip<A, B> {
-    const EXPAND_BY: Option<NonZeroUsize> = A::EXPAND_BY;
-    const MERGE_BY: Option<NonZeroUsize> = A::MERGE_BY;
+    const EXPAND_BY: Option<NonZero<usize>> = A::EXPAND_BY;
+    const MERGE_BY: Option<NonZero<usize>> = A::MERGE_BY;
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index 0e03d0c2d4e..7a4748dcc0d 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -2,7 +2,7 @@ use crate::ascii::Char as AsciiChar;
 use crate::convert::TryFrom;
 use crate::mem;
 use crate::net::{Ipv4Addr, Ipv6Addr};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{self, Try};
 
 use super::{
@@ -629,12 +629,12 @@ trait RangeIteratorImpl {
     // Iterator
     fn spec_next(&mut self) -> Option<Self::Item>;
     fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
-    fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>;
+    fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
 
     // DoubleEndedIterator
     fn spec_next_back(&mut self) -> Option<Self::Item>;
     fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
-    fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>;
+    fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
 }
 
 impl<A: Step> RangeIteratorImpl for ops::Range<A> {
@@ -666,7 +666,7 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
     }
 
     #[inline]
-    default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let available = if self.start <= self.end {
             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
         } else {
@@ -678,7 +678,7 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
         self.start =
             Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
 
-        NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - taken).map_or(Ok(()), Err)
     }
 
     #[inline]
@@ -707,7 +707,7 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
     }
 
     #[inline]
-    default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let available = if self.start <= self.end {
             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
         } else {
@@ -719,7 +719,7 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
         self.end =
             Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
 
-        NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - taken).map_or(Ok(()), Err)
     }
 }
 
@@ -751,7 +751,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
     }
 
     #[inline]
-    fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let available = if self.start <= self.end {
             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
         } else {
@@ -766,7 +766,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
         // Otherwise 0 is returned which always safe to use.
         self.start = unsafe { Step::forward_unchecked(self.start, taken) };
 
-        NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - taken).map_or(Ok(()), Err)
     }
 
     #[inline]
@@ -795,7 +795,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
     }
 
     #[inline]
-    fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let available = if self.start <= self.end {
             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
         } else {
@@ -807,7 +807,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
         // SAFETY: same as the spec_advance_by() implementation
         self.end = unsafe { Step::backward_unchecked(self.end, taken) };
 
-        NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - taken).map_or(Ok(()), Err)
     }
 }
 
@@ -871,7 +871,7 @@ impl<A: Step> Iterator for ops::Range<A> {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.spec_advance_by(n)
     }
 
@@ -949,7 +949,7 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.spec_advance_back_by(n)
     }
 }
diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs
index 67051f6e97b..0168b11c739 100644
--- a/library/core/src/iter/sources/repeat.rs
+++ b/library/core/src/iter/sources/repeat.rs
@@ -1,5 +1,5 @@
 use crate::iter::{FusedIterator, TrustedLen};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 /// Creates a new iterator that endlessly repeats a single element.
 ///
@@ -81,7 +81,7 @@ impl<A: Clone> Iterator for Repeat<A> {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         // Advancing an infinite iterator of a single element is a no-op.
         let _ = n;
         Ok(())
@@ -110,7 +110,7 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         // Advancing an infinite iterator of a single element is a no-op.
         let _ = n;
         Ok(())
diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs
index db2f8b7ac28..77bb8372a44 100644
--- a/library/core/src/iter/sources/repeat_n.rs
+++ b/library/core/src/iter/sources/repeat_n.rs
@@ -1,6 +1,6 @@
 use crate::iter::{FusedIterator, TrustedLen};
 use crate::mem::ManuallyDrop;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 /// Creates a new iterator that repeats a single element a given number of times.
 ///
@@ -136,7 +136,7 @@ impl<A: Clone> Iterator for RepeatN<A> {
     }
 
     #[inline]
-    fn advance_by(&mut self, skip: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, skip: usize) -> Result<(), NonZero<usize>> {
         let len = self.count;
 
         if skip >= len {
@@ -145,7 +145,7 @@ impl<A: Clone> Iterator for RepeatN<A> {
 
         if skip > len {
             // SAFETY: we just checked that the difference is positive
-            Err(unsafe { NonZeroUsize::new_unchecked(skip - len) })
+            Err(unsafe { NonZero::<usize>::new_unchecked(skip - len) })
         } else {
             self.count = len - skip;
             Ok(())
@@ -178,7 +178,7 @@ impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         self.advance_by(n)
     }
 
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index 4c8af4eba78..eb830256962 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -1,4 +1,4 @@
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator able to yield elements from both ends.
@@ -119,8 +119,8 @@ pub trait DoubleEndedIterator: Iterator {
     ///
     /// ```
     /// #![feature(iter_advance_by)]
-    ///
     /// use std::num::NonZeroUsize;
+    ///
     /// let a = [3, 4, 5, 6];
     /// let mut iter = a.iter();
     ///
@@ -134,11 +134,11 @@ pub trait DoubleEndedIterator: Iterator {
     /// [`Err(k)`]: Err
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         for i in 0..n {
             if self.next_back().is_none() {
                 // SAFETY: `i` is always less than `n`.
-                return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
+                return Err(unsafe { NonZero::<usize>::new_unchecked(n - i) });
             }
         }
         Ok(())
@@ -373,7 +373,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
     fn next_back(&mut self) -> Option<I::Item> {
         (**self).next_back()
     }
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         (**self).advance_back_by(n)
     }
     fn nth_back(&mut self, n: usize) -> Option<I::Item> {
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 20dd95a3a46..6df66e779c4 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -1,6 +1,6 @@
 use crate::array;
 use crate::cmp::{self, Ordering};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
 
 use super::super::try_process;
@@ -320,8 +320,8 @@ pub trait Iterator {
     ///
     /// ```
     /// #![feature(iter_advance_by)]
-    ///
     /// use std::num::NonZeroUsize;
+    ///
     /// let a = [1, 2, 3, 4];
     /// let mut iter = a.iter();
     ///
@@ -333,11 +333,11 @@ pub trait Iterator {
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
     #[rustc_do_not_const_check]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         for i in 0..n {
             if self.next().is_none() {
                 // SAFETY: `i` is always less than `n`.
-                return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
+                return Err(unsafe { NonZero::<usize>::new_unchecked(n - i) });
             }
         }
         Ok(())
@@ -4138,7 +4138,7 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (**self).size_hint()
     }
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         (**self).advance_by(n)
     }
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs
index e7c1f195aac..8bdbca120d7 100644
--- a/library/core/src/iter/traits/marker.rs
+++ b/library/core/src/iter/traits/marker.rs
@@ -1,5 +1,5 @@
 use crate::iter::Step;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 /// Same as FusedIterator
 ///
@@ -91,12 +91,12 @@ pub unsafe trait InPlaceIterable {
     /// E.g. [[u8; 4]; 4].iter().flatten().flatten() would have a `EXPAND_BY` of 16.
     /// This is an upper bound, i.e. the transformations will produce at most this many items per
     /// input. It's meant for layout calculations.
-    const EXPAND_BY: Option<NonZeroUsize>;
+    const EXPAND_BY: Option<NonZero<usize>>;
     /// The product of many-to-one item reductions that happen throughout the iterator pipeline.
     /// E.g. [u8].iter().array_chunks::<4>().array_chunks::<4>() would have a `MERGE_BY` of 16.
     /// This is a lower bound, i.e. the transformations will consume at least this many items per
     /// output.
-    const MERGE_BY: Option<NonZeroUsize>;
+    const MERGE_BY: Option<NonZero<usize>>;
 }
 
 /// A type that upholds all invariants of [`Step`].
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 288ad8e8d87..ddaffadf4bf 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -312,10 +312,10 @@ macro_rules! nonzero_integer {
             /// #![feature(non_zero_count_ones)]
             /// # fn main() { test().unwrap(); }
             /// # fn test() -> Option<()> {
-            #[doc = concat!("# use std::num::{self, ", stringify!($Ty), "};")]
-            ///
-            /// let one = num::NonZeroU32::new(1)?;
-            /// let three = num::NonZeroU32::new(3)?;
+            /// # use std::num::*;
+            /// #
+            /// let one = NonZeroU32::new(1)?;
+            /// let three = NonZeroU32::new(3)?;
             #[doc = concat!("let a = ", stringify!($Ty), "::new(0b100_0000)?;")]
             #[doc = concat!("let b = ", stringify!($Ty), "::new(0b100_0011)?;")]
             ///
@@ -336,7 +336,7 @@ macro_rules! nonzero_integer {
                 // SAFETY:
                 // `self` is non-zero, which means it has at least one bit set, which means
                 // that the result of `count_ones` is non-zero.
-                unsafe { NonZeroU32::new_unchecked(self.get().count_ones()) }
+                unsafe { NonZero::<u32>::new_unchecked(self.get().count_ones()) }
             }
 
             nonzero_integer_signedness_dependent_methods! {
diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs
index 743799c4b3e..2ba0bd158f7 100644
--- a/library/core/src/ops/index_range.rs
+++ b/library/core/src/ops/index_range.rs
@@ -1,6 +1,6 @@
 use crate::intrinsics::{unchecked_add, unchecked_sub};
 use crate::iter::{FusedIterator, TrustedLen};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 
 /// Like a `Range<usize>`, but with a safety invariant that `start <= end`.
 ///
@@ -130,9 +130,9 @@ impl Iterator for IndexRange {
     }
 
     #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let taken = self.take_prefix(n);
-        NonZeroUsize::new(n - taken.len()).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - taken.len()).map_or(Ok(()), Err)
     }
 }
 
@@ -148,9 +148,9 @@ impl DoubleEndedIterator for IndexRange {
     }
 
     #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
         let taken = self.take_suffix(n);
-        NonZeroUsize::new(n - taken.len()).map_or(Ok(()), Err)
+        NonZero::<usize>::new(n - taken.len()).map_or(Ok(()), Err)
     }
 }
 
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index ce176e6fc18..ad22ee5a027 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -1,5 +1,5 @@
 use crate::convert::{TryFrom, TryInto};
-use crate::num::NonZeroUsize;
+use crate::num::{NonZero, NonZeroUsize};
 use crate::{cmp, fmt, hash, mem, num};
 
 /// A type storing a `usize` which is a power of two, and thus
@@ -100,7 +100,7 @@ impl Alignment {
     #[inline]
     pub const fn as_nonzero(self) -> NonZeroUsize {
         // SAFETY: All the discriminants are non-zero.
-        unsafe { NonZeroUsize::new_unchecked(self.as_usize()) }
+        unsafe { NonZero::<usize>::new_unchecked(self.as_usize()) }
     }
 
     /// Returns the base-2 logarithm of the alignment.
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 320cd5eb3b2..2246596a883 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -6,7 +6,7 @@ use crate::intrinsics::assert_unsafe_precondition;
 use crate::marker::Unsize;
 use crate::mem::SizedTypeProperties;
 use crate::mem::{self, MaybeUninit};
-use crate::num::NonZeroUsize;
+use crate::num::{NonZero, NonZeroUsize};
 use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::ptr;
 use crate::ptr::Unique;
@@ -295,7 +295,7 @@ impl<T: ?Sized> NonNull<T> {
     pub fn addr(self) -> NonZeroUsize {
         // SAFETY: The pointer is guaranteed by the type to be non-null,
         // meaning that the address will be non-zero.
-        unsafe { NonZeroUsize::new_unchecked(self.pointer.addr()) }
+        unsafe { NonZero::<usize>::new_unchecked(self.pointer.addr()) }
     }
 
     /// Creates a new pointer with the given address.
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 1429313c890..617b385a960 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -11,7 +11,7 @@ use crate::iter::{
 };
 use crate::marker::PhantomData;
 use crate::mem::{self, SizedTypeProperties};
-use crate::num::{NonZero, NonZeroUsize};
+use crate::num::NonZero;
 use crate::ptr::{self, invalid, invalid_mut, NonNull};
 
 use super::{from_raw_parts, from_raw_parts_mut};
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index fc6af45fb90..53218391dcf 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -196,11 +196,11 @@ macro_rules! iterator {
             }
 
             #[inline]
-            fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+            fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
                 let advance = cmp::min(len!(self), n);
                 // SAFETY: By construction, `advance` does not exceed `self.len()`.
                 unsafe { self.post_inc_start(advance) };
-                NonZeroUsize::new(n - advance).map_or(Ok(()), Err)
+                NonZero::<usize>::new(n - advance).map_or(Ok(()), Err)
             }
 
             #[inline]
@@ -421,11 +421,11 @@ macro_rules! iterator {
             }
 
             #[inline]
-            fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
+            fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
                 let advance = cmp::min(len!(self), n);
                 // SAFETY: By construction, `advance` does not exceed `self.len()`.
                 unsafe { self.pre_dec_end(advance) };
-                NonZeroUsize::new(n - advance).map_or(Ok(()), Err)
+                NonZero::<usize>::new(n - advance).map_or(Ok(()), Err)
             }
         }
 
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 73e92ed1dad..c70a3d3224d 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -11,7 +11,7 @@ use crate::fmt;
 use crate::hint;
 use crate::intrinsics::exact_div;
 use crate::mem::{self, SizedTypeProperties};
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{Bound, OneSidedRange, Range, RangeBounds};
 use crate::panic::debug_assert_nounwind;
 use crate::ptr;
@@ -1086,7 +1086,7 @@ impl<T> [T] {
     #[inline]
     #[track_caller]
     pub fn windows(&self, size: usize) -> Windows<'_, T> {
-        let size = NonZeroUsize::new(size).expect("window size must be non-zero");
+        let size = NonZero::<usize>::new(size).expect("window size must be non-zero");
         Windows::new(self, size)
     }
 
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index 4d6239e11a3..d2180fa83fb 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -8,7 +8,7 @@ use crate::iter::{TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use crate::ops::Try;
 use crate::option;
 use crate::slice::{self, Split as SliceSplit};
-use core::num::NonZeroUsize;
+use core::num::{NonZero, NonZeroUsize};
 
 use super::from_utf8_unchecked;
 use super::pattern::Pattern;
@@ -96,7 +96,7 @@ impl<'a> Iterator for Chars<'a> {
             unsafe { self.iter.advance_by(slurp).unwrap_unchecked() };
         }
 
-        NonZeroUsize::new(remainder).map_or(Ok(()), Err)
+        NonZero::<usize>::new(remainder).map_or(Ok(()), Err)
     }
 
     #[inline]
diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs
index ed52de3cbec..579c140c198 100644
--- a/library/core/tests/array.rs
+++ b/library/core/tests/array.rs
@@ -1,4 +1,4 @@
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::sync::atomic::{AtomicUsize, Ordering};
 use core::{array, assert_eq};
 
@@ -548,7 +548,7 @@ fn array_intoiter_advance_by() {
     assert_eq!(counter.get(), 13);
 
     let r = it.advance_by(123456);
-    assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap()));
+    assert_eq!(r, Err(NonZero::<usize>::new(123456 - 87).unwrap()));
     assert_eq!(it.len(), 0);
     assert_eq!(counter.get(), 100);
 
@@ -558,7 +558,7 @@ fn array_intoiter_advance_by() {
     assert_eq!(counter.get(), 100);
 
     let r = it.advance_by(10);
-    assert_eq!(r, Err(NonZeroUsize::new(10).unwrap()));
+    assert_eq!(r, Err(NonZero::<usize>::new(10).unwrap()));
     assert_eq!(it.len(), 0);
     assert_eq!(counter.get(), 100);
 }
@@ -601,7 +601,7 @@ fn array_intoiter_advance_back_by() {
     assert_eq!(counter.get(), 13);
 
     let r = it.advance_back_by(123456);
-    assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap()));
+    assert_eq!(r, Err(NonZero::<usize>::new(123456 - 87).unwrap()));
     assert_eq!(it.len(), 0);
     assert_eq!(counter.get(), 100);
 
@@ -611,7 +611,7 @@ fn array_intoiter_advance_back_by() {
     assert_eq!(counter.get(), 100);
 
     let r = it.advance_back_by(10);
-    assert_eq!(r, Err(NonZeroUsize::new(10).unwrap()));
+    assert_eq!(r, Err(NonZero::<usize>::new(10).unwrap()));
     assert_eq!(it.len(), 0);
     assert_eq!(counter.get(), 100);
 }
diff --git a/library/core/tests/iter/adapters/chain.rs b/library/core/tests/iter/adapters/chain.rs
index ad78a85a88d..9e098d5bee4 100644
--- a/library/core/tests/iter/adapters/chain.rs
+++ b/library/core/tests/iter/adapters/chain.rs
@@ -1,6 +1,6 @@
 use super::*;
 use core::iter::*;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 #[test]
 fn test_iterator_chain() {
@@ -34,7 +34,10 @@ fn test_iterator_chain_advance_by() {
             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
             assert_eq!(iter.advance_by(i), Ok(()));
             assert_eq!(iter.next(), Some(&xs[i]));
-            assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (len - i - 1)).unwrap()));
+            assert_eq!(
+                iter.advance_by(100),
+                Err(NonZero::<usize>::new(100 - (len - i - 1)).unwrap())
+            );
             assert_eq!(iter.advance_by(0), Ok(()));
         }
 
@@ -44,7 +47,7 @@ fn test_iterator_chain_advance_by() {
             assert_eq!(iter.next(), Some(&ys[i]));
             assert_eq!(
                 iter.advance_by(100),
-                Err(NonZeroUsize::new(100 - (ys.len() - i - 1)).unwrap())
+                Err(NonZero::<usize>::new(100 - (ys.len() - i - 1)).unwrap())
             );
             assert_eq!(iter.advance_by(0), Ok(()));
         }
@@ -55,7 +58,7 @@ fn test_iterator_chain_advance_by() {
         assert_eq!(iter.advance_by(0), Ok(()));
 
         let mut iter = xs.iter().chain(ys);
-        assert_eq!(iter.advance_by(len + 1), Err(NonZeroUsize::new(1).unwrap()));
+        assert_eq!(iter.advance_by(len + 1), Err(NonZero::<usize>::new(1).unwrap()));
         assert_eq!(iter.advance_by(0), Ok(()));
     }
 
@@ -76,7 +79,7 @@ fn test_iterator_chain_advance_back_by() {
             assert_eq!(iter.next_back(), Some(&ys[ys.len() - i - 1]));
             assert_eq!(
                 iter.advance_back_by(100),
-                Err(NonZeroUsize::new(100 - (len - i - 1)).unwrap())
+                Err(NonZero::<usize>::new(100 - (len - i - 1)).unwrap())
             );
             assert_eq!(iter.advance_back_by(0), Ok(()));
         }
@@ -87,7 +90,7 @@ fn test_iterator_chain_advance_back_by() {
             assert_eq!(iter.next_back(), Some(&xs[xs.len() - i - 1]));
             assert_eq!(
                 iter.advance_back_by(100),
-                Err(NonZeroUsize::new(100 - (xs.len() - i - 1)).unwrap())
+                Err(NonZero::<usize>::new(100 - (xs.len() - i - 1)).unwrap())
             );
             assert_eq!(iter.advance_back_by(0), Ok(()));
         }
@@ -98,7 +101,7 @@ fn test_iterator_chain_advance_back_by() {
         assert_eq!(iter.advance_back_by(0), Ok(()));
 
         let mut iter = xs.iter().chain(ys);
-        assert_eq!(iter.advance_back_by(len + 1), Err(NonZeroUsize::new(1).unwrap()));
+        assert_eq!(iter.advance_back_by(len + 1), Err(NonZero::<usize>::new(1).unwrap()));
         assert_eq!(iter.advance_back_by(0), Ok(()));
     }
 
diff --git a/library/core/tests/iter/adapters/enumerate.rs b/library/core/tests/iter/adapters/enumerate.rs
index ff57973a62a..5aa7532c10c 100644
--- a/library/core/tests/iter/adapters/enumerate.rs
+++ b/library/core/tests/iter/adapters/enumerate.rs
@@ -1,5 +1,5 @@
 use core::iter::*;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 #[test]
 fn test_iterator_enumerate() {
@@ -66,7 +66,7 @@ fn test_iterator_enumerate_advance_by() {
     assert_eq!(it.next(), Some((2, &2)));
     assert_eq!(it.advance_by(2), Ok(()));
     assert_eq!(it.next(), Some((5, &5)));
-    assert_eq!(it.advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!(it.advance_by(1), Err(NonZero::<usize>::new(1).unwrap()));
     assert_eq!(it.next(), None);
 }
 
diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs
index f429d90cd7d..fb6383b3289 100644
--- a/library/core/tests/iter/adapters/flatten.rs
+++ b/library/core/tests/iter/adapters/flatten.rs
@@ -1,7 +1,7 @@
 use super::*;
 use core::assert_eq;
 use core::iter::*;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 #[test]
 fn test_iterator_flatten() {
@@ -72,8 +72,8 @@ fn test_flatten_advance_by() {
     assert_eq!(it.advance_back_by(9), Ok(()));
     assert_eq!(it.next_back(), Some(25));
 
-    assert_eq!(it.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 9).unwrap()));
-    assert_eq!(it.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap()));
+    assert_eq!(it.advance_by(usize::MAX), Err(NonZero::<usize>::new(usize::MAX - 9).unwrap()));
+    assert_eq!(it.advance_back_by(usize::MAX), Err(NonZero::<usize>::new(usize::MAX).unwrap()));
     assert_eq!(it.advance_by(0), Ok(()));
     assert_eq!(it.advance_back_by(0), Ok(()));
     assert_eq!(it.size_hint(), (0, Some(0)));
diff --git a/library/core/tests/iter/adapters/skip.rs b/library/core/tests/iter/adapters/skip.rs
index e3e88a84fad..45726d158b6 100644
--- a/library/core/tests/iter/adapters/skip.rs
+++ b/library/core/tests/iter/adapters/skip.rs
@@ -1,5 +1,5 @@
 use core::iter::*;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 use super::Unfuse;
 
@@ -75,14 +75,14 @@ fn test_iterator_skip_nth() {
 #[test]
 fn test_skip_advance_by() {
     assert_eq!((0..0).skip(10).advance_by(0), Ok(()));
-    assert_eq!((0..0).skip(10).advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!((0..0).skip(10).advance_by(1), Err(NonZero::<usize>::new(1).unwrap()));
     assert_eq!(
         (0u128..(usize::MAX as u128) + 1).skip(usize::MAX - 10).advance_by(usize::MAX - 5),
-        Err(NonZeroUsize::new(usize::MAX - 16).unwrap())
+        Err(NonZero::<usize>::new(usize::MAX - 16).unwrap())
     );
     assert_eq!((0u128..u128::MAX).skip(usize::MAX - 10).advance_by(20), Ok(()));
 
-    assert_eq!((0..2).skip(1).advance_back_by(10), Err(NonZeroUsize::new(9).unwrap()));
+    assert_eq!((0..2).skip(1).advance_back_by(10), Err(NonZero::<usize>::new(9).unwrap()));
     assert_eq!((0..0).skip(1).advance_back_by(0), Ok(()));
 }
 
diff --git a/library/core/tests/iter/adapters/take.rs b/library/core/tests/iter/adapters/take.rs
index ff6e362b065..6aa1b929546 100644
--- a/library/core/tests/iter/adapters/take.rs
+++ b/library/core/tests/iter/adapters/take.rs
@@ -1,5 +1,5 @@
 use core::iter::*;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 #[test]
 fn test_iterator_take() {
@@ -79,23 +79,23 @@ fn test_take_advance_by() {
     let mut take = (0..10).take(3);
     assert_eq!(take.advance_by(2), Ok(()));
     assert_eq!(take.next(), Some(2));
-    assert_eq!(take.advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!(take.advance_by(1), Err(NonZero::<usize>::new(1).unwrap()));
 
     assert_eq!((0..0).take(10).advance_by(0), Ok(()));
-    assert_eq!((0..0).take(10).advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
-    assert_eq!((0..10).take(4).advance_by(5), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!((0..0).take(10).advance_by(1), Err(NonZero::<usize>::new(1).unwrap()));
+    assert_eq!((0..10).take(4).advance_by(5), Err(NonZero::<usize>::new(1).unwrap()));
 
     let mut take = (0..10).take(3);
     assert_eq!(take.advance_back_by(2), Ok(()));
     assert_eq!(take.next(), Some(0));
-    assert_eq!(take.advance_back_by(1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!(take.advance_back_by(1), Err(NonZero::<usize>::new(1).unwrap()));
 
-    assert_eq!((0..2).take(1).advance_back_by(10), Err(NonZeroUsize::new(9).unwrap()));
-    assert_eq!((0..0).take(1).advance_back_by(1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!((0..2).take(1).advance_back_by(10), Err(NonZero::<usize>::new(9).unwrap()));
+    assert_eq!((0..0).take(1).advance_back_by(1), Err(NonZero::<usize>::new(1).unwrap()));
     assert_eq!((0..0).take(1).advance_back_by(0), Ok(()));
     assert_eq!(
         (0..usize::MAX).take(100).advance_back_by(usize::MAX),
-        Err(NonZeroUsize::new(usize::MAX - 100).unwrap())
+        Err(NonZero::<usize>::new(usize::MAX - 100).unwrap())
     );
 }
 
diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs
index a6b9f1cb7c8..f840218382d 100644
--- a/library/core/tests/iter/range.rs
+++ b/library/core/tests/iter/range.rs
@@ -1,6 +1,6 @@
 use super::*;
 use core::ascii::Char as AsciiChar;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 #[test]
 fn test_range() {
@@ -314,7 +314,7 @@ fn test_range_advance_by() {
 
     assert_eq!((r.start, r.end), (1, usize::MAX - 1));
 
-    assert_eq!(Err(NonZeroUsize::new(2).unwrap()), r.advance_by(usize::MAX));
+    assert_eq!(Err(NonZero::<usize>::new(2).unwrap()), r.advance_by(usize::MAX));
 
     assert_eq!(Ok(()), r.advance_by(0));
     assert_eq!(Ok(()), r.advance_back_by(0));
diff --git a/library/core/tests/iter/traits/iterator.rs b/library/core/tests/iter/traits/iterator.rs
index 4c2d843eaa0..507f15c6088 100644
--- a/library/core/tests/iter/traits/iterator.rs
+++ b/library/core/tests/iter/traits/iterator.rs
@@ -1,4 +1,4 @@
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 
 /// A wrapper struct that implements `Eq` and `Ord` based on the wrapped
 /// integer modulo 3. Used to test that `Iterator::max` and `Iterator::min`
@@ -152,11 +152,14 @@ fn test_iterator_advance_by() {
         let mut iter = v.iter();
         assert_eq!(iter.advance_by(i), Ok(()));
         assert_eq!(iter.next().unwrap(), &v[i]);
-        assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap()));
+        assert_eq!(
+            iter.advance_by(100),
+            Err(NonZero::<usize>::new(100 - (v.len() - 1 - i)).unwrap())
+        );
     }
 
     assert_eq!(v.iter().advance_by(v.len()), Ok(()));
-    assert_eq!(v.iter().advance_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
+    assert_eq!(v.iter().advance_by(100), Err(NonZero::<usize>::new(100 - v.len()).unwrap()));
 }
 
 #[test]
@@ -169,12 +172,12 @@ fn test_iterator_advance_back_by() {
         assert_eq!(iter.next_back().unwrap(), &v[v.len() - 1 - i]);
         assert_eq!(
             iter.advance_back_by(100),
-            Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())
+            Err(NonZero::<usize>::new(100 - (v.len() - 1 - i)).unwrap())
         );
     }
 
     assert_eq!(v.iter().advance_back_by(v.len()), Ok(()));
-    assert_eq!(v.iter().advance_back_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
+    assert_eq!(v.iter().advance_back_by(100), Err(NonZero::<usize>::new(100 - v.len()).unwrap()));
 }
 
 #[test]
@@ -187,12 +190,15 @@ fn test_iterator_rev_advance_back_by() {
         assert_eq!(iter.next_back().unwrap(), &v[i]);
         assert_eq!(
             iter.advance_back_by(100),
-            Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())
+            Err(NonZero::<usize>::new(100 - (v.len() - 1 - i)).unwrap())
         );
     }
 
     assert_eq!(v.iter().rev().advance_back_by(v.len()), Ok(()));
-    assert_eq!(v.iter().rev().advance_back_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
+    assert_eq!(
+        v.iter().rev().advance_back_by(100),
+        Err(NonZero::<usize>::new(100 - v.len()).unwrap())
+    );
 }
 
 #[test]
@@ -460,11 +466,14 @@ fn test_iterator_rev_advance_by() {
         let mut iter = v.iter().rev();
         assert_eq!(iter.advance_by(i), Ok(()));
         assert_eq!(iter.next().unwrap(), &v[v.len() - 1 - i]);
-        assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap()));
+        assert_eq!(
+            iter.advance_by(100),
+            Err(NonZero::<usize>::new(100 - (v.len() - 1 - i)).unwrap())
+        );
     }
 
     assert_eq!(v.iter().rev().advance_by(v.len()), Ok(()));
-    assert_eq!(v.iter().rev().advance_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
+    assert_eq!(v.iter().rev().advance_by(100), Err(NonZero::<usize>::new(100 - v.len()).unwrap()));
 }
 
 #[test]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 2fe79650dbf..fa0e9a979d0 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -40,6 +40,7 @@
 #![feature(float_minimum_maximum)]
 #![feature(future_join)]
 #![feature(generic_assert_internals)]
+#![feature(generic_nonzero)]
 #![feature(array_try_from_fn)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs
index 8873d26880c..69dbe5d7dea 100644
--- a/library/core/tests/nonzero.rs
+++ b/library/core/tests/nonzero.rs
@@ -1,30 +1,27 @@
-use core::num::{
-    IntErrorKind, NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize,
-    NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
-};
+use core::num::{IntErrorKind, NonZero};
 use core::option::Option::None;
 use std::mem::size_of;
 
 #[test]
 fn test_create_nonzero_instance() {
-    let _a = unsafe { NonZeroU32::new_unchecked(21) };
+    let _a = unsafe { NonZero::<u32>::new_unchecked(21) };
 }
 
 #[test]
 fn test_size_nonzero_in_option() {
-    assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
-    assert_eq!(size_of::<NonZeroI32>(), size_of::<Option<NonZeroI32>>());
+    assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>());
+    assert_eq!(size_of::<NonZero<i32>>(), size_of::<Option<NonZero<i32>>>());
 }
 
 #[test]
 fn test_match_on_nonzero_option() {
-    let a = Some(unsafe { NonZeroU32::new_unchecked(42) });
+    let a = Some(unsafe { NonZero::<u32>::new_unchecked(42) });
     match a {
         Some(val) => assert_eq!(val.get(), 42),
         None => panic!("unexpected None while matching on Some(NonZeroU32(_))"),
     }
 
-    match unsafe { Some(NonZeroU32::new_unchecked(43)) } {
+    match unsafe { Some(NonZero::<u32>::new_unchecked(43)) } {
         Some(val) => assert_eq!(val.get(), 43),
         None => panic!("unexpected None while matching on Some(NonZeroU32(_))"),
     }
@@ -89,13 +86,14 @@ fn test_match_option_string() {
 }
 
 mod atom {
-    use core::num::NonZeroU32;
+    use core::num::NonZero;
 
     #[derive(PartialEq, Eq)]
     pub struct Atom {
-        index: NonZeroU32, // private
+        index: NonZero<u32>, // private
     }
-    pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } };
+
+    pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZero::<u32>::new_unchecked(7) } };
 }
 
 macro_rules! atom {
@@ -115,62 +113,65 @@ fn test_match_nonzero_const_pattern() {
 
 #[test]
 fn test_from_nonzero() {
-    let nz = NonZeroU32::new(1).unwrap();
+    let nz = NonZero::<u32>::new(1).unwrap();
     let num: u32 = nz.into();
     assert_eq!(num, 1u32);
 }
 
 #[test]
 fn test_from_signed_nonzero() {
-    let nz = NonZeroI32::new(1).unwrap();
+    let nz = NonZero::<i32>::new(1).unwrap();
     let num: i32 = nz.into();
     assert_eq!(num, 1i32);
 }
 
 #[test]
 fn test_from_str() {
-    assert_eq!("123".parse::<NonZeroU8>(), Ok(NonZeroU8::new(123).unwrap()));
-    assert_eq!("0".parse::<NonZeroU8>().err().map(|e| e.kind().clone()), Some(IntErrorKind::Zero));
+    assert_eq!("123".parse::<NonZero<u8>>(), Ok(NonZero::<u8>::new(123).unwrap()));
+    assert_eq!(
+        "0".parse::<NonZero<u8>>().err().map(|e| e.kind().clone()),
+        Some(IntErrorKind::Zero)
+    );
     assert_eq!(
-        "-1".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
+        "-1".parse::<NonZero<u8>>().err().map(|e| e.kind().clone()),
         Some(IntErrorKind::InvalidDigit)
     );
     assert_eq!(
-        "-129".parse::<NonZeroI8>().err().map(|e| e.kind().clone()),
+        "-129".parse::<NonZero<i8>>().err().map(|e| e.kind().clone()),
         Some(IntErrorKind::NegOverflow)
     );
     assert_eq!(
-        "257".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
+        "257".parse::<NonZero<u8>>().err().map(|e| e.kind().clone()),
         Some(IntErrorKind::PosOverflow)
     );
 }
 
 #[test]
 fn test_nonzero_bitor() {
-    let nz_alt = NonZeroU8::new(0b1010_1010).unwrap();
-    let nz_low = NonZeroU8::new(0b0000_1111).unwrap();
+    let nz_alt = NonZero::<u8>::new(0b1010_1010).unwrap();
+    let nz_low = NonZero::<u8>::new(0b0000_1111).unwrap();
 
-    let both_nz: NonZeroU8 = nz_alt | nz_low;
+    let both_nz: NonZero<u8> = nz_alt | nz_low;
     assert_eq!(both_nz.get(), 0b1010_1111);
 
-    let rhs_int: NonZeroU8 = nz_low | 0b1100_0000u8;
+    let rhs_int: NonZero<u8> = nz_low | 0b1100_0000u8;
     assert_eq!(rhs_int.get(), 0b1100_1111);
 
-    let rhs_zero: NonZeroU8 = nz_alt | 0u8;
+    let rhs_zero: NonZero<u8> = nz_alt | 0u8;
     assert_eq!(rhs_zero.get(), 0b1010_1010);
 
-    let lhs_int: NonZeroU8 = 0b0110_0110u8 | nz_alt;
+    let lhs_int: NonZero<u8> = 0b0110_0110u8 | nz_alt;
     assert_eq!(lhs_int.get(), 0b1110_1110);
 
-    let lhs_zero: NonZeroU8 = 0u8 | nz_low;
+    let lhs_zero: NonZero<u8> = 0u8 | nz_low;
     assert_eq!(lhs_zero.get(), 0b0000_1111);
 }
 
 #[test]
 fn test_nonzero_bitor_assign() {
-    let mut target = NonZeroU8::new(0b1010_1010).unwrap();
+    let mut target = NonZero::<u8>::new(0b1010_1010).unwrap();
 
-    target |= NonZeroU8::new(0b0000_1111).unwrap();
+    target |= NonZero::<u8>::new(0b0000_1111).unwrap();
     assert_eq!(target.get(), 0b1010_1111);
 
     target |= 0b0001_0000;
@@ -182,147 +183,147 @@ fn test_nonzero_bitor_assign() {
 
 #[test]
 fn test_nonzero_from_int_on_success() {
-    assert_eq!(NonZeroU8::try_from(5), Ok(NonZeroU8::new(5).unwrap()));
-    assert_eq!(NonZeroU32::try_from(5), Ok(NonZeroU32::new(5).unwrap()));
+    assert_eq!(NonZero::<u8>::try_from(5), Ok(NonZero::<u8>::new(5).unwrap()));
+    assert_eq!(NonZero::<u32>::try_from(5), Ok(NonZero::<u32>::new(5).unwrap()));
 
-    assert_eq!(NonZeroI8::try_from(-5), Ok(NonZeroI8::new(-5).unwrap()));
-    assert_eq!(NonZeroI32::try_from(-5), Ok(NonZeroI32::new(-5).unwrap()));
+    assert_eq!(NonZero::<i8>::try_from(-5), Ok(NonZero::<i8>::new(-5).unwrap()));
+    assert_eq!(NonZero::<i32>::try_from(-5), Ok(NonZero::<i32>::new(-5).unwrap()));
 }
 
 #[test]
 fn test_nonzero_from_int_on_err() {
-    assert!(NonZeroU8::try_from(0).is_err());
-    assert!(NonZeroU32::try_from(0).is_err());
+    assert!(NonZero::<u8>::try_from(0).is_err());
+    assert!(NonZero::<u32>::try_from(0).is_err());
 
-    assert!(NonZeroI8::try_from(0).is_err());
-    assert!(NonZeroI32::try_from(0).is_err());
+    assert!(NonZero::<i8>::try_from(0).is_err());
+    assert!(NonZero::<i32>::try_from(0).is_err());
 }
 
 #[test]
 fn nonzero_const() {
     // test that the methods of `NonZeroX>` are usable in a const context
-    // Note: only tests NonZero8
+    // Note: only tests NonZero<u8>
 
-    const NONZERO_U8: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(5) };
+    const NONZERO_U8: NonZero<u8> = unsafe { NonZero::<u8>::new_unchecked(5) };
 
     const GET: u8 = NONZERO_U8.get();
     assert_eq!(GET, 5);
 
-    const ZERO: Option<NonZeroU8> = NonZeroU8::new(0);
+    const ZERO: Option<NonZero<u8>> = NonZero::<u8>::new(0);
     assert!(ZERO.is_none());
 
-    const ONE: Option<NonZeroU8> = NonZeroU8::new(1);
+    const ONE: Option<NonZero<u8>> = NonZero::<u8>::new(1);
     assert!(ONE.is_some());
 
     /* FIXME(#110395)
     const FROM_NONZERO_U8: u8 = u8::from(NONZERO_U8);
     assert_eq!(FROM_NONZERO_U8, 5);
 
-    const NONZERO_CONVERT: NonZeroU32 = NonZeroU32::from(NONZERO_U8);
+    const NONZERO_CONVERT: NonZero<u32> = NonZero::<u32>::from(NONZERO_U8);
     assert_eq!(NONZERO_CONVERT.get(), 5);
     */
 }
 
 #[test]
 fn nonzero_leading_zeros() {
-    assert_eq!(NonZeroU8::new(1).unwrap().leading_zeros(), 7);
-    assert_eq!(NonZeroI8::new(1).unwrap().leading_zeros(), 7);
-    assert_eq!(NonZeroU16::new(1).unwrap().leading_zeros(), 15);
-    assert_eq!(NonZeroI16::new(1).unwrap().leading_zeros(), 15);
-    assert_eq!(NonZeroU32::new(1).unwrap().leading_zeros(), 31);
-    assert_eq!(NonZeroI32::new(1).unwrap().leading_zeros(), 31);
-    assert_eq!(NonZeroU64::new(1).unwrap().leading_zeros(), 63);
-    assert_eq!(NonZeroI64::new(1).unwrap().leading_zeros(), 63);
-    assert_eq!(NonZeroU128::new(1).unwrap().leading_zeros(), 127);
-    assert_eq!(NonZeroI128::new(1).unwrap().leading_zeros(), 127);
-    assert_eq!(NonZeroUsize::new(1).unwrap().leading_zeros(), usize::BITS - 1);
-    assert_eq!(NonZeroIsize::new(1).unwrap().leading_zeros(), usize::BITS - 1);
-
-    assert_eq!(NonZeroU8::new(u8::MAX >> 2).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroI8::new((u8::MAX >> 2) as i8).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroU16::new(u16::MAX >> 2).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroI16::new((u16::MAX >> 2) as i16).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroU32::new(u32::MAX >> 2).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroI32::new((u32::MAX >> 2) as i32).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroU64::new(u64::MAX >> 2).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroI64::new((u64::MAX >> 2) as i64).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroU128::new(u128::MAX >> 2).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroI128::new((u128::MAX >> 2) as i128).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroUsize::new(usize::MAX >> 2).unwrap().leading_zeros(), 2);
-    assert_eq!(NonZeroIsize::new((usize::MAX >> 2) as isize).unwrap().leading_zeros(), 2);
-
-    assert_eq!(NonZeroU8::new(u8::MAX).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroI8::new(-1i8).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroU16::new(u16::MAX).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroI16::new(-1i16).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroU32::new(u32::MAX).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroI32::new(-1i32).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroU64::new(u64::MAX).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroI64::new(-1i64).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroU128::new(u128::MAX).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroI128::new(-1i128).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroUsize::new(usize::MAX).unwrap().leading_zeros(), 0);
-    assert_eq!(NonZeroIsize::new(-1isize).unwrap().leading_zeros(), 0);
-
-    const LEADING_ZEROS: u32 = NonZeroU16::new(1).unwrap().leading_zeros();
+    assert_eq!(NonZero::<u8>::new(1).unwrap().leading_zeros(), 7);
+    assert_eq!(NonZero::<i8>::new(1).unwrap().leading_zeros(), 7);
+    assert_eq!(NonZero::<u16>::new(1).unwrap().leading_zeros(), 15);
+    assert_eq!(NonZero::<i16>::new(1).unwrap().leading_zeros(), 15);
+    assert_eq!(NonZero::<u32>::new(1).unwrap().leading_zeros(), 31);
+    assert_eq!(NonZero::<i32>::new(1).unwrap().leading_zeros(), 31);
+    assert_eq!(NonZero::<u64>::new(1).unwrap().leading_zeros(), 63);
+    assert_eq!(NonZero::<i64>::new(1).unwrap().leading_zeros(), 63);
+    assert_eq!(NonZero::<u128>::new(1).unwrap().leading_zeros(), 127);
+    assert_eq!(NonZero::<i128>::new(1).unwrap().leading_zeros(), 127);
+    assert_eq!(NonZero::<usize>::new(1).unwrap().leading_zeros(), usize::BITS - 1);
+    assert_eq!(NonZero::<isize>::new(1).unwrap().leading_zeros(), usize::BITS - 1);
+
+    assert_eq!(NonZero::<u8>::new(u8::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<i8>::new((u8::MAX >> 2) as i8).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<u16>::new(u16::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<i16>::new((u16::MAX >> 2) as i16).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<u32>::new(u32::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<i32>::new((u32::MAX >> 2) as i32).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<u64>::new(u64::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<i64>::new((u64::MAX >> 2) as i64).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<u128>::new(u128::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<i128>::new((u128::MAX >> 2) as i128).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<usize>::new(usize::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZero::<isize>::new((usize::MAX >> 2) as isize).unwrap().leading_zeros(), 2);
+
+    assert_eq!(NonZero::<u8>::new(u8::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<i8>::new(-1i8).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<u16>::new(u16::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<i16>::new(-1i16).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<u32>::new(u32::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<i32>::new(-1i32).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<u64>::new(u64::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<i64>::new(-1i64).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<u128>::new(u128::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<i128>::new(-1i128).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<usize>::new(usize::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZero::<isize>::new(-1isize).unwrap().leading_zeros(), 0);
+
+    const LEADING_ZEROS: u32 = NonZero::<u16>::new(1).unwrap().leading_zeros();
     assert_eq!(LEADING_ZEROS, 15);
 }
 
 #[test]
 fn nonzero_trailing_zeros() {
-    assert_eq!(NonZeroU8::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroI8::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroU16::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroI16::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroU32::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroI32::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroU64::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroI64::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroU128::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroI128::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroUsize::new(1).unwrap().trailing_zeros(), 0);
-    assert_eq!(NonZeroIsize::new(1).unwrap().trailing_zeros(), 0);
-
-    assert_eq!(NonZeroU8::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroI8::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroU16::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroI16::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroU32::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroI32::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroU64::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroI64::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroU128::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroI128::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroUsize::new(1 << 2).unwrap().trailing_zeros(), 2);
-    assert_eq!(NonZeroIsize::new(1 << 2).unwrap().trailing_zeros(), 2);
-
-    assert_eq!(NonZeroU8::new(1 << 7).unwrap().trailing_zeros(), 7);
-    assert_eq!(NonZeroI8::new(1 << 7).unwrap().trailing_zeros(), 7);
-    assert_eq!(NonZeroU16::new(1 << 15).unwrap().trailing_zeros(), 15);
-    assert_eq!(NonZeroI16::new(1 << 15).unwrap().trailing_zeros(), 15);
-    assert_eq!(NonZeroU32::new(1 << 31).unwrap().trailing_zeros(), 31);
-    assert_eq!(NonZeroI32::new(1 << 31).unwrap().trailing_zeros(), 31);
-    assert_eq!(NonZeroU64::new(1 << 63).unwrap().trailing_zeros(), 63);
-    assert_eq!(NonZeroI64::new(1 << 63).unwrap().trailing_zeros(), 63);
-    assert_eq!(NonZeroU128::new(1 << 127).unwrap().trailing_zeros(), 127);
-    assert_eq!(NonZeroI128::new(1 << 127).unwrap().trailing_zeros(), 127);
+    assert_eq!(NonZero::<u8>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<i8>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<u16>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<i16>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<u32>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<i32>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<u64>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<i64>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<u128>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<i128>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<usize>::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZero::<isize>::new(1).unwrap().trailing_zeros(), 0);
+
+    assert_eq!(NonZero::<u8>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<i8>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<u16>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<i16>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<u32>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<i32>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<u64>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<i64>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<u128>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<i128>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<usize>::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZero::<isize>::new(1 << 2).unwrap().trailing_zeros(), 2);
+
+    assert_eq!(NonZero::<u8>::new(1 << 7).unwrap().trailing_zeros(), 7);
+    assert_eq!(NonZero::<i8>::new(1 << 7).unwrap().trailing_zeros(), 7);
+    assert_eq!(NonZero::<u16>::new(1 << 15).unwrap().trailing_zeros(), 15);
+    assert_eq!(NonZero::<i16>::new(1 << 15).unwrap().trailing_zeros(), 15);
+    assert_eq!(NonZero::<u32>::new(1 << 31).unwrap().trailing_zeros(), 31);
+    assert_eq!(NonZero::<i32>::new(1 << 31).unwrap().trailing_zeros(), 31);
+    assert_eq!(NonZero::<u64>::new(1 << 63).unwrap().trailing_zeros(), 63);
+    assert_eq!(NonZero::<i64>::new(1 << 63).unwrap().trailing_zeros(), 63);
+    assert_eq!(NonZero::<u128>::new(1 << 127).unwrap().trailing_zeros(), 127);
+    assert_eq!(NonZero::<i128>::new(1 << 127).unwrap().trailing_zeros(), 127);
 
     assert_eq!(
-        NonZeroUsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
+        NonZero::<usize>::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
         usize::BITS - 1
     );
     assert_eq!(
-        NonZeroIsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
+        NonZero::<isize>::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
         usize::BITS - 1
     );
 
-    const TRAILING_ZEROS: u32 = NonZeroU16::new(1 << 2).unwrap().trailing_zeros();
+    const TRAILING_ZEROS: u32 = NonZero::<u16>::new(1 << 2).unwrap().trailing_zeros();
     assert_eq!(TRAILING_ZEROS, 2);
 }
 
 #[test]
 fn test_nonzero_uint_div() {
-    let nz = NonZeroU32::new(1).unwrap();
+    let nz = NonZero::<u32>::new(1).unwrap();
 
     let x: u32 = 42u32 / nz;
     assert_eq!(x, 42u32);
@@ -330,7 +331,7 @@ fn test_nonzero_uint_div() {
 
 #[test]
 fn test_nonzero_uint_rem() {
-    let nz = NonZeroU32::new(10).unwrap();
+    let nz = NonZero::<u32>::new(10).unwrap();
 
     let x: u32 = 42u32 % nz;
     assert_eq!(x, 2u32);
@@ -338,18 +339,18 @@ fn test_nonzero_uint_rem() {
 
 #[test]
 fn test_signed_nonzero_neg() {
-    assert_eq!((-NonZeroI8::new(1).unwrap()).get(), -1);
-    assert_eq!((-NonZeroI8::new(-1).unwrap()).get(), 1);
+    assert_eq!((-NonZero::<i8>::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZero::<i8>::new(-1).unwrap()).get(), 1);
 
-    assert_eq!((-NonZeroI16::new(1).unwrap()).get(), -1);
-    assert_eq!((-NonZeroI16::new(-1).unwrap()).get(), 1);
+    assert_eq!((-NonZero::<i16>::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZero::<i16>::new(-1).unwrap()).get(), 1);
 
-    assert_eq!((-NonZeroI32::new(1).unwrap()).get(), -1);
-    assert_eq!((-NonZeroI32::new(-1).unwrap()).get(), 1);
+    assert_eq!((-NonZero::<i32>::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZero::<i32>::new(-1).unwrap()).get(), 1);
 
-    assert_eq!((-NonZeroI64::new(1).unwrap()).get(), -1);
-    assert_eq!((-NonZeroI64::new(-1).unwrap()).get(), 1);
+    assert_eq!((-NonZero::<i64>::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZero::<i64>::new(-1).unwrap()).get(), 1);
 
-    assert_eq!((-NonZeroI128::new(1).unwrap()).get(), -1);
-    assert_eq!((-NonZeroI128::new(-1).unwrap()).get(), 1);
+    assert_eq!((-NonZero::<i128>::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZero::<i128>::new(-1).unwrap()).get(), 1);
 }
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index b68f2a50b32..8a0cf90d799 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -1,6 +1,6 @@
 use core::cell::RefCell;
 use core::mem::{self, MaybeUninit};
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::ptr;
 use core::ptr::*;
 use std::fmt::{Debug, Display};
@@ -1051,7 +1051,7 @@ fn nonnull_tagged_pointer_with_provenance() {
         pub fn pointer(self) -> NonNull<T> {
             // SAFETY: The `addr` guaranteed to have bits set in the Self::ADDRESS_MASK, so the result will be non-null.
             self.0.map_addr(|addr| unsafe {
-                NonZeroUsize::new_unchecked(addr.get() & Self::ADDRESS_MASK)
+                NonZero::<usize>::new_unchecked(addr.get() & Self::ADDRESS_MASK)
             })
         }
 
@@ -1073,7 +1073,7 @@ fn nonnull_tagged_pointer_with_provenance() {
             // ADDRESS_MASK) will always be non-zero. This a property of the type and its
             // construction.
             self.0 = self.0.map_addr(|addr| unsafe {
-                NonZeroUsize::new_unchecked((addr.get() & Self::ADDRESS_MASK) | data)
+                NonZero::<usize>::new_unchecked((addr.get() & Self::ADDRESS_MASK) | data)
             })
         }
     }
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index 50926da3ce7..758203408a8 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -406,13 +406,14 @@ fn result_opt_conversions() {
 
 #[test]
 fn result_try_trait_v2_branch() {
-    use core::num::NonZeroU32;
+    use core::num::NonZero;
     use core::ops::{ControlFlow::*, Try};
+
     assert_eq!(Ok::<i32, i32>(4).branch(), Continue(4));
     assert_eq!(Err::<i32, i32>(4).branch(), Break(Err(4)));
-    let one = NonZeroU32::new(1).unwrap();
-    assert_eq!(Ok::<(), NonZeroU32>(()).branch(), Continue(()));
-    assert_eq!(Err::<(), NonZeroU32>(one).branch(), Break(Err(one)));
-    assert_eq!(Ok::<NonZeroU32, ()>(one).branch(), Continue(one));
-    assert_eq!(Err::<NonZeroU32, ()>(()).branch(), Break(Err(())));
+    let one = NonZero::<u32>::new(1).unwrap();
+    assert_eq!(Ok::<(), NonZero<u32>>(()).branch(), Continue(()));
+    assert_eq!(Err::<(), NonZero<u32>>(one).branch(), Break(Err(one)));
+    assert_eq!(Ok::<NonZero<u32>, ()>(one).branch(), Continue(one));
+    assert_eq!(Err::<NonZero<u32>, ()>(()).branch(), Break(Err(())));
 }
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index bcf7b5e5977..bb2c17a479e 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -1,7 +1,7 @@
 use core::cell::Cell;
 use core::cmp::Ordering;
 use core::mem::MaybeUninit;
-use core::num::NonZeroUsize;
+use core::num::NonZero;
 use core::slice;
 
 #[test]
@@ -147,7 +147,7 @@ fn test_iterator_advance_by() {
     }
 
     let mut iter = v.iter();
-    assert_eq!(iter.advance_by(v.len() + 1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!(iter.advance_by(v.len() + 1), Err(NonZero::<usize>::new(1).unwrap()));
     assert_eq!(iter.as_slice(), &[]);
 
     let mut iter = v.iter();
@@ -169,7 +169,7 @@ fn test_iterator_advance_back_by() {
     }
 
     let mut iter = v.iter();
-    assert_eq!(iter.advance_back_by(v.len() + 1), Err(NonZeroUsize::new(1).unwrap()));
+    assert_eq!(iter.advance_back_by(v.len() + 1), Err(NonZero::<usize>::new(1).unwrap()));
     assert_eq!(iter.as_slice(), &[]);
 
     let mut iter = v.iter();
diff --git a/library/proc_macro/src/bridge/handle.rs b/library/proc_macro/src/bridge/handle.rs
index b3a76306997..894acae217e 100644
--- a/library/proc_macro/src/bridge/handle.rs
+++ b/library/proc_macro/src/bridge/handle.rs
@@ -2,13 +2,13 @@
 
 use std::collections::BTreeMap;
 use std::hash::Hash;
-use std::num::NonZeroU32;
+use std::num::NonZero;
 use std::ops::{Index, IndexMut};
 use std::sync::atomic::{AtomicU32, Ordering};
 
 use super::fxhash::FxHashMap;
 
-pub(super) type Handle = NonZeroU32;
+pub(super) type Handle = NonZero<u32>;
 
 /// A store that associates values of type `T` with numeric handles. A value can
 /// be looked up using its handle.
@@ -20,7 +20,7 @@ pub(super) struct OwnedStore<T: 'static> {
 impl<T> OwnedStore<T> {
     pub(super) fn new(counter: &'static AtomicU32) -> Self {
         // Ensure the handle counter isn't 0, which would panic later,
-        // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`.
+        // when `NonZero::new` (aka `Handle::new`) is called in `alloc`.
         assert_ne!(counter.load(Ordering::SeqCst), 0);
 
         OwnedStore { counter, data: BTreeMap::new() }
diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs
index 5b1bfb30983..6d75a5a627c 100644
--- a/library/proc_macro/src/bridge/rpc.rs
+++ b/library/proc_macro/src/bridge/rpc.rs
@@ -2,7 +2,7 @@
 
 use std::any::Any;
 use std::io::Write;
-use std::num::NonZeroU32;
+use std::num::NonZero;
 use std::str;
 
 pub(super) type Writer = super::buffer::Buffer;
@@ -157,13 +157,13 @@ impl<S> DecodeMut<'_, '_, S> for char {
     }
 }
 
-impl<S> Encode<S> for NonZeroU32 {
+impl<S> Encode<S> for NonZero<u32> {
     fn encode(self, w: &mut Writer, s: &mut S) {
         self.get().encode(w, s);
     }
 }
 
-impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
+impl<S> DecodeMut<'_, '_, S> for NonZero<u32> {
     fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
         Self::new(u32::decode(r, s)).unwrap()
     }
diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs
index 930c111455d..ae3c0fe018f 100644
--- a/library/proc_macro/src/bridge/symbol.rs
+++ b/library/proc_macro/src/bridge/symbol.rs
@@ -10,14 +10,14 @@
 //! proc_macro, this module should probably be removed or simplified.
 
 use std::cell::RefCell;
-use std::num::NonZeroU32;
+use std::num::NonZero;
 use std::str;
 
 use super::*;
 
 /// Handle for a symbol string stored within the Interner.
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Symbol(NonZeroU32);
+pub struct Symbol(NonZero<u32>);
 
 impl !Send for Symbol {}
 impl !Sync for Symbol {}
@@ -137,7 +137,7 @@ thread_local! {
         names: fxhash::FxHashMap::default(),
         strings: Vec::new(),
         // Start with a base of 1 to make sure that `NonZeroU32` works.
-        sym_base: NonZeroU32::new(1).unwrap(),
+        sym_base: NonZero::<u32>::new(1).unwrap(),
     });
 }
 
@@ -152,7 +152,7 @@ struct Interner {
     // The offset to apply to symbol names stored in the interner. This is used
     // to ensure that symbol names are not re-used after the interner is
     // cleared.
-    sym_base: NonZeroU32,
+    sym_base: NonZero<u32>,
 }
 
 impl Interner {
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 90b76cbc26e..1e6e4a04310 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -26,6 +26,7 @@
 #![feature(staged_api)]
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
+#![feature(generic_nonzero)]
 #![feature(maybe_uninit_write_slice)]
 #![feature(negative_impls)]
 #![feature(new_uninit)]
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 3384906a15e..789de7f41ff 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -5,7 +5,7 @@ use super::thread_local_dtor::run_dtors;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ptr;
 use crate::time::Duration;
 
@@ -97,8 +97,8 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
-    unsafe { Ok(NonZeroUsize::new_unchecked(abi::get_processor_count())) }
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
+    unsafe { Ok(NonZero::<usize>::new_unchecked(abi::get_processor_count())) }
 }
 
 pub mod guard {
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs
index ae0f718535b..9c1387bf408 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/pal/itron/thread.rs
@@ -11,6 +11,7 @@ use crate::{
     ffi::CStr,
     hint, io,
     mem::ManuallyDrop,
+    num::NonZero,
     ptr::NonNull,
     sync::atomic::{AtomicUsize, Ordering},
     sys::thread_local_dtor::run_dtors,
@@ -363,6 +364,6 @@ unsafe fn terminate_and_delete_current_task() -> ! {
     unsafe { crate::hint::unreachable_unchecked() };
 }
 
-pub fn available_parallelism() -> io::Result<crate::num::NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     super::unsupported()
 }
diff --git a/library/std/src/sys/pal/sgx/abi/tls/mod.rs b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
index 09c4ab3d3e9..5ee1621420e 100644
--- a/library/std/src/sys/pal/sgx/abi/tls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
@@ -3,7 +3,7 @@ mod sync_bitset;
 use self::sync_bitset::*;
 use crate::cell::Cell;
 use crate::mem;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ptr;
 use crate::sync::atomic::{AtomicUsize, Ordering};
 
@@ -30,7 +30,7 @@ extern "C" {
 
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub struct Key(NonZeroUsize);
+pub struct Key(NonZero<usize>);
 
 impl Key {
     fn to_index(self) -> usize {
@@ -38,7 +38,7 @@ impl Key {
     }
 
     fn from_index(index: usize) -> Self {
-        Key(NonZeroUsize::new(index + 1).unwrap())
+        Key(NonZero::<usize>::new(index + 1).unwrap())
     }
 
     pub fn as_usize(self) -> usize {
@@ -46,7 +46,7 @@ impl Key {
     }
 
     pub fn from_usize(index: usize) -> Self {
-        Key(NonZeroUsize::new(index).unwrap())
+        Key(NonZero::<usize>::new(index).unwrap())
     }
 }
 
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
index 10c1456d4fd..4f52bb474b1 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
@@ -3,14 +3,15 @@
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub use fortanix_sgx_abi::*;
 
-use crate::num::NonZeroU64;
+use crate::num::NonZero;
 use crate::ptr::NonNull;
 
 #[repr(C)]
 struct UsercallReturn(u64, u64);
 
 extern "C" {
-    fn usercall(nr: NonZeroU64, p1: u64, p2: u64, abort: u64, p3: u64, p4: u64) -> UsercallReturn;
+    fn usercall(nr: NonZero<u64>, p1: u64, p2: u64, abort: u64, p3: u64, p4: u64)
+    -> UsercallReturn;
 }
 
 /// Performs the raw usercall operation as defined in the ABI calling convention.
@@ -26,7 +27,7 @@ extern "C" {
 #[unstable(feature = "sgx_platform", issue = "56975")]
 #[inline]
 pub unsafe fn do_usercall(
-    nr: NonZeroU64,
+    nr: NonZero<u64>,
     p1: u64,
     p2: u64,
     p3: u64,
@@ -194,7 +195,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[inline(always)]
         pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r {
             ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
-                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    rtunwrap!(Some, NonZero::<u64>::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     RegisterArgument::into_register($n2),
                     RegisterArgument::into_register($n3),
@@ -210,7 +211,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[inline(always)]
         pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r {
             ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
-                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    rtunwrap!(Some, NonZero::<u64>::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     RegisterArgument::into_register($n2),
                     RegisterArgument::into_register($n3),
@@ -226,7 +227,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[inline(always)]
         pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r {
             ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
-                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    rtunwrap!(Some, NonZero::<u64>::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     RegisterArgument::into_register($n2),
                     0,0,
@@ -241,7 +242,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[inline(always)]
         pub unsafe fn $f($n1: $t1) -> $r {
             ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
-                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    rtunwrap!(Some, NonZero::<u64>::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     0,0,0,
                     return_type_is_abort!($r)
@@ -255,7 +256,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[inline(always)]
         pub unsafe fn $f() -> $r {
             ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
-                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    rtunwrap!(Some, NonZero::<u64>::new(Usercalls::$f as Register)),
                     0,0,0,0,
                     return_type_is_abort!($r)
             ) })
diff --git a/library/std/src/sys/pal/sgx/rwlock.rs b/library/std/src/sys/pal/sgx/rwlock.rs
index d89de18ca5f..87bebac37da 100644
--- a/library/std/src/sys/pal/sgx/rwlock.rs
+++ b/library/std/src/sys/pal/sgx/rwlock.rs
@@ -1,7 +1,7 @@
 #[cfg(test)]
 mod tests;
 
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::sys_common::lazy_box::{LazyBox, LazyInit};
 
 use super::waitqueue::{
@@ -10,7 +10,7 @@ use super::waitqueue::{
 use crate::alloc::Layout;
 
 struct AllocatedRwLock {
-    readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
+    readers: SpinMutex<WaitVariable<Option<NonZero<usize>>>>,
     writer: SpinMutex<WaitVariable<bool>>,
 }
 
@@ -54,7 +54,7 @@ impl RwLock {
         } else {
             // No waiting writers, acquire the read lock
             *rguard.lock_var_mut() =
-                NonZeroUsize::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
+                NonZero::<usize>::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
         }
     }
 
@@ -69,7 +69,7 @@ impl RwLock {
         } else {
             // No waiting writers, acquire the read lock
             *rguard.lock_var_mut() =
-                NonZeroUsize::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
+                NonZero::<usize>::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
             true
         }
     }
@@ -108,10 +108,10 @@ impl RwLock {
     #[inline]
     unsafe fn __read_unlock(
         &self,
-        mut rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZeroUsize>>>,
+        mut rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZero<usize>>>>,
         wguard: SpinMutexGuard<'_, WaitVariable<bool>>,
     ) {
-        *rguard.lock_var_mut() = NonZeroUsize::new(rguard.lock_var().unwrap().get() - 1);
+        *rguard.lock_var_mut() = NonZero::<usize>::new(rguard.lock_var().unwrap().get() - 1);
         if rguard.lock_var().is_some() {
             // There are other active readers
         } else {
@@ -137,7 +137,7 @@ impl RwLock {
     #[inline]
     unsafe fn __write_unlock(
         &self,
-        rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZeroUsize>>>,
+        rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZero<usize>>>>,
         wguard: SpinMutexGuard<'_, WaitVariable<bool>>,
     ) {
         match WaitQueue::notify_one(wguard) {
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index 7ac9d1d64b4..c797fde7fbd 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -2,7 +2,7 @@
 use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::time::Duration;
 
 use super::abi::usercalls;
@@ -142,7 +142,7 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
 
diff --git a/library/std/src/sys/pal/sgx/waitqueue/mod.rs b/library/std/src/sys/pal/sgx/waitqueue/mod.rs
index 25eca61d67b..92ffec8d0b7 100644
--- a/library/std/src/sys/pal/sgx/waitqueue/mod.rs
+++ b/library/std/src/sys/pal/sgx/waitqueue/mod.rs
@@ -16,7 +16,7 @@ mod tests;
 mod spin_mutex;
 mod unsafe_list;
 
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ops::{Deref, DerefMut};
 use crate::panic::{self, AssertUnwindSafe};
 use crate::time::Duration;
@@ -68,7 +68,7 @@ impl<T> WaitVariable<T> {
 #[derive(Copy, Clone)]
 pub enum NotifiedTcs {
     Single(Tcs),
-    All { count: NonZeroUsize },
+    All { count: NonZero<usize> },
 }
 
 /// An RAII guard that will notify a set of target threads as well as unlock
@@ -252,7 +252,7 @@ impl WaitQueue {
                 entry_guard.wake = true;
             }
 
-            if let Some(count) = NonZeroUsize::new(count) {
+            if let Some(count) = NonZero::<usize>::new(count) {
                 Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } })
             } else {
                 Err(guard)
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index 155f333f906..77f9040ead5 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -4,7 +4,7 @@ use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ptr;
 use crate::sys::os;
 use crate::time::Duration;
@@ -140,7 +140,7 @@ impl Drop for Thread {
 
 // Note: Both `sched_getaffinity` and `sysconf` are available but not functional on
 // teeos, so this function always returns an Error!
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     Err(io::Error::new(
         io::ErrorKind::NotFound,
         "The number of hardware threads is not known for the target platform",
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
index ddfc3af2f50..f6f5b20a421 100644
--- a/library/std/src/sys/pal/uefi/thread.rs
+++ b/library/std/src/sys/pal/uefi/thread.rs
@@ -1,7 +1,7 @@
 use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ptr::NonNull;
 use crate::time::Duration;
 
@@ -44,9 +44,9 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // UEFI is single threaded
-    Ok(NonZeroUsize::new(1).unwrap())
+    Ok(NonZero::<usize>::new(1).unwrap())
 }
 
 pub mod guard {
diff --git a/library/std/src/sys/pal/unix/process/process_common/tests.rs b/library/std/src/sys/pal/unix/process/process_common/tests.rs
index 4e41efc9096..823b4a56336 100644
--- a/library/std/src/sys/pal/unix/process/process_common/tests.rs
+++ b/library/std/src/sys/pal/unix/process/process_common/tests.rs
@@ -170,7 +170,7 @@ fn test_program_kind() {
 )))]
 #[test]
 fn unix_exit_statuses() {
-    use crate::num::NonZeroI32;
+    use crate::num::NonZero;
     use crate::os::unix::process::ExitStatusExt;
     use crate::process::*;
 
@@ -182,7 +182,7 @@ fn unix_exit_statuses() {
 
         assert_eq!(exit_status.code(), Some(exit_code));
 
-        if let Ok(nz) = NonZeroI32::try_from(exit_code) {
+        if let Ok(nz) = NonZero::try_from(exit_code) {
             assert!(!exit_status.success());
             let es_error = exit_status.exit_ok().unwrap_err();
             assert_eq!(es_error.code().unwrap(), i32::from(nz));
diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs
index 9931c2af2f1..b6a74fb4831 100644
--- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs
@@ -1,7 +1,7 @@
 use crate::fmt;
 use crate::io;
 use crate::mem;
-use crate::num::{NonZeroI32, NonZeroI64};
+use crate::num::NonZero;
 use crate::ptr;
 
 use crate::sys::process::process_common::*;
@@ -240,7 +240,7 @@ pub struct ExitStatus(i64);
 
 impl ExitStatus {
     pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
-        match NonZeroI64::try_from(self.0) {
+        match NonZero::try_from(self.0) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => Ok(()),
         }
@@ -314,7 +314,7 @@ impl fmt::Display for ExitStatus {
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(NonZeroI64);
+pub struct ExitStatusError(NonZero<i64>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
@@ -323,7 +323,7 @@ impl Into<ExitStatus> for ExitStatusError {
 }
 
 impl ExitStatusError {
-    pub fn code(self) -> Option<NonZeroI32> {
+    pub fn code(self) -> Option<NonZero<i32>> {
         // fixme: affected by the same bug as ExitStatus::code()
         ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap())
     }
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 94c4c56bd51..d5a77085725 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -1,7 +1,7 @@
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::mem;
-use crate::num::{NonZero, NonZeroI32};
+use crate::num::NonZero;
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
@@ -1106,7 +1106,7 @@ impl fmt::Debug for ExitStatusError {
 }
 
 impl ExitStatusError {
-    pub fn code(self) -> Option<NonZeroI32> {
+    pub fn code(self) -> Option<NonZero<i32>> {
         ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap())
     }
 }
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported.rs b/library/std/src/sys/pal/unix/process/process_unsupported.rs
index 89a2a0c6e56..33d359d3f84 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/pal/unix/process/process_unsupported.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::io;
-use crate::num::{NonZero, NonZeroI32};
+use crate::num::NonZero;
 use crate::sys::pal::unix::unsupported::*;
 use crate::sys::process::process_common::*;
 
@@ -67,7 +67,7 @@ impl Into<ExitStatus> for ExitStatusError {
 }
 
 impl ExitStatusError {
-    pub fn code(self) -> Option<NonZeroI32> {
+    pub fn code(self) -> Option<NonZero<i32>> {
         ExitStatus::from(c_int::from(self.0)).code().map(|st| st.try_into().unwrap())
     }
 }
diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs
index 5b4e94d0f1b..76179e0910d 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
-use crate::num::{NonZero, NonZeroI32};
+use crate::num::NonZero;
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
@@ -257,7 +257,7 @@ impl Into<ExitStatus> for ExitStatusError {
 }
 
 impl ExitStatusError {
-    pub fn code(self) -> Option<NonZeroI32> {
+    pub fn code(self) -> Option<NonZero<i32>> {
         ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap())
     }
 }
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7e4a01a5ecd..dd3c370667a 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -2,7 +2,7 @@ use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::ptr;
 use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
@@ -306,7 +306,7 @@ fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_W
     result
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     cfg_if::cfg_if! {
         if #[cfg(any(
             target_os = "android",
@@ -338,7 +338,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                         // some old MIPS kernels were buggy and zero-initialized the mask if
                         // none was explicitly set.
                         // In that case we use the sysconf fallback.
-                        if let Some(count) = NonZeroUsize::new(count) {
+                        if let Some(count) = NonZero::<usize>::new(count) {
                             return Ok(count)
                         }
                     }
@@ -351,7 +351,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                     let count = cpus as usize;
                     // Cover the unusual situation where we were able to get the quota but not the affinity mask
                     let count = count.min(quota);
-                    Ok(unsafe { NonZeroUsize::new_unchecked(count) })
+                    Ok(unsafe { NonZero::<usize>::new_unchecked(count) })
                 }
             }
         } else if #[cfg(any(
@@ -375,7 +375,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                     ) == 0 {
                         let count = libc::CPU_COUNT(&set) as usize;
                         if count > 0 {
-                            return Ok(NonZeroUsize::new_unchecked(count));
+                            return Ok(NonZero::<usize>::new_unchecked(count));
                         }
                     }
                 }
@@ -397,7 +397,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                             }
                         }
                         libc::_cpuset_destroy(set);
-                        if let Some(count) = NonZeroUsize::new(count) {
+                        if let Some(count) = NonZero::<usize>::new(count) {
                             return Ok(count);
                         }
                     }
@@ -433,7 +433,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                 }
             }
 
-            Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
+            Ok(unsafe { NonZero::<usize>::new_unchecked(cpus as usize) })
         } else if #[cfg(target_os = "nto")] {
             unsafe {
                 use libc::_syspage_ptr;
@@ -441,7 +441,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                     Err(io::const_io_error!(io::ErrorKind::NotFound, "No syspage available"))
                 } else {
                     let cpus = (*_syspage_ptr).num_cpu;
-                    NonZeroUsize::new(cpus as usize)
+                    NonZero::<usize>::new(cpus as usize)
                         .ok_or(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"))
                 }
             }
@@ -456,7 +456,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                     return Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
                 }
 
-                Ok(NonZeroUsize::new_unchecked(sinfo.cpu_count as usize))
+                Ok(NonZero::<usize>::new_unchecked(sinfo.cpu_count as usize))
             }
         } else {
             // FIXME: implement on vxWorks, Redox, l4re
diff --git a/library/std/src/sys/pal/unsupported/process.rs b/library/std/src/sys/pal/unsupported/process.rs
index a639afcc674..6a989dd3e76 100644
--- a/library/std/src/sys/pal/unsupported/process.rs
+++ b/library/std/src/sys/pal/unsupported/process.rs
@@ -2,7 +2,7 @@ use crate::ffi::OsStr;
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::num::NonZeroI32;
+use crate::num::NonZero;
 use crate::path::Path;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
@@ -170,7 +170,7 @@ impl Into<ExitStatus> for ExitStatusError {
 }
 
 impl ExitStatusError {
-    pub fn code(self) -> Option<NonZeroI32> {
+    pub fn code(self) -> Option<NonZero<i32>> {
         self.0
     }
 }
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs
index a8db251de20..cd1ae7f7d11 100644
--- a/library/std/src/sys/pal/unsupported/thread.rs
+++ b/library/std/src/sys/pal/unsupported/thread.rs
@@ -1,7 +1,7 @@
 use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::time::Duration;
 
 pub struct Thread(!);
@@ -31,7 +31,7 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
 
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index a0eefa8811a..77d8b4378e7 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -1,7 +1,7 @@
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::sys::unsupported;
 use crate::time::Duration;
 
@@ -186,7 +186,7 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
 
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
index 714b7049227..49f936f1449 100644
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ b/library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -1,6 +1,6 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::sys::unsupported;
 use crate::time::Duration;
 
@@ -40,7 +40,7 @@ impl Thread {
     pub fn join(self) {}
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
 
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index fbbdbc21265..c3a4d470699 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -10,7 +10,7 @@ use super::os::current_exe;
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::io;
-use crate::num::NonZeroU16;
+use crate::num::NonZero;
 use crate::os::windows::prelude::*;
 use crate::path::{Path, PathBuf};
 use crate::sys::path::get_long_path;
@@ -21,12 +21,12 @@ use crate::vec;
 
 use crate::iter;
 
-/// This is the const equivalent to `NonZeroU16::new(n).unwrap()`
+/// This is the const equivalent to `NonZero::<u16>::new(n).unwrap()`
 ///
 /// FIXME: This can be removed once `Option::unwrap` is stably const.
 /// See the `const_option` feature (#67441).
-const fn non_zero_u16(n: u16) -> NonZeroU16 {
-    match NonZeroU16::new(n) {
+const fn non_zero_u16(n: u16) -> NonZero<u16> {
+    match NonZero::<u16>::new(n) {
         Some(n) => n,
         None => panic!("called `unwrap` on a `None` value"),
     }
@@ -69,10 +69,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>(
     lp_cmd_line: Option<WStrUnits<'a>>,
     exe_name: F,
 ) -> Vec<OsString> {
-    const BACKSLASH: NonZeroU16 = non_zero_u16(b'\\' as u16);
-    const QUOTE: NonZeroU16 = non_zero_u16(b'"' as u16);
-    const TAB: NonZeroU16 = non_zero_u16(b'\t' as u16);
-    const SPACE: NonZeroU16 = non_zero_u16(b' ' as u16);
+    const BACKSLASH: NonZero<u16> = non_zero_u16(b'\\' as u16);
+    const QUOTE: NonZero<u16> = non_zero_u16(b'"' as u16);
+    const TAB: NonZero<u16> = non_zero_u16(b'\t' as u16);
+    const SPACE: NonZero<u16> = non_zero_u16(b' ' as u16);
 
     let mut ret_val = Vec::new();
     // If the cmd line pointer is null or it points to an empty string then
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 9ec775959fd..6a94d377140 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -12,7 +12,7 @@ use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::mem;
 use crate::mem::MaybeUninit;
-use crate::num::NonZeroI32;
+use crate::num::NonZero;
 use crate::os::windows::ffi::{OsStrExt, OsStringExt};
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle};
 use crate::path::{Path, PathBuf};
@@ -747,7 +747,7 @@ impl Into<ExitStatus> for ExitStatusError {
 }
 
 impl ExitStatusError {
-    pub fn code(self) -> Option<NonZeroI32> {
+    pub fn code(self) -> Option<NonZero<i32>> {
         Some((u32::from(self.0) as i32).try_into().unwrap())
     }
 }
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index 1fe74493519..4f189944fb2 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -1,6 +1,6 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::os::windows::io::AsRawHandle;
 use crate::os::windows::io::HandleOrNull;
 use crate::ptr;
@@ -110,7 +110,7 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     let res = unsafe {
         let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed();
         c::GetSystemInfo(&mut sysinfo);
@@ -121,7 +121,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
             io::ErrorKind::NotFound,
             "The number of hardware threads is not known for the target platform",
         )),
-        cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }),
+        cpus => Ok(unsafe { NonZero::<usize>::new_unchecked(cpus) }),
     }
 }
 
diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs
index 0f452e07a5c..2cc15856501 100644
--- a/library/std/src/sys/pal/xous/thread.rs
+++ b/library/std/src/sys/pal/xous/thread.rs
@@ -1,6 +1,6 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZeroUsize;
+use crate::num::NonZero;
 use crate::os::xous::ffi::{
     blocking_scalar, create_thread, do_yield, join_thread, map_memory, update_memory_flags,
     MemoryFlags, Syscall, ThreadId,
@@ -132,9 +132,9 @@ impl Thread {
     }
 }
 
-pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // We're unicore right now.
-    Ok(unsafe { NonZeroUsize::new_unchecked(1) })
+    Ok(unsafe { NonZero::<usize>::new_unchecked(1) })
 }
 
 pub mod guard {
diff --git a/library/std/src/sys_common/wstr.rs b/library/std/src/sys_common/wstr.rs
index b230fd1a829..601ef3dd150 100644
--- a/library/std/src/sys_common/wstr.rs
+++ b/library/std/src/sys_common/wstr.rs
@@ -2,7 +2,7 @@
 #![allow(dead_code)]
 
 use crate::marker::PhantomData;
-use crate::num::NonZeroU16;
+use crate::num::NonZero;
 use crate::ptr::NonNull;
 
 /// A safe iterator over a LPWSTR
@@ -23,15 +23,15 @@ impl WStrUnits<'_> {
         Some(Self { lpwstr: NonNull::new(lpwstr as _)?, lifetime: PhantomData })
     }
 
-    pub fn peek(&self) -> Option<NonZeroU16> {
+    pub fn peek(&self) -> Option<NonZero<u16>> {
         // SAFETY: It's always safe to read the current item because we don't
         // ever move out of the array's bounds.
-        unsafe { NonZeroU16::new(*self.lpwstr.as_ptr()) }
+        unsafe { NonZero::<u16>::new(*self.lpwstr.as_ptr()) }
     }
 
     /// Advance the iterator while `predicate` returns true.
     /// Returns the number of items it advanced by.
-    pub fn advance_while<P: FnMut(NonZeroU16) -> bool>(&mut self, mut predicate: P) -> usize {
+    pub fn advance_while<P: FnMut(NonZero<u16>) -> bool>(&mut self, mut predicate: P) -> usize {
         let mut counter = 0;
         while let Some(w) = self.peek() {
             if !predicate(w) {
@@ -46,8 +46,9 @@ impl WStrUnits<'_> {
 
 impl Iterator for WStrUnits<'_> {
     // This can never return zero as that marks the end of the string.
-    type Item = NonZeroU16;
-    fn next(&mut self) -> Option<NonZeroU16> {
+    type Item = NonZero<u16>;
+
+    fn next(&mut self) -> Option<Self::Item> {
         // SAFETY: If NULL is reached we immediately return.
         // Therefore it's safe to advance the pointer after that.
         unsafe {
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index eb837c8f6c6..0da3da23568 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -165,8 +165,7 @@ use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
 use crate::mem::{self, forget};
-use crate::num::NonZeroU64;
-use crate::num::NonZeroUsize;
+use crate::num::{NonZero, NonZeroU64, NonZeroUsize};
 use crate::panic;
 use crate::panicking;
 use crate::pin::Pin;
@@ -1166,7 +1165,7 @@ pub fn park_timeout(dur: Duration) {
 /// [`id`]: Thread::id
 #[stable(feature = "thread_id", since = "1.19.0")]
 #[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
-pub struct ThreadId(NonZeroU64);
+pub struct ThreadId(NonZero<u64>);
 
 impl ThreadId {
     // Generate a new unique thread ID.
@@ -1189,7 +1188,7 @@ impl ThreadId {
                     };
 
                     match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) {
-                        Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()),
+                        Ok(_) => return ThreadId(NonZero::<u64>::new(id).unwrap()),
                         Err(id) => last = id,
                     }
                 }
@@ -1208,7 +1207,7 @@ impl ThreadId {
 
                 *counter = id;
                 drop(counter);
-                ThreadId(NonZeroU64::new(id).unwrap())
+                ThreadId(NonZero::<u64>::new(id).unwrap())
             }
         }
     }
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index de7a4b79d26..095ba173671 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -1,3 +1,4 @@
+#![feature(generic_nonzero)]
 #![feature(rustc_private, stmt_expr_attributes)]
 #![allow(
     clippy::manual_range_contains,
@@ -17,7 +18,7 @@ extern crate rustc_middle;
 extern crate rustc_session;
 
 use std::env::{self, VarError};
-use std::num::NonZeroU64;
+use std::num::NonZero;
 use std::path::PathBuf;
 use std::str::FromStr;
 
@@ -528,7 +529,7 @@ fn main() {
                 }
             }
         } else if let Some(param) = arg.strip_prefix("-Zmiri-track-alloc-id=") {
-            let ids: Vec<miri::AllocId> = match parse_comma_list::<NonZeroU64>(param) {
+            let ids: Vec<miri::AllocId> = match parse_comma_list::<NonZero<u64>>(param) {
                 Ok(ids) => ids.into_iter().map(miri::AllocId).collect(),
                 Err(err) =>
                     show_error!(
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 46f96a715f1..4424595ea1c 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -1,6 +1,6 @@
 use std::cell::RefCell;
 use std::fmt;
-use std::num::NonZeroU64;
+use std::num::NonZero;
 
 use log::trace;
 use smallvec::SmallVec;
@@ -13,22 +13,22 @@ use crate::*;
 pub mod stacked_borrows;
 pub mod tree_borrows;
 
-pub type CallId = NonZeroU64;
+pub type CallId = NonZero<u64>;
 
 /// Tracking pointer provenance
 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct BorTag(NonZeroU64);
+pub struct BorTag(NonZero<u64>);
 
 impl BorTag {
     pub fn new(i: u64) -> Option<Self> {
-        NonZeroU64::new(i).map(BorTag)
+        NonZero::<u64>::new(i).map(BorTag)
     }
 
     pub fn get(&self) -> u64 {
         self.0.get()
     }
 
-    pub fn inner(&self) -> NonZeroU64 {
+    pub fn inner(&self) -> NonZero<u64> {
         self.0
     }
 
@@ -184,7 +184,7 @@ impl GlobalStateInner {
             borrow_tracker_method,
             next_ptr_tag: BorTag::one(),
             base_ptr_tags: FxHashMap::default(),
-            next_call_id: NonZeroU64::new(1).unwrap(),
+            next_call_id: NonZero::<u64>::new(1).unwrap(),
             protected_tags: FxHashMap::default(),
             tracked_pointer_tags,
             tracked_call_ids,
@@ -206,7 +206,7 @@ impl GlobalStateInner {
         if self.tracked_call_ids.contains(&call_id) {
             machine.emit_diagnostic(NonHaltingDiagnostic::CreatedCallId(call_id));
         }
-        self.next_call_id = NonZeroU64::new(call_id.get() + 1).unwrap();
+        self.next_call_id = NonZero::<u64>::new(call_id.get() + 1).unwrap();
         FrameState { call_id, protected_tags: SmallVec::new() }
     }
 
diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs
index 9a848d50341..35dcfecbbe3 100644
--- a/src/tools/miri/src/concurrency/init_once.rs
+++ b/src/tools/miri/src/concurrency/init_once.rs
@@ -1,5 +1,4 @@
 use std::collections::VecDeque;
-use std::num::NonZeroU32;
 
 use rustc_index::Idx;
 use rustc_middle::ty::layout::TyAndLayout;
diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs
index b288b69e0ce..c3130c8a8f0 100644
--- a/src/tools/miri/src/concurrency/sync.rs
+++ b/src/tools/miri/src/concurrency/sync.rs
@@ -1,5 +1,4 @@
 use std::collections::{hash_map::Entry, VecDeque};
-use std::num::NonZeroU32;
 use std::ops::Not;
 
 use log::trace;
@@ -26,12 +25,12 @@ macro_rules! declare_id {
         /// 0 is used to indicate that the id was not yet assigned and,
         /// therefore, is not a valid identifier.
         #[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
-        pub struct $name(NonZeroU32);
+        pub struct $name(std::num::NonZero<u32>);
 
         impl SyncId for $name {
             // Panics if `id == 0`.
             fn from_u32(id: u32) -> Self {
-                Self(NonZeroU32::new(id).unwrap())
+                Self(std::num::NonZero::<u32>::new(id).unwrap())
             }
             fn to_u32(&self) -> u32 {
                 self.0.get()
@@ -44,11 +43,11 @@ macro_rules! declare_id {
                 // therefore, need to shift by one when converting from an index
                 // into a vector.
                 let shifted_idx = u32::try_from(idx).unwrap().checked_add(1).unwrap();
-                $name(NonZeroU32::new(shifted_idx).unwrap())
+                $name(std::num::NonZero::<u32>::new(shifted_idx).unwrap())
             }
             fn index(self) -> usize {
                 // See the comment in `Self::new`.
-                // (This cannot underflow because self is NonZeroU32.)
+                // (This cannot underflow because `self.0` is `NonZero<u32>`.)
                 usize::try_from(self.0.get() - 1).unwrap()
             }
         }
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 7f91af59d56..19b29a41819 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -1,5 +1,5 @@
 use std::fmt::{self, Write};
-use std::num::NonZeroU64;
+use std::num::NonZero;
 
 use log::trace;
 
@@ -115,7 +115,7 @@ pub enum NonHaltingDiagnostic {
     /// (new_tag, new_perm, (alloc_id, base_offset, orig_tag))
     ///
     /// new_perm is `None` for base tags.
-    CreatedPointerTag(NonZeroU64, Option<String>, Option<(AllocId, AllocRange, ProvenanceExtra)>),
+    CreatedPointerTag(NonZero<u64>, Option<String>, Option<(AllocId, AllocRange, ProvenanceExtra)>),
     /// This `Item` was popped from the borrow stack. The string explains the reason.
     PoppedPointerTag(Item, String),
     CreatedCallId(CallId),
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index d6b1e135808..3cee4df5885 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -1,6 +1,6 @@
 use std::cmp;
 use std::iter;
-use std::num::NonZeroUsize;
+use std::num::NonZero;
 use std::time::Duration;
 
 use log::trace;
@@ -574,7 +574,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             fn visit_union(
                 &mut self,
                 _v: &MPlaceTy<'tcx, Provenance>,
-                _fields: NonZeroUsize,
+                _fields: NonZero<usize>,
             ) -> InterpResult<'tcx> {
                 bug!("we should have already handled unions in `visit_value`")
             }
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 5a2bb84f3ef..305c71fb0f9 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -1,6 +1,7 @@
 #![feature(rustc_private)]
 #![feature(cell_update)]
 #![feature(float_gamma)]
+#![feature(generic_nonzero)]
 #![feature(map_try_insert)]
 #![feature(never_type)]
 #![feature(try_blocks)]
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 25654248db4..f0e6e0374d2 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -477,7 +477,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [id, show_unnamed] = this.check_shim(abi, Abi::Rust, link_name, args)?;
                 let id = this.read_scalar(id)?.to_u64()?;
                 let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?;
-                if let Some(id) = std::num::NonZeroU64::new(id) {
+                if let Some(id) = std::num::NonZero::<u64>::new(id) {
                     this.print_borrow_state(AllocId(id), show_unnamed)?;
                 }
             }