diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index a3783db5f80d6..f414ff746bb82 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 dd87a5c4dc384..fada69c4e6df1 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_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index cfb46f3ac8a96..08b6aead7288b 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1650,16 +1650,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
         let func_ty = func.ty(body, self.infcx.tcx);
         if let ty::FnDef(def_id, _) = *func_ty.kind() {
-            if self.tcx().is_intrinsic(def_id) {
-                match self.tcx().item_name(def_id) {
-                    sym::simd_shuffle => {
-                        if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
-                            self.tcx()
-                                .dcx()
-                                .emit_err(SimdShuffleLastConst { span: term.source_info.span });
-                        }
-                    }
-                    _ => {}
+            if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) {
+                if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
+                    self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span });
                 }
             }
         }
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 0f0d828c8fc3f..6e846d721f2e2 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -387,15 +387,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
 
         match instance.def {
             InstanceDef::Intrinsic(_) => {
-                crate::intrinsics::codegen_intrinsic_call(
+                match crate::intrinsics::codegen_intrinsic_call(
                     fx,
                     instance,
                     args,
                     ret_place,
                     target,
                     source_info,
-                );
-                return;
+                ) {
+                    Ok(()) => return,
+                    Err(instance) => Some(instance),
+                }
             }
             InstanceDef::DropGlue(_, None) => {
                 // empty drop glue - a nop.
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 819cb5ef137ce..476752c7230a7 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -268,7 +268,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
     destination: CPlace<'tcx>,
     target: Option<BasicBlock>,
     source_info: mir::SourceInfo,
-) {
+) -> Result<(), Instance<'tcx>> {
     let intrinsic = fx.tcx.item_name(instance.def_id());
     let instance_args = instance.args;
 
@@ -295,8 +295,9 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
             destination,
             target,
             source_info,
-        );
+        )?;
     }
+    Ok(())
 }
 
 fn codegen_float_intrinsic_call<'tcx>(
@@ -430,25 +431,20 @@ fn codegen_regular_intrinsic_call<'tcx>(
     ret: CPlace<'tcx>,
     destination: Option<BasicBlock>,
     source_info: mir::SourceInfo,
-) {
+) -> Result<(), Instance<'tcx>> {
+    assert_eq!(generic_args, instance.args);
     let usize_layout = fx.layout_of(fx.tcx.types.usize);
 
     match intrinsic {
         sym::abort => {
             fx.bcx.ins().trap(TrapCode::User(0));
-            return;
+            return Ok(());
         }
         sym::likely | sym::unlikely => {
             intrinsic_args!(fx, args => (a); intrinsic);
 
             ret.write_cvalue(fx, a);
         }
-        sym::is_val_statically_known => {
-            intrinsic_args!(fx, args => (_a); intrinsic);
-
-            let res = fx.bcx.ins().iconst(types::I8, 0);
-            ret.write_cvalue(fx, CValue::by_val(res, ret.layout()));
-        }
         sym::breakpoint => {
             intrinsic_args!(fx, args => (); intrinsic);
 
@@ -697,7 +693,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                         })
                     });
                     crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span));
-                    return;
+                    return Ok(());
                 }
             }
         }
@@ -792,7 +788,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                     if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
                         // special case for compiler-builtins to avoid having to patch it
                         crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
-                        return;
+                        return Ok(());
                     } else {
                         fx.tcx
                             .dcx()
@@ -802,7 +798,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
-                    return;
+                    return Ok(());
                 }
             }
             let clif_ty = fx.clif_type(ty).unwrap();
@@ -823,7 +819,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                     if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
                         // special case for compiler-builtins to avoid having to patch it
                         crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
-                        return;
+                        return Ok(());
                     } else {
                         fx.tcx
                             .dcx()
@@ -833,7 +829,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
-                    return;
+                    return Ok(());
                 }
             }
 
@@ -850,7 +846,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -872,7 +868,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
 
@@ -895,7 +891,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -917,7 +913,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -939,7 +935,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -960,7 +956,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -981,7 +977,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -1002,7 +998,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -1023,7 +1019,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -1044,7 +1040,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -1065,7 +1061,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -1086,7 +1082,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
-                    return;
+                    return Ok(());
                 }
             }
             let ty = fx.clif_type(layout.ty).unwrap();
@@ -1233,19 +1229,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
             ret.write_cvalue(fx, CValue::by_val(cmp, ret.layout()));
         }
 
-        sym::const_allocate => {
-            intrinsic_args!(fx, args => (_size, _align); intrinsic);
-
-            // returns a null pointer at runtime.
-            let null = fx.bcx.ins().iconst(fx.pointer_type, 0);
-            ret.write_cvalue(fx, CValue::by_val(null, ret.layout()));
-        }
-
-        sym::const_deallocate => {
-            intrinsic_args!(fx, args => (_ptr, _size, _align); intrinsic);
-            // nop at runtime.
-        }
-
         sym::black_box => {
             intrinsic_args!(fx, args => (a); intrinsic);
 
@@ -1261,13 +1244,12 @@ fn codegen_regular_intrinsic_call<'tcx>(
             );
         }
 
-        _ => {
-            fx.tcx
-                .dcx()
-                .span_fatal(source_info.span, format!("unsupported intrinsic {}", intrinsic));
-        }
+        // Unimplemented intrinsics must have a fallback body. The fallback body is obtained
+        // by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`.
+        _ => return Err(Instance::new(instance.def_id(), instance.args)),
     }
 
     let ret_block = fx.get_block(destination.unwrap());
     fx.bcx.ins().jump(ret_block, &[]);
+    Ok(())
 }
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index eac8cb437794b..f162ef831b768 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -90,7 +90,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, name: Symbol) ->
 }
 
 impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
-    fn codegen_intrinsic_call(&mut self, instance: Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], llresult: RValue<'gcc>, span: Span) {
+    fn codegen_intrinsic_call(&mut self, instance: Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], llresult: RValue<'gcc>, span: Span) -> Result<(), Instance<'tcx>> {
         let tcx = self.tcx;
         let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
 
@@ -137,7 +137,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                         args[2].immediate(),
                         llresult,
                     );
-                    return;
+                    return Ok(());
                 }
                 sym::breakpoint => {
                     unimplemented!();
@@ -166,12 +166,12 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                 sym::volatile_store => {
                     let dst = args[0].deref(self.cx());
                     args[1].val.volatile_store(self, dst);
-                    return;
+                    return Ok(());
                 }
                 sym::unaligned_volatile_store => {
                     let dst = args[0].deref(self.cx());
                     args[1].val.unaligned_volatile_store(self, dst);
-                    return;
+                    return Ok(());
                 }
                 sym::prefetch_read_data
                     | sym::prefetch_write_data
@@ -269,7 +269,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                             },
                             None => {
                                 tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
-                                return;
+                                return Ok(());
                             }
                         }
                     }
@@ -339,7 +339,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     extended_asm.set_volatile_flag(true);
 
                     // We have copied the value to `result` already.
-                    return;
+                    return Ok(());
                 }
 
                 sym::ptr_mask => {
@@ -357,11 +357,12 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                 _ if name_str.starts_with("simd_") => {
                     match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
                         Ok(llval) => llval,
-                        Err(()) => return,
+                        Err(()) => return Ok(()),
                     }
                 }
 
-                _ => bug!("unknown intrinsic '{}'", name),
+                // Fall back to default body
+                _ => return Err(Instance::new(instance.def_id(), instance.args)),
             };
 
         if !fn_abi.ret.is_ignore() {
@@ -376,6 +377,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     .store(self, result);
             }
         }
+        Ok(())
     }
 
     fn abort(&mut self) {
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index e3e48ecb3aa5f..4415c51acf684 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -86,7 +86,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
         args: &[OperandRef<'tcx, &'ll Value>],
         llresult: &'ll Value,
         span: Span,
-    ) {
+    ) -> Result<(), ty::Instance<'tcx>> {
         let tcx = self.tcx;
         let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
 
@@ -141,7 +141,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     args[2].immediate(),
                     llresult,
                 );
-                return;
+                return Ok(());
             }
             sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[]),
             sym::va_copy => {
@@ -194,17 +194,17 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 if !result.layout.is_zst() {
                     self.store(load, result.llval, result.align);
                 }
-                return;
+                return Ok(());
             }
             sym::volatile_store => {
                 let dst = args[0].deref(self.cx());
                 args[1].val.volatile_store(self, dst);
-                return;
+                return Ok(());
             }
             sym::unaligned_volatile_store => {
                 let dst = args[0].deref(self.cx());
                 args[1].val.unaligned_volatile_store(self, dst);
-                return;
+                return Ok(());
             }
             sym::prefetch_read_data
             | sym::prefetch_write_data
@@ -305,7 +305,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                             name,
                             ty,
                         });
-                        return;
+                        return Ok(());
                     }
                 }
             }
@@ -387,7 +387,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 .unwrap_or_else(|| bug!("failed to generate inline asm call for `black_box`"));
 
                 // We have copied the value to `result` already.
-                return;
+                return Ok(());
             }
 
             _ if name.as_str().starts_with("simd_") => {
@@ -395,11 +395,15 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     self, name, callee_ty, fn_args, args, ret_ty, llret_ty, span,
                 ) {
                     Ok(llval) => llval,
-                    Err(()) => return,
+                    Err(()) => return Ok(()),
                 }
             }
 
-            _ => bug!("unknown intrinsic '{}' -- should it have been lowered earlier?", name),
+            _ => {
+                debug!("unknown intrinsic '{}' -- falling back to default body", name);
+                // Call the fallback body instead of generating the intrinsic code
+                return Err(ty::Instance::new(instance.def_id(), instance.args));
+            }
         };
 
         if !fn_abi.ret.is_ignore() {
@@ -411,6 +415,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     .store(self, result);
             }
         }
+        Ok(())
     }
 
     fn abort(&mut self) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index e35b4029b4506..75d413dedad3e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -787,7 +787,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Handle intrinsics old codegen wants Expr's for, ourselves.
         let intrinsic = match def {
-            Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().item_name(def_id)),
+            Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()),
             _ => None,
         };
 
@@ -817,21 +817,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // The arguments we'll be passing. Plus one to account for outptr, if used.
         let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
-        let mut llargs = Vec::with_capacity(arg_count);
-
-        // Prepare the return value destination
-        let ret_dest = if target.is_some() {
-            let is_intrinsic = intrinsic.is_some();
-            self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, is_intrinsic)
-        } else {
-            ReturnDest::Nothing
-        };
 
         if intrinsic == Some(sym::caller_location) {
             return if let Some(target) = target {
                 let location =
                     self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
 
+                let mut llargs = Vec::with_capacity(arg_count);
+                let ret_dest =
+                    self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, true, true);
+                assert_eq!(llargs, []);
                 if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
                     location.val.store(bx, tmp);
                 }
@@ -842,9 +837,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             };
         }
 
-        match intrinsic {
-            None | Some(sym::drop_in_place) => {}
+        let instance = match intrinsic {
+            None | Some(sym::drop_in_place) => instance,
             Some(intrinsic) => {
+                let mut llargs = Vec::with_capacity(1);
+                let ret_dest = self.make_return_dest(
+                    bx,
+                    destination,
+                    &fn_abi.ret,
+                    &mut llargs,
+                    true,
+                    target.is_some(),
+                );
                 let dest = match ret_dest {
                     _ if fn_abi.ret.is_indirect() => llargs[0],
                     ReturnDest::Nothing => bx.const_undef(bx.type_ptr()),
@@ -878,27 +882,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     })
                     .collect();
 
-                Self::codegen_intrinsic_call(
-                    bx,
-                    *instance.as_ref().unwrap(),
-                    fn_abi,
-                    &args,
-                    dest,
-                    span,
-                );
+                let instance = *instance.as_ref().unwrap();
+                match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) {
+                    Ok(()) => {
+                        if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
+                            self.store_return(bx, ret_dest, &fn_abi.ret, dst.llval);
+                        }
 
-                if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
-                    self.store_return(bx, ret_dest, &fn_abi.ret, dst.llval);
+                        return if let Some(target) = target {
+                            helper.funclet_br(self, bx, target, mergeable_succ)
+                        } else {
+                            bx.unreachable();
+                            MergingSucc::False
+                        };
+                    }
+                    Err(instance) => Some(instance),
                 }
-
-                return if let Some(target) = target {
-                    helper.funclet_br(self, bx, target, mergeable_succ)
-                } else {
-                    bx.unreachable();
-                    MergingSucc::False
-                };
             }
-        }
+        };
+
+        let mut llargs = Vec::with_capacity(arg_count);
+        let destination = target.as_ref().map(|&target| {
+            (self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, false, true), target)
+        });
 
         // Split the rust-call tupled arguments off.
         let (first_args, untuple) = if abi == Abi::RustCall && !args.is_empty() {
@@ -1040,14 +1046,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             (_, Some(llfn)) => llfn,
             _ => span_bug!(span, "no instance or llfn for call"),
         };
-
         helper.do_call(
             self,
             bx,
             fn_abi,
             fn_ptr,
             &llargs,
-            target.as_ref().map(|&target| (ret_dest, target)),
+            destination,
             unwind,
             &copied_constant_arguments,
             mergeable_succ,
@@ -1632,7 +1637,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         fn_ret: &ArgAbi<'tcx, Ty<'tcx>>,
         llargs: &mut Vec<Bx::Value>,
         is_intrinsic: bool,
+        has_target: bool,
     ) -> ReturnDest<'tcx, Bx::Value> {
+        if !has_target {
+            return ReturnDest::Nothing;
+        }
         // If the return is ignored, we can just return a do-nothing `ReturnDest`.
         if fn_ret.is_ignore() {
             return ReturnDest::Nothing;
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 8530bf9e2b363..e4633acd81740 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -54,6 +54,7 @@ fn memset_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 }
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
+    /// In the `Err` case, returns the instance that should be called instead.
     pub fn codegen_intrinsic_call(
         bx: &mut Bx,
         instance: ty::Instance<'tcx>,
@@ -61,7 +62,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         args: &[OperandRef<'tcx, Bx::Value>],
         llresult: Bx::Value,
         span: Span,
-    ) {
+    ) -> Result<(), ty::Instance<'tcx>> {
         let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
 
         let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
@@ -81,7 +82,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let llval = match name {
             sym::abort => {
                 bx.abort();
-                return;
+                return Ok(());
             }
 
             sym::va_start => bx.va_start(args[0].immediate()),
@@ -150,7 +151,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     args[0].immediate(),
                     args[2].immediate(),
                 );
-                return;
+                return Ok(());
             }
             sym::write_bytes => {
                 memset_intrinsic(
@@ -161,7 +162,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     args[1].immediate(),
                     args[2].immediate(),
                 );
-                return;
+                return Ok(());
             }
 
             sym::volatile_copy_nonoverlapping_memory => {
@@ -174,7 +175,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     args[1].immediate(),
                     args[2].immediate(),
                 );
-                return;
+                return Ok(());
             }
             sym::volatile_copy_memory => {
                 copy_intrinsic(
@@ -186,7 +187,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     args[1].immediate(),
                     args[2].immediate(),
                 );
-                return;
+                return Ok(());
             }
             sym::volatile_set_memory => {
                 memset_intrinsic(
@@ -197,17 +198,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     args[1].immediate(),
                     args[2].immediate(),
                 );
-                return;
+                return Ok(());
             }
             sym::volatile_store => {
                 let dst = args[0].deref(bx.cx());
                 args[1].val.volatile_store(bx, dst);
-                return;
+                return Ok(());
             }
             sym::unaligned_volatile_store => {
                 let dst = args[0].deref(bx.cx());
                 args[1].val.unaligned_volatile_store(bx, dst);
-                return;
+                return Ok(());
             }
             sym::exact_div => {
                 let ty = arg_tys[0];
@@ -225,7 +226,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             name,
                             ty,
                         });
-                        return;
+                        return Ok(());
                     }
                 }
             }
@@ -245,7 +246,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             name,
                             ty: arg_tys[0],
                         });
-                        return;
+                        return Ok(());
                     }
                 }
             }
@@ -256,14 +257,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         span,
                         ty: arg_tys[0],
                     });
-                    return;
+                    return Ok(());
                 }
                 let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else {
                     bx.tcx().dcx().emit_err(InvalidMonomorphization::FloatToIntUnchecked {
                         span,
                         ty: ret_ty,
                     });
-                    return;
+                    return Ok(());
                 };
                 if signed {
                     bx.fptosi(args[0].immediate(), llret_ty)
@@ -280,16 +281,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
-            sym::const_allocate => {
-                // returns a null pointer at runtime.
-                bx.const_null(bx.type_ptr())
-            }
-
-            sym::const_deallocate => {
-                // nop at runtime.
-                return;
-            }
-
             // This requires that atomic intrinsics follow a specific naming pattern:
             // "atomic_<operation>[_<ordering>]"
             name if let Some(atomic) = name_str.strip_prefix("atomic_") => {
@@ -350,10 +341,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             bx.store(val, dest.llval, dest.align);
                             let dest = result.project_field(bx, 1);
                             bx.store(success, dest.llval, dest.align);
-                            return;
                         } else {
-                            return invalid_monomorphization(ty);
+                            invalid_monomorphization(ty);
                         }
+                        return Ok(());
                     }
 
                     "load" => {
@@ -383,7 +374,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 )
                             }
                         } else {
-                            return invalid_monomorphization(ty);
+                            invalid_monomorphization(ty);
+                            return Ok(());
                         }
                     }
 
@@ -399,10 +391,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 val = bx.ptrtoint(val, bx.type_isize());
                             }
                             bx.atomic_store(val, ptr, parse_ordering(bx, ordering), size);
-                            return;
                         } else {
-                            return invalid_monomorphization(ty);
+                            invalid_monomorphization(ty);
                         }
+                        return Ok(());
                     }
 
                     "fence" => {
@@ -410,7 +402,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             parse_ordering(bx, ordering),
                             SynchronizationScope::CrossThread,
                         );
-                        return;
+                        return Ok(());
                     }
 
                     "singlethreadfence" => {
@@ -418,7 +410,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             parse_ordering(bx, ordering),
                             SynchronizationScope::SingleThread,
                         );
-                        return;
+                        return Ok(());
                     }
 
                     // These are all AtomicRMW ops
@@ -449,7 +441,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             }
                             bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
                         } else {
-                            return invalid_monomorphization(ty);
+                            invalid_monomorphization(ty);
+                            return Ok(());
                         }
                     }
                 }
@@ -458,7 +451,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             sym::nontemporal_store => {
                 let dst = args[0].deref(bx.cx());
                 args[1].val.nontemporal_store(bx, dst);
-                return;
+                return Ok(());
             }
 
             sym::ptr_guaranteed_cmp => {
@@ -493,8 +486,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
             _ => {
                 // Need to use backend-specific things in the implementation.
-                bx.codegen_intrinsic_call(instance, fn_abi, args, llresult, span);
-                return;
+                return bx.codegen_intrinsic_call(instance, fn_abi, args, llresult, span);
             }
         };
 
@@ -507,6 +499,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     .store(bx, result);
             }
         }
+        Ok(())
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 450672fb94122..502f0b3fcb510 100644
--- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
@@ -8,6 +8,8 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
     /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`,
     /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics,
     /// add them to `compiler/rustc_codegen_llvm/src/context.rs`.
+    /// Returns `Err` if another instance should be called instead. This is used to invoke
+    /// intrinsic default bodies in case an intrinsic is not implemented by the backend.
     fn codegen_intrinsic_call(
         &mut self,
         instance: ty::Instance<'tcx>,
@@ -15,7 +17,7 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
         args: &[OperandRef<'tcx, Self::Value>],
         llresult: Self::Value,
         span: Span,
-    );
+    ) -> Result<(), ty::Instance<'tcx>>;
 
     fn abort(&mut self);
     fn assume(&mut self, val: Self::Value);
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index dbc29e607eff9..ddad6683afbd9 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -49,7 +49,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
         hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
             // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
             // foreign items cannot be evaluated at compile-time.
-            let is_const = if tcx.is_intrinsic(def_id) {
+            let is_const = if tcx.intrinsic(def_id).is_some() {
                 tcx.lookup_const_stability(def_id).is_some()
             } else {
                 false
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 33e96e7faa8d6..8af69220e03ac 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -288,7 +288,7 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
             if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
                 write!(f, "inside closure")
             } else {
-                // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever
+                // Note: this triggers a `must_produce_diag` state, which means that if we ever
                 // get here we must emit a diagnostic. We should never display a `FrameInfo` unless
                 // we actually want to emit a warning or error to the user.
                 write!(f, "inside `{}`", self.instance)
@@ -304,7 +304,7 @@ impl<'tcx> FrameInfo<'tcx> {
             errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 }
         } else {
             let instance = format!("{}", self.instance);
-            // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever get
+            // Note: this triggers a `must_produce_diag` state, which means that if we ever get
             // here we must emit a diagnostic. We should never display a `FrameInfo` unless we
             // actually want to emit a warning or error to the user.
             errors::FrameNote { where_: "instance", span, instance, times: 0 }
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 4037220e5ed4b..20eb0c830e22b 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -526,7 +526,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         match instance.def {
             ty::InstanceDef::Intrinsic(def_id) => {
-                assert!(self.tcx.is_intrinsic(def_id));
+                assert!(self.tcx.intrinsic(def_id).is_some());
                 // FIXME: Should `InPlace` arguments be reset to uninit?
                 M::call_intrinsic(
                     self,
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index eb9f3fee1650a..d9edcf6ea9700 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 340a496a68990..b200ecbf73af5 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 839cfd8d85acf..fd8be45e25d52 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_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 43048dc41d3c2..96c9e740568cc 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -861,7 +861,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     // We do not use `const` modifiers for intrinsic "functions", as intrinsics are
                     // `extern` functions, and these have no way to get marked `const`. So instead we
                     // use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
-                    if self.ccx.is_const_stable_const_fn() || tcx.is_intrinsic(callee) {
+                    if self.ccx.is_const_stable_const_fn() || tcx.intrinsic(callee).is_some() {
                         self.check_op(ops::FnCallUnstable(callee, None));
                         return;
                     }
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 2b799d6f5d3b8..b82a9a909e6d0 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 52304c72a2f8d..15691804a94b2 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 b34d3dd904400..50a614a1b0279 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 e893a2c781346..ff4208def319d 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,14 @@ 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::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::new_unchecked(addr.get() << T::BITS) })
     }
 
     /// This provides a reference to the `P` pointer itself, rather than the
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index e174cba7813f5..a1abe8fd4f306 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -376,7 +376,7 @@ impl From<Cow<'static, str>> for DiagnosticMessage {
     }
 }
 
-/// A workaround for good_path_delayed_bug ICEs when formatting types in disabled lints.
+/// A workaround for must_produce_diag ICEs when formatting types in disabled lints.
 ///
 /// Delays formatting until `.into(): DiagnosticMessage` is used.
 pub struct DelayDm<F>(pub F);
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 37f568f12a797..1a34a83c1a44a 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -85,11 +85,7 @@ fn source_string(file: Lrc<SourceFile>, line: &Line) -> String {
 /// Maps `Diagnostic::Level` to `snippet::AnnotationType`
 fn annotation_type_for_level(level: Level) -> AnnotationType {
     match level {
-        Level::Bug
-        | Level::Fatal
-        | Level::Error
-        | Level::DelayedBug
-        | Level::GoodPathDelayedBug => AnnotationType::Error,
+        Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => AnnotationType::Error,
         Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning,
         Level::Note | Level::OnceNote => AnnotationType::Note,
         Level::Help | Level::OnceHelp => AnnotationType::Help,
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 2deb18484ec2e..b14a12175c79b 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -237,8 +237,7 @@ impl Diagnostic {
         match self.level {
             Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true,
 
-            Level::GoodPathDelayedBug
-            | Level::ForceWarning(_)
+            Level::ForceWarning(_)
             | Level::Warning
             | Level::Note
             | Level::OnceNote
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index e936ebc7185fa..eaf75539f59b9 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 da9ef6627beae..38bc5916276ec 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::panic;
 use std::path::{Path, PathBuf};
 
@@ -435,7 +436,6 @@ struct DiagCtxtInner {
     lint_err_guars: Vec<ErrorGuaranteed>,
     /// The delayed bugs and their error guarantees.
     delayed_bugs: Vec<(DelayedDiagnostic, ErrorGuaranteed)>,
-    good_path_delayed_bugs: Vec<DelayedDiagnostic>,
 
     /// The number of stashed errors. Unlike the other counts, this can go up
     /// and down, so it doesn't guarantee anything.
@@ -446,13 +446,18 @@ struct DiagCtxtInner {
     /// The warning count shown to the user at the end.
     deduplicated_warn_count: usize,
 
+    emitter: Box<DynEmitter>,
+
+    /// Must we produce a diagnostic to justify the use of the expensive
+    /// `trimmed_def_paths` function?
+    must_produce_diag: bool,
+
     /// Has this diagnostic context printed any diagnostics? (I.e. has
     /// `self.emitter.emit_diagnostic()` been called?
     has_printed: bool,
 
-    emitter: Box<DynEmitter>,
     /// This flag indicates that an expected diagnostic was emitted and suppressed.
-    /// This is used for the `good_path_delayed_bugs` check.
+    /// This is used for the `must_produce_diag` check.
     suppressed_expected_diag: bool,
 
     /// This set contains the code of all emitted diagnostics to avoid
@@ -533,11 +538,6 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
 pub static TRACK_DIAGNOSTIC: AtomicRef<fn(Diagnostic, &mut dyn FnMut(Diagnostic))> =
     AtomicRef::new(&(default_track_diagnostic as _));
 
-enum DelayedBugKind {
-    Normal,
-    GoodPath,
-}
-
 #[derive(Copy, Clone, Default)]
 pub struct DiagCtxtFlags {
     /// If false, warning-level lints are suppressed.
@@ -545,7 +545,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,
@@ -563,11 +563,16 @@ impl Drop for DiagCtxtInner {
         self.emit_stashed_diagnostics();
 
         if self.err_guars.is_empty() {
-            self.flush_delayed(DelayedBugKind::Normal)
+            self.flush_delayed()
         }
 
         if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
-            self.flush_delayed(DelayedBugKind::GoodPath);
+            if self.must_produce_diag {
+                panic!(
+                    "must_produce_diag: trimmed_def_paths called but no diagnostics emitted; \
+                       use `DelayDm` for lints or `with_no_trimmed_paths` for debugging"
+                );
+            }
         }
 
         if self.check_unstable_expect_diagnostics {
@@ -609,12 +614,12 @@ impl DiagCtxt {
                 err_guars: Vec::new(),
                 lint_err_guars: Vec::new(),
                 delayed_bugs: Vec::new(),
-                good_path_delayed_bugs: Vec::new(),
                 stashed_err_count: 0,
                 deduplicated_err_count: 0,
                 deduplicated_warn_count: 0,
-                has_printed: false,
                 emitter,
+                must_produce_diag: false,
+                has_printed: false,
                 suppressed_expected_diag: false,
                 taught_diagnostics: Default::default(),
                 emitted_diagnostic_codes: Default::default(),
@@ -666,13 +671,14 @@ impl DiagCtxt {
         inner.stashed_err_count = 0;
         inner.deduplicated_err_count = 0;
         inner.deduplicated_warn_count = 0;
+        inner.must_produce_diag = false;
         inner.has_printed = false;
+        inner.suppressed_expected_diag = false;
 
         // actually free the underlying memory (which `clear` would not do)
         inner.err_guars = Default::default();
         inner.lint_err_guars = Default::default();
         inner.delayed_bugs = Default::default();
-        inner.good_path_delayed_bugs = Default::default();
         inner.taught_diagnostics = Default::default();
         inner.emitted_diagnostic_codes = Default::default();
         inner.emitted_diagnostics = Default::default();
@@ -934,7 +940,13 @@ impl DiagCtxt {
     }
 
     pub fn flush_delayed(&self) {
-        self.inner.borrow_mut().flush_delayed(DelayedBugKind::Normal);
+        self.inner.borrow_mut().flush_delayed();
+    }
+
+    /// Used when trimmed_def_paths is called and we must produce a diagnostic
+    /// to justify its cost.
+    pub fn set_must_produce_diag(&self) {
+        self.inner.borrow_mut().must_produce_diag = true;
     }
 }
 
@@ -1108,13 +1120,6 @@ impl DiagCtxt {
         DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit()
     }
 
-    /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`.
-    // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
-    #[track_caller]
-    pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
-        DiagnosticBuilder::<()>::new(self, GoodPathDelayedBug, msg).emit()
-    }
-
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
@@ -1266,19 +1271,17 @@ impl DiagCtxtInner {
         if diagnostic.has_future_breakage() {
             // Future breakages aren't emitted if they're Level::Allow,
             // but they still need to be constructed and stashed below,
-            // so they'll trigger the good-path bug check.
+            // so they'll trigger the must_produce_diag check.
             self.suppressed_expected_diag = true;
             self.future_breakage_diagnostics.push(diagnostic.clone());
         }
 
-        if matches!(diagnostic.level, DelayedBug | GoodPathDelayedBug)
-            && self.flags.eagerly_emit_delayed_bugs
-        {
+        if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
             diagnostic.level = Error;
         }
 
         match diagnostic.level {
-            // This must come after the possible promotion of `DelayedBug`/`GoodPathDelayedBug` to
+            // This must come after the possible promotion of `DelayedBug` to
             // `Error` above.
             Fatal | Error if self.treat_next_err_as_bug() => {
                 diagnostic.level = Bug;
@@ -1297,12 +1300,6 @@ impl DiagCtxtInner {
                     .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
                 return Some(guar);
             }
-            GoodPathDelayedBug => {
-                let backtrace = std::backtrace::Backtrace::capture();
-                self.good_path_delayed_bugs
-                    .push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
-                return None;
-            }
             Warning if !self.flags.can_emit_warnings => {
                 if diagnostic.has_future_breakage() {
                     (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {});
@@ -1414,23 +1411,14 @@ impl DiagCtxtInner {
         self.emit_diagnostic(Diagnostic::new(FailureNote, msg));
     }
 
-    fn flush_delayed(&mut self, kind: DelayedBugKind) {
-        let (bugs, note1) = match kind {
-            DelayedBugKind::Normal => (
-                std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(),
-                "no errors encountered even though delayed bugs were created",
-            ),
-            DelayedBugKind::GoodPath => (
-                std::mem::take(&mut self.good_path_delayed_bugs),
-                "no warnings or errors encountered even though good path delayed bugs were created",
-            ),
-        };
-        let note2 = "those delayed bugs will now be shown as internal compiler errors";
-
-        if bugs.is_empty() {
+    fn flush_delayed(&mut self) {
+        if self.delayed_bugs.is_empty() {
             return;
         }
 
+        let bugs: Vec<_> =
+            std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
+
         // If backtraces are enabled, also print the query stack
         let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0");
         for (i, bug) in bugs.into_iter().enumerate() {
@@ -1454,6 +1442,8 @@ impl DiagCtxtInner {
                 // frame them better (e.g. separate warnings from them). Also,
                 // make it a note so it doesn't count as an error, because that
                 // could trigger `-Ztreat-err-as-bug`, which we don't want.
+                let note1 = "no errors encountered even though delayed bugs were created";
+                let note2 = "those delayed bugs will now be shown as internal compiler errors";
                 self.emit_diagnostic(Diagnostic::new(Note, note1));
                 self.emit_diagnostic(Diagnostic::new(Note, note2));
             }
@@ -1462,7 +1452,7 @@ impl DiagCtxtInner {
                 if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
 
             // "Undelay" the delayed bugs (into plain `Bug`s).
-            if !matches!(bug.level, DelayedBug | GoodPathDelayedBug) {
+            if bug.level != DelayedBug {
                 // NOTE(eddyb) not panicking here because we're already producing
                 // an ICE, and the more information the merrier.
                 bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
@@ -1534,7 +1524,6 @@ impl DelayedDiagnostic {
 /// Fatal              yes       FatalAbort/FatalError(*)  yes        -     -
 /// Error              yes       ErrorGuaranteed           yes        -     yes
 /// DelayedBug         yes       ErrorGuaranteed           yes        -     -
-/// GoodPathDelayedBug -         ()                        yes        -     -
 /// ForceWarning       -         ()                        yes        -     lint-only
 /// Warning            -         ()                        yes        yes   yes
 /// Note               -         ()                        rare       yes   -
@@ -1567,20 +1556,6 @@ pub enum Level {
     /// that should only be reached when compiling erroneous code.
     DelayedBug,
 
-    /// Like `DelayedBug`, but weaker: lets you register an error without emitting it. If
-    /// compilation ends without any other diagnostics being emitted (and without an expected lint
-    /// being suppressed), this will be emitted as a bug. Otherwise, it will be silently dropped.
-    /// I.e. "expect other diagnostics are emitted (or suppressed)" semantics. Useful on code paths
-    /// that should only be reached when emitting diagnostics, e.g. for expensive one-time
-    /// diagnostic formatting operations.
-    ///
-    /// FIXME(nnethercote) good path delayed bugs are semantically strange: if printed they produce
-    /// an ICE, but they don't satisfy `is_error` and they don't guarantee an error is emitted.
-    /// Plus there's the extra complication with expected (suppressed) lints. They have limited
-    /// use, and are used in very few places, and "good path" isn't a good name. It would be good
-    /// to remove them.
-    GoodPathDelayedBug,
-
     /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
     /// from finishing.
     ///
@@ -1625,7 +1600,7 @@ impl Level {
     fn color(self) -> ColorSpec {
         let mut spec = ColorSpec::new();
         match self {
-            Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
+            Bug | Fatal | Error | DelayedBug => {
                 spec.set_fg(Some(Color::Red)).set_intense(true);
             }
             ForceWarning(_) | Warning => {
@@ -1645,7 +1620,7 @@ impl Level {
 
     pub fn to_str(self) -> &'static str {
         match self {
-            Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error",
+            Bug | DelayedBug => "error: internal compiler error",
             Fatal | Error => "error",
             ForceWarning(_) | Warning => "warning",
             Note | OnceNote => "note",
@@ -1670,8 +1645,8 @@ impl Level {
     // subdiagnostic message?
     fn can_be_top_or_sub(&self) -> (bool, bool) {
         match self {
-            Bug | DelayedBug | Fatal | Error | GoodPathDelayedBug | ForceWarning(_)
-            | FailureNote | Allow | Expect(_) => (true, false),
+            Bug | DelayedBug | Fatal | Error | ForceWarning(_) | FailureNote | Allow
+            | Expect(_) => (true, false),
 
             Warning | Note | Help => (true, true),
 
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 6aedd2a5e3341..99875ec540545 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -788,6 +788,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
         "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
     ),
+    rustc_attr!(
+        rustc_intrinsic, Normal, template!(Word), ErrorFollowing,
+        "the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
+    ),
 
     // ==========================================================================
     // Internal attributes, Testing:
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index f1c8f2e2dde5c..cbc0ce8c97468 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::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/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index a6ac8ecd950ea..cee7c84adb2e9 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
                     if self_ty.span.can_be_used_for_suggestions() {
                         lint.multipart_suggestion_verbose(
-                            "use `dyn`",
+                            "if this is an object-safe trait, use `dyn`",
                             sugg,
                             Applicability::MachineApplicable,
                         );
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index b693d7201c15e..d9d5e371bb1b5 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -525,7 +525,18 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         DefKind::Enum => {
             check_enum(tcx, def_id);
         }
-        DefKind::Fn => {} // entirely within check_item_body
+        DefKind::Fn => {
+            if let Some(name) = tcx.intrinsic(def_id) {
+                intrinsic::check_intrinsic_type(
+                    tcx,
+                    def_id,
+                    tcx.def_ident_span(def_id).unwrap(),
+                    name,
+                    Abi::Rust,
+                )
+            }
+            // Everything else is checked entirely within check_item_body
+        }
         DefKind::Impl { of_trait } => {
             if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
                 check_impl_items_against_trait(
@@ -590,15 +601,24 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             match abi {
                 Abi::RustIntrinsic => {
                     for item in items {
-                        let item = tcx.hir().foreign_item(item.id);
-                        intrinsic::check_intrinsic_type(tcx, item);
+                        intrinsic::check_intrinsic_type(
+                            tcx,
+                            item.id.owner_id.def_id,
+                            item.span,
+                            item.ident.name,
+                            abi,
+                        );
                     }
                 }
 
                 Abi::PlatformIntrinsic => {
                     for item in items {
-                        let item = tcx.hir().foreign_item(item.id);
-                        intrinsic::check_platform_intrinsic_type(tcx, item);
+                        intrinsic::check_platform_intrinsic_type(
+                            tcx,
+                            item.id.owner_id.def_id,
+                            item.span,
+                            item.ident.name,
+                        );
                     }
                 }
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index dc391ab5648c6..f0f6bfff64aaa 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -7,30 +7,36 @@ use crate::errors::{
     WrongNumberOfGenericArgumentsToIntrinsic,
 };
 
-use hir::def_id::DefId;
 use rustc_errors::{codes::*, struct_span_code_err, DiagnosticMessage};
 use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{kw, sym};
+use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi::Abi;
 
 fn equate_intrinsic_type<'tcx>(
     tcx: TyCtxt<'tcx>,
-    it: &hir::ForeignItem<'_>,
+    span: Span,
+    def_id: LocalDefId,
     n_tps: usize,
     n_lts: usize,
     n_cts: usize,
     sig: ty::PolyFnSig<'tcx>,
 ) {
-    let (own_counts, span) = match &it.kind {
-        hir::ForeignItemKind::Fn(.., generics) => {
-            let own_counts = tcx.generics_of(it.owner_id.to_def_id()).own_counts();
+    let (own_counts, span) = match tcx.hir_node_by_def_id(def_id) {
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })
+        | hir::Node::ForeignItem(hir::ForeignItem {
+            kind: hir::ForeignItemKind::Fn(.., generics),
+            ..
+        }) => {
+            let own_counts = tcx.generics_of(def_id).own_counts();
             (own_counts, generics.span)
         }
         _ => {
-            struct_span_code_err!(tcx.dcx(), it.span, E0622, "intrinsic must be a function")
-                .with_span_label(it.span, "expected a function")
+            struct_span_code_err!(tcx.dcx(), span, E0622, "intrinsic must be a function")
+                .with_span_label(span, "expected a function")
                 .emit();
             return;
         }
@@ -54,23 +60,26 @@ fn equate_intrinsic_type<'tcx>(
         && gen_count_ok(own_counts.types, n_tps, "type")
         && gen_count_ok(own_counts.consts, n_cts, "const")
     {
-        let it_def_id = it.owner_id.def_id;
         let _ = check_function_signature(
             tcx,
-            ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType),
-            it_def_id.into(),
+            ObligationCause::new(span, def_id, ObligationCauseCode::IntrinsicType),
+            def_id.into(),
             sig,
         );
     }
 }
 
 /// Returns the unsafety of the given intrinsic.
-pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety {
-    let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
-        true => hir::Unsafety::Normal,
-        false => hir::Unsafety::Unsafe,
+pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Unsafety {
+    let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
+        tcx.fn_sig(intrinsic_id).skip_binder().unsafety()
+    } else {
+        match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
+            true => hir::Unsafety::Normal,
+            false => hir::Unsafety::Unsafe,
+        }
     };
-    let is_in_list = match tcx.item_name(intrinsic_id) {
+    let is_in_list = match tcx.item_name(intrinsic_id.into()) {
         // When adding a new intrinsic to this list,
         // it's usually worth updating that intrinsic's documentation
         // to note that it's safe to call, since
@@ -112,6 +121,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
         | sym::forget
         | sym::black_box
         | sym::variant_count
+        | sym::is_val_statically_known
         | sym::ptr_mask
         | sym::debug_assertions => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
@@ -122,7 +132,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
             tcx.def_span(intrinsic_id),
             DiagnosticMessage::from(format!(
                 "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`",
-                tcx.item_name(intrinsic_id)
+                tcx.item_name(intrinsic_id.into())
             )
         )).emit();
     }
@@ -132,8 +142,14 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
 
 /// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
 /// and in `library/core/src/intrinsics.rs`.
-pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
-    let generics = tcx.generics_of(it.owner_id);
+pub fn check_intrinsic_type(
+    tcx: TyCtxt<'_>,
+    intrinsic_id: LocalDefId,
+    span: Span,
+    intrinsic_name: Symbol,
+    abi: Abi,
+) {
+    let generics = tcx.generics_of(intrinsic_id);
     let param = |n| {
         if let Some(&ty::GenericParamDef {
             name, kind: ty::GenericParamDefKind::Type { .. }, ..
@@ -141,11 +157,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         {
             Ty::new_param(tcx, n, name)
         } else {
-            Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
+            Ty::new_error_with_message(tcx, span, "expected param")
         }
     };
-    let intrinsic_id = it.owner_id.to_def_id();
-    let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
     let bound_vars = tcx.mk_bound_variable_kinds(&[
@@ -169,7 +183,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         })
     };
 
-    let (n_tps, n_lts, inputs, output, unsafety) = if name_str.starts_with("atomic_") {
+    let (n_tps, n_lts, n_cts, inputs, output, unsafety) = if name_str.starts_with("atomic_") {
         let split: Vec<&str> = name_str.split('_').collect();
         assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
 
@@ -187,49 +201,51 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             | "umin" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)),
             "fence" | "singlethreadfence" => (0, Vec::new(), Ty::new_unit(tcx)),
             op => {
-                tcx.dcx().emit_err(UnrecognizedAtomicOperation { span: it.span, op });
+                tcx.dcx().emit_err(UnrecognizedAtomicOperation { span, op });
                 return;
             }
         };
-        (n_tps, 0, inputs, output, hir::Unsafety::Unsafe)
+        (n_tps, 0, 0, inputs, output, hir::Unsafety::Unsafe)
     } else {
         let unsafety = intrinsic_operation_unsafety(tcx, intrinsic_id);
-        let (n_tps, inputs, output) = match intrinsic_name {
-            sym::abort => (0, Vec::new(), tcx.types.never),
-            sym::unreachable => (0, Vec::new(), tcx.types.never),
-            sym::breakpoint => (0, Vec::new(), Ty::new_unit(tcx)),
+        let (n_tps, n_cts, inputs, output) = match intrinsic_name {
+            sym::abort => (0, 0, vec![], tcx.types.never),
+            sym::unreachable => (0, 0, vec![], tcx.types.never),
+            sym::breakpoint => (0, 0, vec![], Ty::new_unit(tcx)),
             sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
-                (1, Vec::new(), tcx.types.usize)
+                (1, 0, vec![], tcx.types.usize)
             }
             sym::size_of_val | sym::min_align_of_val => {
-                (1, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
+                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
             }
-            sym::rustc_peek => (1, vec![param(0)], param(0)),
-            sym::caller_location => (0, vec![], tcx.caller_location_ty()),
+            sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
+            sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
             sym::assert_inhabited
             | sym::assert_zero_valid
-            | sym::assert_mem_uninitialized_valid => (1, Vec::new(), Ty::new_unit(tcx)),
-            sym::forget => (1, vec![param(0)], Ty::new_unit(tcx)),
-            sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)),
+            | sym::assert_mem_uninitialized_valid => (1, 0, vec![], Ty::new_unit(tcx)),
+            sym::forget => (1, 0, vec![param(0)], Ty::new_unit(tcx)),
+            sym::transmute | sym::transmute_unchecked => (2, 0, vec![param(0)], param(1)),
             sym::prefetch_read_data
             | sym::prefetch_write_data
             | sym::prefetch_read_instruction
             | sym::prefetch_write_instruction => (
                 1,
+                0,
                 vec![
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
                     tcx.types.i32,
                 ],
                 Ty::new_unit(tcx),
             ),
-            sym::drop_in_place => (1, vec![Ty::new_mut_ptr(tcx, param(0))], Ty::new_unit(tcx)),
-            sym::needs_drop => (1, Vec::new(), tcx.types.bool),
+            sym::drop_in_place => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0))], Ty::new_unit(tcx)),
+            sym::needs_drop => (1, 0, vec![], tcx.types.bool),
 
-            sym::type_name => (1, Vec::new(), Ty::new_static_str(tcx)),
-            sym::type_id => (1, Vec::new(), tcx.types.u128),
-            sym::offset => (2, vec![param(0), param(1)], param(0)),
+            sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)),
+            sym::type_id => (1, 0, vec![], tcx.types.u128),
+            sym::offset => (2, 0, vec![param(0), param(1)], param(0)),
             sym::arith_offset => (
                 1,
+                0,
                 vec![
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
                     tcx.types.isize,
@@ -238,6 +254,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             ),
             sym::ptr_mask => (
                 1,
+                0,
                 vec![
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
                     tcx.types.usize,
@@ -247,6 +264,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
 
             sym::copy | sym::copy_nonoverlapping => (
                 1,
+                0,
                 vec![
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
@@ -256,6 +274,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             ),
             sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
                 1,
+                0,
                 vec![
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -265,10 +284,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             ),
             sym::compare_bytes => {
                 let byte_ptr = Ty::new_imm_ptr(tcx, tcx.types.u8);
-                (0, vec![byte_ptr, byte_ptr, tcx.types.usize], tcx.types.i32)
+                (0, 0, vec![byte_ptr, byte_ptr, tcx.types.usize], tcx.types.i32)
             }
             sym::write_bytes | sym::volatile_set_memory => (
                 1,
+                0,
                 vec![
                     Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
                     tcx.types.u8,
@@ -276,56 +296,56 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 ],
                 Ty::new_unit(tcx),
             ),
-            sym::sqrtf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::sqrtf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::powif32 => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
-            sym::powif64 => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
-            sym::sinf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::sinf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::cosf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::cosf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::powf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::powf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::expf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::expf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::exp2f32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::exp2f64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::logf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::logf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::log10f32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::log10f64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::log2f32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::log2f64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::fmaf32 => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::fmaf64 => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::fabsf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::fabsf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::minnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::minnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::maxnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::maxnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::copysignf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::copysignf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::floorf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::floorf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::ceilf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::ceilf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::truncf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::truncf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::rintf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::rintf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::nearbyintf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::nearbyintf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::roundf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::roundf64 => (0, vec![tcx.types.f64], tcx.types.f64),
-            sym::roundevenf32 => (0, vec![tcx.types.f32], tcx.types.f32),
-            sym::roundevenf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::sqrtf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::sqrtf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::powif32 => (0, 0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
+            sym::powif64 => (0, 0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
+            sym::sinf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::sinf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::cosf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::cosf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::powf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::powf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::expf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::expf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::exp2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::exp2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::logf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::logf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::log10f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::log10f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::log2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::log2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::fmaf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::fmaf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::fabsf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::minnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::copysignf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::floorf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::floorf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::ceilf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::ceilf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::truncf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+            sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+            sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
 
             sym::volatile_load | sym::unaligned_volatile_load => {
-                (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
+                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
             }
             sym::volatile_store | sym::unaligned_volatile_store => {
-                (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
             }
 
             sym::ctpop
@@ -334,62 +354,66 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             | sym::cttz
             | sym::cttz_nonzero
             | sym::bswap
-            | sym::bitreverse => (1, vec![param(0)], param(0)),
+            | sym::bitreverse => (1, 0, vec![param(0)], param(0)),
 
             sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
-                (1, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]))
+                (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]))
             }
 
             sym::ptr_guaranteed_cmp => (
                 1,
+                0,
                 vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
                 tcx.types.u8,
             ),
 
             sym::const_allocate => {
-                (0, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
+                (0, 1, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
             }
             sym::const_deallocate => (
                 0,
+                1,
                 vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize],
                 Ty::new_unit(tcx),
             ),
 
             sym::ptr_offset_from => (
                 1,
+                0,
                 vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
                 tcx.types.isize,
             ),
             sym::ptr_offset_from_unsigned => (
                 1,
+                0,
                 vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
                 tcx.types.usize,
             ),
             sym::unchecked_div | sym::unchecked_rem | sym::exact_div => {
-                (1, vec![param(0), param(0)], param(0))
+                (1, 0, vec![param(0), param(0)], param(0))
             }
             sym::unchecked_shl | sym::unchecked_shr | sym::rotate_left | sym::rotate_right => {
-                (1, vec![param(0), param(0)], param(0))
+                (1, 0, vec![param(0), param(0)], param(0))
             }
             sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
-                (1, vec![param(0), param(0)], param(0))
+                (1, 0, vec![param(0), param(0)], param(0))
             }
             sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
-                (1, vec![param(0), param(0)], param(0))
+                (1, 0, vec![param(0), param(0)], param(0))
             }
-            sym::saturating_add | sym::saturating_sub => (1, vec![param(0), param(0)], param(0)),
+            sym::saturating_add | sym::saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
             sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
-                (1, vec![param(0), param(0)], param(0))
+                (1, 0, vec![param(0), param(0)], param(0))
             }
-            sym::float_to_int_unchecked => (2, vec![param(0)], param(1)),
+            sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
 
-            sym::assume => (0, vec![tcx.types.bool], Ty::new_unit(tcx)),
-            sym::likely => (0, vec![tcx.types.bool], tcx.types.bool),
-            sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool),
+            sym::assume => (0, 0, vec![tcx.types.bool], Ty::new_unit(tcx)),
+            sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
+            sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
 
-            sym::read_via_copy => (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
+            sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
             sym::write_via_move => {
-                (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
             }
 
             sym::discriminant_value => {
@@ -401,6 +425,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
                 (
                     1,
+                    0,
                     vec![Ty::new_imm_ref(
                         tcx,
                         ty::Region::new_bound(tcx, ty::INNERMOST, br),
@@ -427,6 +452,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                     Abi::Rust,
                 ));
                 (
+                    0,
                     0,
                     vec![Ty::new_fn_ptr(tcx, try_fn_ty), mut_u8, Ty::new_fn_ptr(tcx, catch_fn_ty)],
                     tcx.types.i32,
@@ -434,61 +460,66 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             }
 
             sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
-                Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], Ty::new_unit(tcx)),
+                Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], Ty::new_unit(tcx)),
                 None => bug!("`va_list` language item needed for C-variadic intrinsics"),
             },
 
             sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
                 Some((va_list_ref_ty, va_list_ty)) => {
                     let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
-                    (0, vec![va_list_ptr_ty, va_list_ref_ty], Ty::new_unit(tcx))
+                    (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], Ty::new_unit(tcx))
                 }
                 None => bug!("`va_list` language item needed for C-variadic intrinsics"),
             },
 
             sym::va_arg => match mk_va_list_ty(hir::Mutability::Mut) {
-                Some((va_list_ref_ty, _)) => (1, vec![va_list_ref_ty], param(0)),
+                Some((va_list_ref_ty, _)) => (1, 0, vec![va_list_ref_ty], param(0)),
                 None => bug!("`va_list` language item needed for C-variadic intrinsics"),
             },
 
             sym::nontemporal_store => {
-                (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
             }
 
             sym::raw_eq => {
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
                 let param_ty =
                     Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
-                (1, vec![param_ty; 2], tcx.types.bool)
+                (1, 0, vec![param_ty; 2], tcx.types.bool)
             }
 
-            sym::black_box => (1, vec![param(0)], param(0)),
+            sym::black_box => (1, 0, vec![param(0)], param(0)),
 
-            sym::is_val_statically_known => (1, vec![param(0)], tcx.types.bool),
+            sym::is_val_statically_known => (1, 1, vec![param(0)], tcx.types.bool),
 
-            sym::const_eval_select => (4, vec![param(0), param(1), param(2)], param(3)),
+            sym::const_eval_select => (4, 0, vec![param(0), param(1), param(2)], param(3)),
 
             sym::vtable_size | sym::vtable_align => {
-                (0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
+                (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
             }
 
-            sym::debug_assertions => (0, Vec::new(), tcx.types.bool),
+            sym::debug_assertions => (0, 1, Vec::new(), tcx.types.bool),
 
             other => {
-                tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span: it.span, name: other });
+                tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
                 return;
             }
         };
-        (n_tps, 0, inputs, output, unsafety)
+        (n_tps, 0, n_cts, inputs, output, unsafety)
     };
-    let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic);
+    let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, abi);
     let sig = ty::Binder::bind_with_vars(sig, bound_vars);
-    equate_intrinsic_type(tcx, it, n_tps, n_lts, 0, sig)
+    equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, n_lts, n_cts, sig)
 }
 
 /// Type-check `extern "platform-intrinsic" { ... }` functions.
-pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
-    let generics = tcx.generics_of(it.owner_id);
+pub fn check_platform_intrinsic_type(
+    tcx: TyCtxt<'_>,
+    intrinsic_id: LocalDefId,
+    span: Span,
+    name: Symbol,
+) {
+    let generics = tcx.generics_of(intrinsic_id);
     let param = |n| {
         if let Some(&ty::GenericParamDef {
             name, kind: ty::GenericParamDefKind::Type { .. }, ..
@@ -496,12 +527,10 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         {
             Ty::new_param(tcx, n, name)
         } else {
-            Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
+            Ty::new_error_with_message(tcx, span, "expected param")
         }
     };
 
-    let name = it.ident.name;
-
     let (n_tps, n_cts, inputs, output) = match name {
         sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => {
             (2, 0, vec![param(0), param(0)], param(1))
@@ -574,12 +603,12 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)),
         _ => {
             let msg = format!("unrecognized platform-specific intrinsic function: `{name}`");
-            tcx.dcx().span_err(it.span, msg);
+            tcx.dcx().span_err(span, msg);
             return;
         }
     };
 
     let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic);
     let sig = ty::Binder::dummy(sig);
-    equate_intrinsic_type(tcx, it, n_tps, 0, n_cts, sig)
+    equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, 0, n_cts, sig)
 }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 2f8e065df3303..6b064b36cf19b 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/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e8787d159ae12..2420b742ea699 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1650,7 +1650,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        intrinsic_operation_unsafety(tcx, def_id.to_def_id())
+        intrinsic_operation_unsafety(tcx, def_id)
     } else {
         hir::Unsafety::Unsafe
     };
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 1aaefc5b52087..d507fb39e192b 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)]
@@ -187,8 +188,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
     }
 
     tcx.sess.time("wf_checking", || {
-        tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
-    })?;
+        tcx.hir().par_for_each_module(|module| {
+            let _ = tcx.ensure().check_mod_type_wf(module);
+        })
+    });
 
     if tcx.features().rustc_attrs {
         collect::test_opaque_hidden_types(tcx)?;
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index c4271c66e1c9d..27614634c6b3e 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -540,8 +540,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(def_id) = def_id
             && self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
-            && self.tcx.is_intrinsic(def_id)
-            && self.tcx.item_name(def_id) == sym::const_eval_select
+            && matches!(self.tcx.intrinsic(def_id), Some(sym::const_eval_select))
         {
             let fn_sig = self.resolve_vars_if_possible(fn_sig);
             for idx in 0..=1 {
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index e6319747e782e..6bab8f75d248c 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -867,7 +867,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 let a_sig = a.fn_sig(self.tcx);
                 if let ty::FnDef(def_id, _) = *a.kind() {
                     // Intrinsics are not coercible to function pointers
-                    if self.tcx.is_intrinsic(def_id) {
+                    if self.tcx.intrinsic(def_id).is_some() {
                         return Err(TypeError::IntrinsicCast);
                     }
 
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 4e9cb92919afb..a580c114f2614 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -518,12 +518,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                         .report_mismatched_types(&cause, method_self_ty, self_ty, terr)
                         .emit();
                 } else {
-                    span_bug!(
-                        self.span,
-                        "{} was a subtype of {} but now is not?",
-                        self_ty,
-                        method_self_ty
-                    );
+                    error!("{self_ty} was a subtype of {method_self_ty} but now is not?");
+                    // This must already have errored elsewhere.
+                    self.dcx().has_errors().unwrap();
                 }
             }
         }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 4d2d19b51e22c..b953b25d6c4cf 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -132,20 +132,6 @@ pub struct TypeErrCtxt<'a, 'tcx> {
         Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>,
 }
 
-impl Drop for TypeErrCtxt<'_, '_> {
-    fn drop(&mut self) {
-        if self.dcx().has_errors().is_some() {
-            // Ok, emitted an error.
-        } else {
-            // Didn't emit an error; maybe it was created but not yet emitted.
-            self.infcx
-                .tcx
-                .sess
-                .good_path_delayed_bug("used a `TypeErrCtxt` without raising an error or lint");
-        }
-    }
-}
-
 impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     pub fn dcx(&self) -> &'tcx DiagCtxt {
         self.infcx.tcx.dcx()
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 248e1c0fcc878..81c531fad5580 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -313,7 +313,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
                 if !self.same_type_modulo_infer(*found_sig, *expected_sig)
                     || !sig.is_suggestable(self.tcx, true)
-                    || self.tcx.is_intrinsic(*did)
+                    || self.tcx.intrinsic(*did).is_some()
                 {
                     return;
                 }
@@ -345,8 +345,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 if !self.same_type_modulo_infer(*found_sig, *expected_sig)
                     || !found_sig.is_suggestable(self.tcx, true)
                     || !expected_sig.is_suggestable(self.tcx, true)
-                    || self.tcx.is_intrinsic(*did1)
-                    || self.tcx.is_intrinsic(*did2)
+                    || self.tcx.intrinsic(*did1).is_some()
+                    || self.tcx.intrinsic(*did2).is_some()
                 {
                     return;
                 }
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 7d69e49b209f5..24c2e29053488 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 bfc4fc07d4cc7..112553b2f7031 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::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 76b9e8de75fb0..087c43075f175 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::new(threads).unwrap());
 
     if !sync::is_dyn_thread_safe() {
         return run_in_thread_with_globals(edition, || {
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 6ee1d1ca92472..faa35f51cd496 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1227,7 +1227,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
         }
 
         fn def_id_is_transmute(cx: &LateContext<'_>, def_id: DefId) -> bool {
-            cx.tcx.is_intrinsic(def_id) && cx.tcx.item_name(def_id) == sym::transmute
+            matches!(cx.tcx.intrinsic(def_id), Some(sym::transmute))
         }
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 5f769e9ad8a5b..85f9d3bd63ec7 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 7445e2e80b407..da59ffebdc5a9 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 2e7130f356579..70ad859895724 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 72e9744295bc9..2cfbaff35ef29 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::new(position).unwrap();
         self.lazy_state = LazyState::Previous(position);
         f(position)
     }
@@ -685,15 +685,15 @@ impl MetadataBlob {
     }
 
     pub(crate) fn get_rustc_version(&self) -> String {
-        LazyValue::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 8).unwrap())
+        LazyValue::<String>::from_position(NonZero::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::new(pos as usize).unwrap()
     }
 
     pub(crate) fn get_header(&self) -> CrateHeader {
@@ -1749,8 +1749,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         self.root.tables.attr_flags.get(self, index)
     }
 
-    fn get_is_intrinsic(self, index: DefIndex) -> bool {
-        self.root.tables.is_intrinsic.get(self, index)
+    fn get_intrinsic(self, index: DefIndex) -> Option<Symbol> {
+        self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self))
     }
 
     fn get_doc_link_resolutions(self, index: DefIndex) -> DocLinkResMap {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index d79d4b226a54f..b895745299415 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -347,7 +347,7 @@ provide! { tcx, def_id, other, cdata,
         cdata.get_stability_implications(tcx).iter().copied().collect()
     }
     stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) }
-    is_intrinsic => { cdata.get_is_intrinsic(def_id.index) }
+    intrinsic => { cdata.get_intrinsic(def_id.index) }
     defined_lang_items => { cdata.get_lang_items(tcx) }
     diagnostic_items => { cdata.get_diagnostic_items() }
     missing_lang_items => { cdata.get_missing_lang_items(tcx) }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 4a24c038f7ae0..5c37b1fbc8666 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::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::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::new(self.position()).unwrap();
 
         assert_eq!(self.lazy_state, LazyState::NoNode);
         self.lazy_state = LazyState::NodeStart(pos);
@@ -1411,7 +1411,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if let DefKind::Fn | DefKind::AssocFn = def_kind {
                 self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id));
                 record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id));
-                self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
+                if let Some(name) = tcx.intrinsic(def_id) {
+                    record!(self.tables.intrinsic[def_id] <- name);
+                }
             }
             if let DefKind::TyParam = def_kind {
                 let default = self.tcx.object_lifetime_default(def_id);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 4d0a6cb60ee76..2ab2ccb34011c 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::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>>>;
@@ -375,7 +375,7 @@ macro_rules! define_tables {
 
 define_tables! {
 - defaulted:
-    is_intrinsic: Table<DefIndex, bool>,
+    intrinsic: Table<DefIndex, Option<LazyValue<Symbol>>>,
     is_macro_rules: Table<DefIndex, bool>,
     is_type_alias_impl_trait: Table<DefIndex, bool>,
     type_alias_is_lazy: Table<DefIndex, bool>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 306bf07a97608..c5f281964df02 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::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::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::new(pos).unwrap(),
             width,
             self.blocks.len(),
         )
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 2aaece1060a1f..9c0846e9fb199 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 afb6937b43b94..2f624ab052710 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::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 0da3524e05564..903c83cc54e51 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::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 dabf6297aa9c8..e2767ee298958 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::new(self.0.get() & !IMMUTABLE_MASK).unwrap())
     }
 
     /// Returns whether this provenance is immutable.
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 5666a59e38e8a..f0b992cf8c48e 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -241,6 +241,7 @@ trivial! {
     Option<rustc_target::abi::FieldIdx>,
     Option<rustc_target::spec::PanicStrategy>,
     Option<usize>,
+    Option<rustc_span::Symbol>,
     Result<(), rustc_errors::ErrorGuaranteed>,
     Result<(), rustc_middle::traits::query::NoSolution>,
     Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 60d195e4d3ef9..a1580f1e2031b 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1749,8 +1749,8 @@ rustc_queries! {
         separate_provide_extern
     }
     /// Whether the function is an intrinsic
-    query is_intrinsic(def_id: DefId) -> bool {
-        desc { |tcx| "checking whether `{}` is an intrinsic", tcx.def_path_str(def_id) }
+    query intrinsic(def_id: DefId) -> Option<Symbol> {
+        desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) }
         separate_provide_extern
     }
     /// Returns the lang items defined in another crate by loading it from metadata.
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 515d564e81db7..5d50510338c61 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::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::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::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::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::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::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::new(std::mem::size_of::<$ty>() as u8).unwrap(),
                     }
                 }
             }
@@ -427,7 +427,7 @@ 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::new(std::mem::size_of::<char>() as u8).unwrap() }
     }
 }
 
@@ -454,7 +454,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::new((Single::BITS / 8) as u8).unwrap() }
     }
 }
 
@@ -470,7 +470,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::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 84de12b23a06e..813a7a64daf00 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;
 
@@ -143,9 +143,8 @@ impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
 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))
-        };
+        let ptr =
+            unsafe { self.ptr.map_addr(|addr| NonZero::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()`,
         // and this is just going in the other direction.
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 8d8d06b7c0b7f..2b34f5daaf63f 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::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 6ee74ef2fb648..a6509c3e5c38e 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};
@@ -606,9 +606,8 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
 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))
-        };
+        let ptr =
+            unsafe { self.ptr.map_addr(|addr| NonZero::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()`,
         // and this is just going in the other direction.
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5cf90e94907b0..92ec1a83beeb9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -3156,13 +3156,12 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
 // this is pub to be able to intra-doc-link it
 pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
     // Trimming paths is expensive and not optimized, since we expect it to only be used for error
-    // reporting.
+    // reporting. Record the fact that we did it, so we can abort if we later found it was
+    // unnecessary.
     //
-    // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths`
-    // wrapper can be used to suppress this query, in exchange for full paths being formatted.
-    tcx.sess.good_path_delayed_bug(
-        "trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging",
-    );
+    // The `rustc_middle::ty::print::with_no_trimmed_paths` wrapper can be used to suppress this
+    // checking, in exchange for full paths being formatted.
+    tcx.sess.record_trimmed_def_paths();
 
     // Once constructed, unique namespace+symbol pairs will have a `Some(_)` entry, while
     // non-unique pairs will have a `None` entry.
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index c674a868d9fa2..35b171a7fbfb2 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -18,7 +18,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_macros::HashStable;
 use rustc_session::Limit;
-use rustc_span::sym;
+use rustc_span::{sym, Symbol};
 use rustc_target::abi::{Integer, IntegerType, Primitive, Size};
 use rustc_target::spec::abi::Abi;
 use smallvec::SmallVec;
@@ -1551,9 +1551,15 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait)))
 }
 
-/// Determines whether an item is an intrinsic by Abi.
-pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
+/// Determines whether an item is an intrinsic by Abi. or by whether it has a `rustc_intrinsic` attribute
+pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Symbol> {
+    if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
+        || tcx.has_attr(def_id, sym::rustc_intrinsic)
+    {
+        Some(tcx.item_name(def_id.into()))
+    } else {
+        None
+    }
 }
 
 pub fn provide(providers: &mut Providers) {
@@ -1561,7 +1567,7 @@ pub fn provide(providers: &mut Providers) {
         reveal_opaque_types_in_bounds,
         is_doc_hidden,
         is_doc_notable_trait,
-        is_intrinsic,
+        intrinsic,
         ..*providers
     }
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index c24b24d6f01e8..99952e1c17878 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -3,6 +3,7 @@ use crate::thir::cx::region::Scope;
 use crate::thir::cx::Cx;
 use crate::thir::util::UserAnnotatedTyHelpers;
 use itertools::Itertools;
+use rustc_ast::LitKind;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -20,7 +21,8 @@ use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{
     self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType,
 };
-use rustc_span::{sym, Span};
+use rustc_span::source_map::Spanned;
+use rustc_span::{sym, Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
 
 impl<'tcx> Cx<'tcx> {
@@ -894,7 +896,14 @@ impl<'tcx> Cx<'tcx> {
             Res::Def(DefKind::ConstParam, def_id) => {
                 let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
                 let generics = self.tcx.generics_of(hir_id.owner);
-                let index = generics.param_def_id_to_index[&def_id];
+                let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
+                    self.tcx.dcx().has_errors().unwrap();
+                    // We already errored about a late bound const
+                    return ExprKind::Literal {
+                        lit: &Spanned { span: DUMMY_SP, node: LitKind::Err },
+                        neg: false,
+                    };
+                };
                 let name = self.tcx.hir().name(hir_id);
                 let param = ty::ParamConst::new(index, name);
 
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index cbbf3548c07ef..1575f31e75e0e 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -202,8 +202,7 @@ impl PeekCall {
             &terminator.kind
         {
             if let ty::FnDef(def_id, fn_args) = *func.const_.ty().kind() {
-                let name = tcx.item_name(def_id);
-                if !tcx.is_intrinsic(def_id) || name != sym::rustc_peek {
+                if tcx.intrinsic(def_id)? != sym::rustc_peek {
                     return None;
                 }
 
diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs
index 79bed960b950f..2c692c9500303 100644
--- a/compiler/rustc_mir_transform/src/cost_checker.rs
+++ b/compiler/rustc_mir_transform/src/cost_checker.rs
@@ -70,7 +70,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
             TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
                 let fn_ty = self.instantiate_ty(f.const_.ty());
                 self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind()
-                    && tcx.is_intrinsic(def_id)
+                    && tcx.intrinsic(def_id).is_some()
                 {
                     // Don't give intrinsics the extra penalty for calls
                     INSTR_COST
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index d936c64c55cb2..73102a5f026d9 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -289,9 +289,9 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         if args.is_empty() {
             return;
         }
-        let ty = args.type_at(0);
 
-        let known_is_valid = intrinsic_assert_panics(self.tcx, self.param_env, ty, intrinsic_name);
+        let known_is_valid =
+            intrinsic_assert_panics(self.tcx, self.param_env, args[0], intrinsic_name);
         match known_is_valid {
             // We don't know the layout or it's not validity assertion at all, don't touch it
             None => {}
@@ -310,10 +310,11 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
 fn intrinsic_assert_panics<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    ty: Ty<'tcx>,
+    arg: ty::GenericArg<'tcx>,
     intrinsic_name: Symbol,
 ) -> Option<bool> {
     let requirement = ValidityRequirement::from_intrinsic(intrinsic_name)?;
+    let ty = arg.expect_ty();
     Some(!tcx.check_validity_requirement((requirement, param_env.and(ty))).ok()?)
 }
 
@@ -322,9 +323,8 @@ fn resolve_rust_intrinsic<'tcx>(
     func_ty: Ty<'tcx>,
 ) -> Option<(Symbol, GenericArgsRef<'tcx>)> {
     if let ty::FnDef(def_id, args) = *func_ty.kind() {
-        if tcx.is_intrinsic(def_id) {
-            return Some((tcx.item_name(def_id), args));
-        }
+        let name = tcx.intrinsic(def_id)?;
+        return Some((name, args));
     }
     None
 }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 9f30f2836f195..7946f850b9ddc 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -161,8 +161,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
                 fn_span,
                 ..
             } if let ty::FnDef(def_id, _) = *const_.ty().kind()
-                && tcx.item_name(def_id) == sym::const_eval_select
-                && tcx.is_intrinsic(def_id) =>
+                && matches!(tcx.intrinsic(def_id), Some(sym::const_eval_select)) =>
             {
                 let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
                     std::mem::take(args).try_into().unwrap();
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index f43b85173d428..a0af902c4e109 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -14,9 +14,8 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
             if let TerminatorKind::Call { func, args, destination, target, .. } =
                 &mut terminator.kind
                 && let ty::FnDef(def_id, generic_args) = *func.ty(local_decls, tcx).kind()
-                && tcx.is_intrinsic(def_id)
+                && let Some(intrinsic_name) = tcx.intrinsic(def_id)
             {
-                let intrinsic_name = tcx.item_name(def_id);
                 match intrinsic_name {
                     sym::unreachable => {
                         terminator.kind = TerminatorKind::Unreachable;
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 1c9913fa20367..5593de607844d 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -956,19 +956,24 @@ fn visit_instance_use<'tcx>(
     if !should_codegen_locally(tcx, &instance) {
         return;
     }
-
-    // The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will
-    // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
-    // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
-    // codegen a call to that function without generating code for the function itself.
     if let ty::InstanceDef::Intrinsic(def_id) = instance.def {
         let name = tcx.item_name(def_id);
         if let Some(_requirement) = ValidityRequirement::from_intrinsic(name) {
+            // The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will
+            // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
+            // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
+            // codegen a call to that function without generating code for the function itself.
             let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap();
             let panic_instance = Instance::mono(tcx, def_id);
             if should_codegen_locally(tcx, &panic_instance) {
                 output.push(create_fn_mono_item(tcx, panic_instance, source));
             }
+        } else if tcx.has_attr(def_id, sym::rustc_intrinsic) {
+            // Codegen the fallback body of intrinsics with fallback bodies
+            let instance = ty::Instance::new(def_id, instance.args);
+            if should_codegen_locally(tcx, &instance) {
+                output.push(create_fn_mono_item(tcx, instance, source));
+            }
         }
     }
 
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index e795537e84ad7..7227b185f4d3b 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 c1fe8c2133b75..ba3ac34840615 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::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 0fe5b9c664a35..33116737a4203 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 a827717d9bbd1..5917d79983d02 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,10 +68,8 @@ impl QueryContext for QueryCtxt<'_> {
     #[inline]
     fn next_job_id(self) -> QueryJobId {
         QueryJobId(
-            NonZeroU64::new(
-                self.query_system.jobs.fetch_add(1, std::sync::atomic::Ordering::Relaxed),
-            )
-            .unwrap(),
+            NonZero::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 416f556f57d28..6a959a99e5d42 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 3ef9de7da74b2..a5acb1f91e180 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 95833f532f4d8..bb822c611a170 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 287e317b10f33..412f7eced433c 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::new(d.read_u32()).unwrap()
     }
 }
 
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d35f951e2aea3..b89dfab2ca97d 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 c36cec6f35327..192dbb05530f3 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 58e1394c09071..c63af90a7f312 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 ea93ac5841fe9..743f476033935 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::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/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 0c084660761d8..25c20be8e627b 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -322,10 +322,9 @@ impl Session {
         }
     }
 
-    /// Used for code paths of expensive computations that should only take place when
-    /// warnings or errors are emitted. If no messages are emitted ("good path"), then
-    /// it's likely a bug.
-    pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
+    /// Record the fact that we called `trimmed_def_paths`, and do some
+    /// checking about whether its cost was justified.
+    pub fn record_trimmed_def_paths(&self) {
         if self.opts.unstable_opts.print_type_sizes
             || self.opts.unstable_opts.query_dep_graph
             || self.opts.unstable_opts.dump_mir.is_some()
@@ -336,7 +335,7 @@ impl Session {
             return;
         }
 
-        self.dcx().good_path_delayed_bug(msg)
+        self.dcx().set_must_produce_diag()
     }
 
     #[inline]
@@ -546,8 +545,8 @@ impl Session {
                 if fuel.remaining == 0 && !fuel.out_of_fuel {
                     if self.dcx().can_emit_warnings() {
                         // We only call `msg` in case we can actually emit warnings.
-                        // Otherwise, this could cause a `good_path_delayed_bug` to
-                        // trigger (issue #79546).
+                        // Otherwise, this could cause a `must_produce_diag` ICE
+                        // (issue #79546).
                         self.dcx().emit_warn(errors::OptimisationFuelExhausted { msg: msg() });
                     }
                     fuel.out_of_fuel = true;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 134aa9efc01b6..29c88783357b7 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1422,6 +1422,7 @@ symbols! {
         rustc_if_this_changed,
         rustc_inherit_overflow_checks,
         rustc_insignificant_dtor,
+        rustc_intrinsic,
         rustc_layout,
         rustc_layout_scalar_valid_range_end,
         rustc_layout_scalar_valid_range_start,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index c5ee03916825c..bf4aba7df4cb5 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -3112,10 +3112,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             obligation.param_env,
             trait_ref.args.const_at(3),
         ) else {
-            span_bug!(
+            self.dcx().span_delayed_bug(
                 span,
-                "Unable to construct rustc_transmute::Assume where it was previously possible"
+                "Unable to construct rustc_transmute::Assume where it was previously possible",
             );
+            return GetSafeTransmuteErrorAndReason::Silent;
         };
 
         match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 7fa416197b35f..5fc93d666ab16 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -28,7 +28,8 @@ fn resolve_instance<'tcx>(
             tcx.normalize_erasing_regions(param_env, args),
         )
     } else {
-        let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) {
+        let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.intrinsic(def_id).is_some()
+        {
             debug!(" => intrinsic");
             ty::InstanceDef::Intrinsic(def_id)
         } else if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 00a101541c589..c89a380628020 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::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::new(1);
+    const MERGE_BY: Option<NonZero<usize>> = NonZero::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 d9e274df0f5f2..692af7c197a30 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::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::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 646a2a991e701..5a5e7f70854d8 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 7defbb1090ffd..5061931afb7b7 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 3341b564d1f65..b84273848ee95 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 5dc3c69e49320..07eb91c900597 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 7800560da94f9..63d8fe19ac35c 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::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::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::new(1);
+    const MERGE_BY: Option<NonZero<usize>> = NonZero::new(1);
 }
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index ca17dab55b027..c4e89a58a05ac 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 38a68df79cc73..04bb20e96b792 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::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::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::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 f6fb1f73e5cf9..eda2f8bb812b5 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::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::new(5).unwrap()));
     }
 }
 
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index 2b22488b8ffc5..e3d2cd2a31fbc 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::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::new(remaining).map_or(Ok(()), Err)
     }
 }
 
diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs
index 02867789b79dd..c29e5565d514a 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 5c42912874c66..12bca0b438cc3 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 2548d9e24c9db..b19eef8e25587 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 60b5df752ca85..143e277283e2c 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/intrinsics.rs b/library/core/src/intrinsics.rs
index c8259c0024c75..fc6c1eab803d7 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2368,32 +2368,6 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8;
 
-    /// Allocates a block of memory at compile time.
-    /// At runtime, just returns a null pointer.
-    ///
-    /// # Safety
-    ///
-    /// - The `align` argument must be a power of two.
-    ///    - At compile time, a compile error occurs if this constraint is violated.
-    ///    - At runtime, it is not checked.
-    #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
-    #[rustc_nounwind]
-    pub fn const_allocate(size: usize, align: usize) -> *mut u8;
-
-    /// Deallocates a memory which allocated by `intrinsics::const_allocate` at compile time.
-    /// At runtime, does nothing.
-    ///
-    /// # Safety
-    ///
-    /// - The `align` argument must be a power of two.
-    ///    - At compile time, a compile error occurs if this constraint is violated.
-    ///    - At runtime, it is not checked.
-    /// - If the `ptr` is created in an another const, this intrinsic doesn't deallocate it.
-    /// - If the `ptr` is pointing to a local variable, this intrinsic doesn't deallocate it.
-    #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
-    #[rustc_nounwind]
-    pub fn const_deallocate(ptr: *mut u8, size: usize, align: usize);
-
     /// Determines whether the raw bytes of the two values are equal.
     ///
     /// This is particularly handy for arrays, since it allows things like just
@@ -2517,83 +2491,112 @@ extern "rust-intrinsic" {
     where
         G: FnOnce<ARG, Output = RET>,
         F: FnOnce<ARG, Output = RET>;
+}
 
-    /// Returns whether the argument's value is statically known at
-    /// compile-time.
-    ///
-    /// This is useful when there is a way of writing the code that will
-    /// be *faster* when some variables have known values, but *slower*
-    /// in the general case: an `if is_val_statically_known(var)` can be used
-    /// to select between these two variants. The `if` will be optimized away
-    /// and only the desired branch remains.
-    ///
-    /// Formally speaking, this function non-deterministically returns `true`
-    /// or `false`, and the caller has to ensure sound behavior for both cases.
-    /// In other words, the following code has *Undefined Behavior*:
-    ///
-    /// ```no_run
-    /// #![feature(is_val_statically_known)]
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    /// use std::hint::unreachable_unchecked;
-    /// use std::intrinsics::is_val_statically_known;
-    ///
-    /// unsafe {
-    ///    if !is_val_statically_known(0) { unreachable_unchecked(); }
-    /// }
-    /// ```
-    ///
-    /// This also means that the following code's behavior is unspecified; it
-    /// may panic, or it may not:
-    ///
-    /// ```no_run
-    /// #![feature(is_val_statically_known)]
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    /// use std::intrinsics::is_val_statically_known;
-    ///
-    /// unsafe {
-    ///     assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
-    /// }
-    /// ```
-    ///
-    /// Unsafe code may not rely on `is_val_statically_known` returning any
-    /// particular value, ever. However, the compiler will generally make it
-    /// return `true` only if the value of the argument is actually known.
-    ///
-    /// When calling this in a `const fn`, both paths must be semantically
-    /// equivalent, that is, the result of the `true` branch and the `false`
-    /// branch must return the same value and have the same side-effects *no
-    /// matter what*.
-    #[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")]
-    #[rustc_nounwind]
-    pub fn is_val_statically_known<T: Copy>(arg: T) -> bool;
-
-    /// Returns the value of `cfg!(debug_assertions)`, but after monomorphization instead of in
-    /// macro expansion.
-    ///
-    /// This always returns `false` in const eval and Miri. The interpreter provides better
-    /// diagnostics than the checks that this is used to implement. However, this means
-    /// you should only be using this intrinsic to guard requirements that, if violated,
-    /// immediately lead to UB. Otherwise, const-eval and Miri will miss out on those
-    /// checks entirely.
-    ///
-    /// Since this is evaluated after monomorphization, branching on this value can be used to
-    /// implement debug assertions that are included in the precompiled standard library, but can
-    /// be optimized out by builds that monomorphize the standard library code with debug
-    /// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
-    #[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
-    #[rustc_safe_intrinsic]
-    #[cfg(not(bootstrap))]
-    pub(crate) fn debug_assertions() -> bool;
+/// Returns whether the argument's value is statically known at
+/// compile-time.
+///
+/// This is useful when there is a way of writing the code that will
+/// be *faster* when some variables have known values, but *slower*
+/// in the general case: an `if is_val_statically_known(var)` can be used
+/// to select between these two variants. The `if` will be optimized away
+/// and only the desired branch remains.
+///
+/// Formally speaking, this function non-deterministically returns `true`
+/// or `false`, and the caller has to ensure sound behavior for both cases.
+/// In other words, the following code has *Undefined Behavior*:
+///
+/// ```no_run
+/// #![feature(is_val_statically_known)]
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+/// use std::hint::unreachable_unchecked;
+/// use std::intrinsics::is_val_statically_known;
+///
+/// if !is_val_statically_known(0) { unsafe { unreachable_unchecked(); } }
+/// ```
+///
+/// This also means that the following code's behavior is unspecified; it
+/// may panic, or it may not:
+///
+/// ```no_run
+/// #![feature(is_val_statically_known)]
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+/// use std::intrinsics::is_val_statically_known;
+///
+/// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
+/// ```
+///
+/// Unsafe code may not rely on `is_val_statically_known` returning any
+/// particular value, ever. However, the compiler will generally make it
+/// return `true` only if the value of the argument is actually known.
+///
+/// When calling this in a `const fn`, both paths must be semantically
+/// equivalent, that is, the result of the `true` branch and the `false`
+/// branch must return the same value and have the same side-effects *no
+/// matter what*.
+#[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")]
+#[rustc_nounwind]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
+    false
 }
 
-#[cfg(bootstrap)]
+/// Returns the value of `cfg!(debug_assertions)`, but after monomorphization instead of in
+/// macro expansion.
+///
+/// This always returns `false` in const eval and Miri. The interpreter provides better
+/// diagnostics than the checks that this is used to implement. However, this means
+/// you should only be using this intrinsic to guard requirements that, if violated,
+/// immediately lead to UB. Otherwise, const-eval and Miri will miss out on those
+/// checks entirely.
+///
+/// Since this is evaluated after monomorphization, branching on this value can be used to
+/// implement debug assertions that are included in the precompiled standard library, but can
+/// be optimized out by builds that monomorphize the standard library code with debug
+/// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
 #[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
 pub(crate) const fn debug_assertions() -> bool {
     cfg!(debug_assertions)
 }
 
+/// Allocates a block of memory at compile time.
+/// At runtime, just returns a null pointer.
+///
+/// # Safety
+///
+/// - The `align` argument must be a power of two.
+///    - At compile time, a compile error occurs if this constraint is violated.
+///    - At runtime, it is not checked.
+#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_nounwind]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 {
+    // const eval overrides this function, but runtime code should always just return null pointers.
+    crate::ptr::null_mut()
+}
+
+/// Deallocates a memory which allocated by `intrinsics::const_allocate` at compile time.
+/// At runtime, does nothing.
+///
+/// # Safety
+///
+/// - The `align` argument must be a power of two.
+///    - At compile time, a compile error occurs if this constraint is violated.
+///    - At runtime, it is not checked.
+/// - If the `ptr` is created in an another const, this intrinsic doesn't deallocate it.
+/// - If the `ptr` is pointing to a local variable, this intrinsic doesn't deallocate it.
+#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_nounwind]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+
 // Some functions are defined here because they accidentally got made
 // available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
 // (`transmute` also falls into this category, but it cannot be wrapped due to the
diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs
index 946d0051ccec3..8c68ea114dbd2 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::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 4e0e19ddc7822..d084bede1eba6 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 c748336cd7fa0..bcaac2f42cf04 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::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::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 3de91267cf5d9..1a106ef97942b 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 52a5add1132a4..6d82d1581f79d 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 51bd09b6effe1..b35ed8442032d 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::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 92f465ccdb4e8..ef46040f0a703 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 882f3e3bc60f5..a7f1fde6975c0 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 81ac0eaa67e95..64bd5b3e2b668 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 7d6f746845e31..99344a88efc3f 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::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::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::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,7 @@ where
         }
 
         match self.iter_try_fold(n, advance) {
-            ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err),
+            ControlFlow::Continue(remaining) => NonZero::new(remaining).map_or(Ok(()), Err),
             _ => Ok(()),
         }
     }
@@ -759,7 +759,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 +770,7 @@ where
         }
 
         match self.iter_try_rfold(n, advance) {
-            ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err),
+            ControlFlow::Continue(remaining) => NonZero::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 fd2d830b693d1..1c4656a649a37 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 c882c9e7f3f51..6e163e20d8ec4 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 bcae73cbe09cf..9ad50048c25ea 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 4037e2e2839c0..cc514bd914f14 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 4aaf7c61f50d6..06ab15d5e900d 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 635bad199ff95..d261a535b183a 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 f5188dd458df9..f51a2c39b8e28 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::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::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 3a661973e5fe0..8001e6e64713a 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 80e06066d28f9..6870c677b1e07 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::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::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 e55d55a6d2377..d3f09ab356ad8 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 b33400fab476f..2e885f06b5272 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 0e03d0c2d4e4f..68937161e046a 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::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::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::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::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 67051f6e97bdd..0168b11c7394a 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 db2f8b7ac283f..8224e4b12a0eb 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::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 4c8af4eba7889..48aae73d928a0 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::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 20dd95a3a4623..522e75a5683b2 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::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 e7c1f195aacc6..8bdbca120d7f9 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 288ad8e8d8784..fe2873261751d 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -160,6 +160,27 @@ where
             }
         }
     }
+
+    /// Returns the contained value as a primitive type.
+    #[stable(feature = "nonzero", since = "1.28.0")]
+    #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
+    #[inline]
+    pub const fn get(self) -> T {
+        // FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata
+        // for function arguments: https://github.com/llvm/llvm-project/issues/76628
+        //
+        // Rustc can set range metadata only if it loads `self` from
+        // memory somewhere. If the value of `self` was from by-value argument
+        // of some not-inlined function, LLVM don't have range metadata
+        // to understand that the value cannot be zero.
+        match Self::new(self.0) {
+            Some(Self(n)) => n,
+            None => {
+                // SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable.
+                unsafe { intrinsics::unreachable() }
+            }
+        }
+    }
 }
 
 macro_rules! impl_nonzero_fmt {
@@ -221,26 +242,6 @@ macro_rules! nonzero_integer {
         pub type $Ty = NonZero<$Int>;
 
         impl $Ty {
-            /// Returns the value as a primitive type.
-            #[$stability]
-            #[inline]
-            #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
-            pub const fn get(self) -> $Int {
-                // FIXME: Remove this after LLVM supports `!range` metadata for function
-                // arguments https://github.com/llvm/llvm-project/issues/76628
-                //
-                // Rustc can set range metadata only if it loads `self` from
-                // memory somewhere. If the value of `self` was from by-value argument
-                // of some not-inlined function, LLVM don't have range metadata
-                // to understand that the value cannot be zero.
-
-                // SAFETY: It is an invariant of this type.
-                unsafe {
-                    intrinsics::assume(self.0 != 0);
-                }
-                self.0
-            }
-
             /// The size of this non-zero integer type in bits.
             ///
             #[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")]
@@ -312,10 +313,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 +337,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::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 743799c4b3edf..07ea2e930d57a 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::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::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 ce176e6fc18f3..d2422bb80ae58 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::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 320cd5eb3b2ae..16e903439936d 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::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 1429313c89064..617b385a960c4 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 fc6af45fb9077..7910981d0f5ee 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::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::new(n - advance).map_or(Ok(()), Err)
             }
         }
 
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 73e92ed1dad63..1d8ac6aa04394 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::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 4d6239e11a399..00b4405faaefb 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::new(remainder).map_or(Ok(()), Err)
     }
 
     #[inline]
diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs
index ed52de3cbec16..e7773d138c255 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::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::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::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::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 ad78a85a88dcb..b2429588de12b 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,7 @@ 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::new(100 - (len - i - 1)).unwrap()));
             assert_eq!(iter.advance_by(0), Ok(()));
         }
 
@@ -42,10 +42,7 @@ fn test_iterator_chain_advance_by() {
             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
             assert_eq!(iter.advance_by(xs.len() + i), Ok(()));
             assert_eq!(iter.next(), Some(&ys[i]));
-            assert_eq!(
-                iter.advance_by(100),
-                Err(NonZeroUsize::new(100 - (ys.len() - i - 1)).unwrap())
-            );
+            assert_eq!(iter.advance_by(100), Err(NonZero::new(100 - (ys.len() - i - 1)).unwrap()));
             assert_eq!(iter.advance_by(0), Ok(()));
         }
 
@@ -55,7 +52,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::new(1).unwrap()));
         assert_eq!(iter.advance_by(0), Ok(()));
     }
 
@@ -74,10 +71,7 @@ fn test_iterator_chain_advance_back_by() {
             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
             assert_eq!(iter.advance_back_by(i), Ok(()));
             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())
-            );
+            assert_eq!(iter.advance_back_by(100), Err(NonZero::new(100 - (len - i - 1)).unwrap()));
             assert_eq!(iter.advance_back_by(0), Ok(()));
         }
 
@@ -87,7 +81,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::new(100 - (xs.len() - i - 1)).unwrap())
             );
             assert_eq!(iter.advance_back_by(0), Ok(()));
         }
@@ -98,7 +92,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::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 ff57973a62a4b..b57d51c077e9b 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::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 f429d90cd7ddd..2af7e0c388a3b 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::new(usize::MAX - 9).unwrap()));
+    assert_eq!(it.advance_back_by(usize::MAX), Err(NonZero::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 e3e88a84fadf6..8d5d06ad9fb3a 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::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::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::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 ff6e362b065c6..39afa2cbfcaf2 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::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::new(1).unwrap()));
+    assert_eq!((0..10).take(4).advance_by(5), Err(NonZero::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::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::new(9).unwrap()));
+    assert_eq!((0..0).take(1).advance_back_by(1), Err(NonZero::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::new(usize::MAX - 100).unwrap())
     );
 }
 
diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs
index a6b9f1cb7c889..9af07119a89a2 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::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 4c2d843eaa0dc..93ef9c0812b16 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,11 @@ 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::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::new(100 - v.len()).unwrap()));
 }
 
 #[test]
@@ -167,14 +167,11 @@ fn test_iterator_advance_back_by() {
         let mut iter = v.iter();
         assert_eq!(iter.advance_back_by(i), Ok(()));
         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())
-        );
+        assert_eq!(iter.advance_back_by(100), Err(NonZero::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::new(100 - v.len()).unwrap()));
 }
 
 #[test]
@@ -185,14 +182,11 @@ fn test_iterator_rev_advance_back_by() {
         let mut iter = v.iter().rev();
         assert_eq!(iter.advance_back_by(i), Ok(()));
         assert_eq!(iter.next_back().unwrap(), &v[i]);
-        assert_eq!(
-            iter.advance_back_by(100),
-            Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())
-        );
+        assert_eq!(iter.advance_back_by(100), Err(NonZero::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::new(100 - v.len()).unwrap()));
 }
 
 #[test]
@@ -460,11 +454,11 @@ 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::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::new(100 - v.len()).unwrap()));
 }
 
 #[test]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 2fe79650dbfd4..fa0e9a979d060 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 8873d26880ced..d728513a4e297 100644
--- a/library/core/tests/nonzero.rs
+++ b/library/core/tests/nonzero.rs
@@ -1,32 +1,29 @@
-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::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(_))"),
+        None => panic!("unexpected None while matching on Some(NonZero(_))"),
     }
 
-    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(_))"),
+        None => panic!("unexpected None while matching on Some(NonZero(_))"),
     }
 }
 
@@ -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::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::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::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::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::new(0b1010_1010).unwrap();
+    let nz_low = NonZero::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::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::new(5).unwrap()));
+    assert_eq!(NonZero::<u32>::try_from(5), Ok(NonZero::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::new(-5).unwrap()));
+    assert_eq!(NonZero::<i32>::try_from(-5), Ok(NonZero::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::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::new(0);
     assert!(ZERO.is_none());
 
-    const ONE: Option<NonZeroU8> = NonZeroU8::new(1);
+    const ONE: Option<NonZero<u8>> = NonZero::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::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::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 b68f2a50b3211..b3f7dfa1fb9c7 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};
@@ -1050,9 +1050,8 @@ fn nonnull_tagged_pointer_with_provenance() {
         /// memory location.
         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)
-            })
+            self.0
+                .map_addr(|addr| unsafe { NonZero::new_unchecked(addr.get() & Self::ADDRESS_MASK) })
         }
 
         /// Consume this tagged pointer and produce the data it carries.
@@ -1073,7 +1072,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::new_unchecked((addr.get() & Self::ADDRESS_MASK) | data)
             })
         }
     }
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index 50926da3ce799..6c008ab2cb196 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::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 bcf7b5e59775a..c5743eda3e802 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::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::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 b3a763069974f..894acae217e44 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 5b1bfb30983b2..6d75a5a627c82 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 930c111455df0..712f6b4545828 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::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 90b76cbc26ebf..1e6e4a043106b 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 3384906a15e3b..fee80c02d4a6f 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::new_unchecked(abi::get_processor_count())) }
 }
 
 pub mod guard {
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 09c4ab3d3e901..06dbeeb9079e6 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};
 
@@ -38,7 +38,7 @@ impl Key {
     }
 
     fn from_index(index: usize) -> Self {
-        Key(NonZeroUsize::new(index + 1).unwrap())
+        Key(NonZero::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::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 10c1456d4fd05..ce3af818c4df5 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs
@@ -194,7 +194,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::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     RegisterArgument::into_register($n2),
                     RegisterArgument::into_register($n3),
@@ -210,7 +210,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::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     RegisterArgument::into_register($n2),
                     RegisterArgument::into_register($n3),
@@ -226,7 +226,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::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     RegisterArgument::into_register($n2),
                     0,0,
@@ -241,7 +241,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::new(Usercalls::$f as Register)),
                     RegisterArgument::into_register($n1),
                     0,0,0,
                     return_type_is_abort!($r)
@@ -255,7 +255,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::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 d89de18ca5ff8..e0295788874b4 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::{
@@ -53,8 +53,7 @@ impl RwLock {
         // Another thread has passed the lock to us
         } else {
             // No waiting writers, acquire the read lock
-            *rguard.lock_var_mut() =
-                NonZeroUsize::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
+            *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
         }
     }
 
@@ -68,8 +67,7 @@ impl RwLock {
             false
         } else {
             // No waiting writers, acquire the read lock
-            *rguard.lock_var_mut() =
-                NonZeroUsize::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
+            *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
             true
         }
     }
@@ -111,7 +109,7 @@ impl RwLock {
         mut rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZeroUsize>>>,
         wguard: SpinMutexGuard<'_, WaitVariable<bool>>,
     ) {
-        *rguard.lock_var_mut() = NonZeroUsize::new(rguard.lock_var().unwrap().get() - 1);
+        *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().unwrap().get() - 1);
         if rguard.lock_var().is_some() {
             // There are other active readers
         } else {
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index 7ac9d1d64b420..c797fde7fbdca 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 25eca61d67b66..9dfc5a88d1540 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;
@@ -252,7 +252,7 @@ impl WaitQueue {
                 entry_guard.wake = true;
             }
 
-            if let Some(count) = NonZeroUsize::new(count) {
+            if let Some(count) = NonZero::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 155f333f90616..77f9040ead540 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/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7e4a01a5ecd33..767f269dbea3d 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::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::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::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::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::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::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::new_unchecked(sinfo.cpu_count as usize))
             }
         } else {
             // FIXME: implement on vxWorks, Redox, l4re
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs
index a8db251de2017..cd1ae7f7d11cd 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 a0eefa8811a39..77d8b4378e7d5 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 714b704922794..49f936f14498c 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 fbbdbc2126595..2ecfe088d107b 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::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::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/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index 1fe744935193c..0f709e2ec7ba7 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::new_unchecked(cpus) }),
     }
 }
 
diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs
index 0f452e07a5c58..21f5954d6e2d2 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::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 b230fd1a829f7..8eae160648502 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::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 eb837c8f6c63f..4f0f010984ab9 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::new(id).unwrap()),
                         Err(id) => last = id,
                     }
                 }
@@ -1208,7 +1207,7 @@ impl ThreadId {
 
                 *counter = id;
                 drop(counter);
-                ThreadId(NonZeroU64::new(id).unwrap())
+                ThreadId(NonZero::new(id).unwrap())
             }
         }
     }
diff --git a/src/doc/unstable-book/src/language-features/intrinsics.md b/src/doc/unstable-book/src/language-features/intrinsics.md
index 8fa8f567d7eed..9d07ae6fc67e1 100644
--- a/src/doc/unstable-book/src/language-features/intrinsics.md
+++ b/src/doc/unstable-book/src/language-features/intrinsics.md
@@ -2,13 +2,60 @@
 
 The tracking issue for this feature is: None.
 
-Intrinsics are never intended to be stable directly, but intrinsics are often
+Intrinsics are rarely intended to be stable directly, but are usually
 exported in some sort of stable manner. Prefer using the stable interfaces to
 the intrinsic directly when you can.
 
 ------------------------
 
 
+## Intrinsics with fallback logic
+
+Many intrinsics can be written in pure rust, albeit inefficiently or without supporting
+some features that only exist on some backends. Backends can simply not implement those
+intrinsics without causing any code miscompilations or failures to compile.
+
+```rust
+#![feature(rustc_attrs, effects)]
+#![allow(internal_features)]
+
+#[rustc_intrinsic]
+const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+```
+
+Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
+
+```rust
+#![feature(rustc_attrs, effects)]
+#![allow(internal_features)]
+
+#[rustc_intrinsic]
+const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+
+mod foo {
+    #[rustc_intrinsic]
+    const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {
+        panic!("noisy const dealloc")
+    }
+}
+
+```
+
+The behaviour on backends that override the intrinsic is exactly the same. On other
+backends, the intrinsic behaviour depends on which implementation is called, just like
+with any regular function.
+
+## Intrinsics lowered to MIR instructions
+
+Various intrinsics have native MIR operations that they correspond to. Instead of requiring
+backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass
+will convert the calls to the MIR operation. Backends do not need to know about these intrinsics
+at all.
+
+## Intrinsics without fallback logic
+
+These must be implemented by all backends.
+
 These are imported as if they were FFI functions, with the special
 `rust-intrinsic` ABI. For example, if one was in a freestanding
 context, but wished to be able to `transmute` between types, and
@@ -27,4 +74,5 @@ extern "rust-intrinsic" {
 }
 ```
 
-As with any other FFI functions, these are always `unsafe` to call.
+As with any other FFI functions, these are by default always `unsafe` to call.
+You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call.
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 96b4d1a45f6ea..f4ef9a39a65f0 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -643,7 +643,7 @@ impl Item {
                 let abi = tcx.fn_sig(def_id).skip_binder().abi();
                 hir::FnHeader {
                     unsafety: if abi == Abi::RustIntrinsic {
-                        intrinsic_operation_unsafety(tcx, self.def_id().unwrap())
+                        intrinsic_operation_unsafety(tcx, def_id.expect_local())
                     } else {
                         hir::Unsafety::Unsafe
                     },
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 8d5bcd665ad25..47195fcc17b48 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -335,7 +335,7 @@ fn check_terminator<'tcx>(
                 // within const fns. `transmute` is allowed in all other const contexts.
                 // This won't really scale to more intrinsics or functions. Let's allow const
                 // transmutes in const fn before we add more hacks to this.
-                if tcx.is_intrinsic(fn_def_id) && tcx.item_name(fn_def_id) == sym::transmute {
+                if matches!(tcx.intrinsic(fn_def_id), Some(sym::transmute)) {
                     return Err((
                         span,
                         "can only call `transmute` from const items, not `const fn`".into(),
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index de7a4b79d26ff..095ba17367135 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 46f96a715f1c6..45240edea455d 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::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::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::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 9a848d50341a4..35dcfecbbe334 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 b288b69e0cef9..b948ecb834539 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::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::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 7f91af59d5622..19b29a4181984 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 d6b1e1358086c..3cee4df588542 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 5a2bb84f3eff0..305c71fb0f945 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 25654248db41a..bf90d1468bb0e 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::new(id) {
                     this.print_borrow_state(AllocId(id), show_unnamed)?;
                 }
             }
diff --git a/src/tools/miri/tests/pass/intrinsics.rs b/src/tools/miri/tests/pass/intrinsics.rs
index 8e46bd7ad48fb..0dda5aadce20a 100644
--- a/src/tools/miri/tests/pass/intrinsics.rs
+++ b/src/tools/miri/tests/pass/intrinsics.rs
@@ -37,7 +37,7 @@ fn main() {
     let mut saw_false = false;
 
     for _ in 0..50 {
-        if unsafe { intrinsics::is_val_statically_known(0) } {
+        if intrinsics::is_val_statically_known(0) {
             saw_true = true;
         } else {
             saw_false = true;
diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs
index 8f084f6c54bdc..95f6466b2548f 100644
--- a/tests/codegen/is_val_statically_known.rs
+++ b/tests/codegen/is_val_statically_known.rs
@@ -11,7 +11,7 @@ pub enum B {
 
 #[inline]
 pub fn _u32(a: u32) -> i32 {
-    if unsafe { is_val_statically_known(a) } { 1 } else { 0 }
+    if is_val_statically_known(a) { 1 } else { 0 }
 }
 
 // CHECK-LABEL: @_u32_true(
@@ -30,7 +30,7 @@ pub fn _u32_false(a: u32) -> i32 {
 
 #[inline]
 pub fn _bool(b: bool) -> i32 {
-    if unsafe { is_val_statically_known(b) } { 3 } else { 2 }
+    if is_val_statically_known(b) { 3 } else { 2 }
 }
 
 // CHECK-LABEL: @_bool_true(
diff --git a/tests/ui/abi/issues/issue-22565-rust-call.rs b/tests/ui/abi/issues/issue-22565-rust-call.rs
index a572666c8887f..72f45cba0c02e 100644
--- a/tests/ui/abi/issues/issue-22565-rust-call.rs
+++ b/tests/ui/abi/issues/issue-22565-rust-call.rs
@@ -25,7 +25,11 @@ impl Tr for Foo {
 
 fn main() {
     b(10);
+    //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
     Foo::bar();
+    //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
     <Foo as Tr>::a();
+    //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
     <Foo as Tr>::b();
+    //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
 }
diff --git a/tests/ui/abi/issues/issue-22565-rust-call.stderr b/tests/ui/abi/issues/issue-22565-rust-call.stderr
index 9d205b444fad4..0fd3285cd3a52 100644
--- a/tests/ui/abi/issues/issue-22565-rust-call.stderr
+++ b/tests/ui/abi/issues/issue-22565-rust-call.stderr
@@ -28,6 +28,30 @@ error: functions with the "rust-call" ABI must take a single non-self tuple argu
 LL |     extern "rust-call" fn b() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
+  --> $DIR/issue-22565-rust-call.rs:27:7
+   |
+LL |     b(10);
+   |       ^^ the trait `Tuple` is not implemented for `i32`
+
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+  --> $DIR/issue-22565-rust-call.rs:29:5
+   |
+LL |     Foo::bar();
+   |     ^^^^^^^^^^
+
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+  --> $DIR/issue-22565-rust-call.rs:31:5
+   |
+LL |     <Foo as Tr>::a();
+   |     ^^^^^^^^^^^^^^^^
+
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+  --> $DIR/issue-22565-rust-call.rs:33:5
+   |
+LL |     <Foo as Tr>::b();
+   |     ^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-consts/associated-const-in-trait.rs b/tests/ui/associated-consts/associated-const-in-trait.rs
index cf5d5d859b6e4..4e8143d5795db 100644
--- a/tests/ui/associated-consts/associated-const-in-trait.rs
+++ b/tests/ui/associated-consts/associated-const-in-trait.rs
@@ -7,6 +7,7 @@ trait Trait {
 impl dyn Trait {
     //~^ ERROR the trait `Trait` cannot be made into an object [E0038]
     const fn n() -> usize { Self::N }
+    //~^ ERROR the trait `Trait` cannot be made into an object [E0038]
 }
 
 fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr
index 59acd4820aea9..88360cd2dd5c2 100644
--- a/tests/ui/associated-consts/associated-const-in-trait.stderr
+++ b/tests/ui/associated-consts/associated-const-in-trait.stderr
@@ -13,6 +13,21 @@ LL |     const N: usize;
    |           ^ ...because it contains this associated `const`
    = help: consider moving `N` to another trait
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/associated-const-in-trait.rs:9:29
+   |
+LL |     const fn n() -> usize { Self::N }
+   |                             ^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/associated-const-in-trait.rs:4:11
+   |
+LL | trait Trait {
+   |       ----- this trait cannot be made into an object...
+LL |     const N: usize;
+   |           ^ ...because it contains this associated `const`
+   = help: consider moving `N` to another trait
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs
index 6c6dae864f340..fb2169ab43f2e 100644
--- a/tests/ui/associated-consts/issue-105330.rs
+++ b/tests/ui/associated-consts/issue-105330.rs
@@ -10,10 +10,15 @@ impl TraitWAssocConst for impl Demo { //~ ERROR E0404
 
 fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
     foo::<Demo>()();
+    //~^ ERROR is not satisfied
+    //~| ERROR type mismatch
+    //~| ERROR expected function, found `()`
 }
 
 fn main<A: TraitWAssocConst<A=32>>() {
     //~^ ERROR E0658
     //~| ERROR E0131
     foo::<Demo>();
+    //~^ ERROR type mismatch
+    //~| ERROR is not satisfied
 }
diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr
index b4c021d0f4fdc..50ce69b33815d 100644
--- a/tests/ui/associated-consts/issue-105330.stderr
+++ b/tests/ui/associated-consts/issue-105330.stderr
@@ -26,7 +26,7 @@ LL | fn foo<A: TraitWAssocConst<A=32>>() {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated const equality is incomplete
-  --> $DIR/issue-105330.rs:15:29
+  --> $DIR/issue-105330.rs:18:29
    |
 LL | fn main<A: TraitWAssocConst<A=32>>() {
    |                             ^^^^
@@ -44,12 +44,76 @@ LL | impl TraitWAssocConst for impl Demo {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0131]: `main` function is not allowed to have generic parameters
-  --> $DIR/issue-105330.rs:15:8
+  --> $DIR/issue-105330.rs:18:8
    |
 LL | fn main<A: TraitWAssocConst<A=32>>() {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
 
-error: aborting due to 6 previous errors
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+  --> $DIR/issue-105330.rs:12:11
+   |
+LL |     foo::<Demo>()();
+   |           ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+   |
+   = help: the trait `TraitWAssocConst` is implemented for `{type error}`
+note: required by a bound in `foo`
+  --> $DIR/issue-105330.rs:11:11
+   |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+   |           ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+  --> $DIR/issue-105330.rs:12:11
+   |
+LL |     foo::<Demo>()();
+   |           ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
+   |
+   = note: expected constant `32`
+              found constant `<Demo as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+  --> $DIR/issue-105330.rs:11:28
+   |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+   |                            ^^^^ required by this bound in `foo`
+
+error[E0618]: expected function, found `()`
+  --> $DIR/issue-105330.rs:12:5
+   |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+   | ----------------------------------- `foo::<Demo>` defined here returns `()`
+LL |     foo::<Demo>()();
+   |     ^^^^^^^^^^^^^--
+   |     |
+   |     call expression requires function
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+  --> $DIR/issue-105330.rs:21:11
+   |
+LL |     foo::<Demo>();
+   |           ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+   |
+   = help: the trait `TraitWAssocConst` is implemented for `{type error}`
+note: required by a bound in `foo`
+  --> $DIR/issue-105330.rs:11:11
+   |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+   |           ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+  --> $DIR/issue-105330.rs:21:11
+   |
+LL |     foo::<Demo>();
+   |           ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
+   |
+   = note: expected constant `32`
+              found constant `<Demo as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+  --> $DIR/issue-105330.rs:11:28
+   |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+   |                            ^^^^ required by this bound in `foo`
+
+error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0131, E0404, E0562, E0658.
+Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658.
 For more information about an error, try `rustc --explain E0131`.
diff --git a/tests/ui/associated-inherent-types/issue-109299.rs b/tests/ui/associated-inherent-types/issue-109299.rs
index 84e4f9e72527a..b6c010c34e441 100644
--- a/tests/ui/associated-inherent-types/issue-109299.rs
+++ b/tests/ui/associated-inherent-types/issue-109299.rs
@@ -8,5 +8,6 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d`
 }
 
 fn test(_: Lexer::Cursor) {}
+//~^ ERROR: lifetime may not live long enough
 
 fn main() {}
diff --git a/tests/ui/associated-inherent-types/issue-109299.stderr b/tests/ui/associated-inherent-types/issue-109299.stderr
index 1e11c0e8c2af1..f108a52b92c08 100644
--- a/tests/ui/associated-inherent-types/issue-109299.stderr
+++ b/tests/ui/associated-inherent-types/issue-109299.stderr
@@ -6,6 +6,15 @@ LL | impl Lexer<'d> {
    |     |
    |     help: consider introducing lifetime `'d` here: `<'d>`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/issue-109299.rs:10:1
+   |
+LL | fn test(_: Lexer::Cursor) {}
+   | ^^^^^^^^-^^^^^^^^^^^^^^^^
+   | |       |
+   | |       has type `Lexer<'1>::Cursor`
+   | requires that `'1` must outlive `'static`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs
index 0b5ba7d1fb55d..46dd4590141d0 100644
--- a/tests/ui/associated-inherent-types/issue-109789.rs
+++ b/tests/ui/associated-inherent-types/issue-109789.rs
@@ -18,5 +18,7 @@ impl Other for u32 {}
 fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
 //~^ ERROR mismatched types
 //~| ERROR mismatched types
+//~| ERROR higher-ranked subtype error
+//~| ERROR higher-ranked subtype error
 
 fn main() {}
diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr
index e844f6795e6f8..c6ea6c5541d23 100644
--- a/tests/ui/associated-inherent-types/issue-109789.stderr
+++ b/tests/ui/associated-inherent-types/issue-109789.stderr
@@ -17,6 +17,20 @@ LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
               found struct `Foo<for<'a> fn(&'a ())>`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 2 previous errors
+error: higher-ranked subtype error
+  --> $DIR/issue-109789.rs:18:1
+   |
+LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+  --> $DIR/issue-109789.rs:18:1
+   |
+LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/regionck-2.rs b/tests/ui/associated-inherent-types/regionck-2.rs
index 7a0b8b0830015..573dd359bf2b0 100644
--- a/tests/ui/associated-inherent-types/regionck-2.rs
+++ b/tests/ui/associated-inherent-types/regionck-2.rs
@@ -10,5 +10,6 @@ impl Lexer<'static> {
 }
 
 fn test(_: Lexer::Cursor) {} //~ ERROR mismatched types
+//~^ ERROR: lifetime may not live long enough
 
 fn main() {}
diff --git a/tests/ui/associated-inherent-types/regionck-2.stderr b/tests/ui/associated-inherent-types/regionck-2.stderr
index 4c68a591240f2..82f5c6a72c008 100644
--- a/tests/ui/associated-inherent-types/regionck-2.stderr
+++ b/tests/ui/associated-inherent-types/regionck-2.stderr
@@ -13,6 +13,15 @@ LL | fn test(_: Lexer::Cursor) {}
    |            ^^^^^
    = note: ...does not necessarily outlive the static lifetime
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/regionck-2.rs:12:1
+   |
+LL | fn test(_: Lexer::Cursor) {}
+   | ^^^^^^^^-^^^^^^^^^^^^^^^^
+   | |       |
+   | |       has type `Lexer<'1>::Cursor`
+   | requires that `'1` must outlive `'static`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed
index adfba994f32dc..e713db025e8be 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed
@@ -8,9 +8,9 @@ trait Get {
 }
 
 trait Other {
-    fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+    fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get, Self: Get {}
     //~^ ERROR the trait bound `Self: Get` is not satisfied
+    //~| ERROR the trait bound `Self: Get` is not satisfied
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.rs b/tests/ui/associated-types/associated-types-for-unimpl-trait.rs
index 50478171d869a..c5d7ba3a75537 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.rs
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.rs
@@ -8,9 +8,9 @@ trait Get {
 }
 
 trait Other {
-    fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+    fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {}
     //~^ ERROR the trait bound `Self: Get` is not satisfied
+    //~| ERROR the trait bound `Self: Get` is not satisfied
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
index 27014fa53d8a2..4cba3990049a5 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -1,14 +1,25 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-for-unimpl-trait.rs:11:40
+  --> $DIR/associated-types-for-unimpl-trait.rs:11:41
    |
-LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {}
+   |                                         ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
-LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
-   |                                                              +++++++++++++++
+LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get {}
+   |                                                                                +++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `Self: Get` is not satisfied
+  --> $DIR/associated-types-for-unimpl-trait.rs:11:81
+   |
+LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {}
+   |                                                                                 ^^ the trait `Get` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get {}
+   |                                                                                +++++++++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/associated-types-no-suitable-bound.rs b/tests/ui/associated-types/associated-types-no-suitable-bound.rs
index d42460a4c072d..7019c476237bb 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-bound.rs
+++ b/tests/ui/associated-types/associated-types-no-suitable-bound.rs
@@ -10,7 +10,7 @@ struct Struct {
 impl Struct {
     fn uhoh<T>(foo: <T as Get>::Value) {}
     //~^ ERROR the trait bound `T: Get` is not satisfied
+    //~| ERROR the trait bound `T: Get` is not satisfied
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/associated-types/associated-types-no-suitable-bound.stderr b/tests/ui/associated-types/associated-types-no-suitable-bound.stderr
index fe1be6be01554..9713051d97327 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-bound.stderr
+++ b/tests/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -9,6 +9,17 @@ help: consider restricting type parameter `T`
 LL |     fn uhoh<T: Get>(foo: <T as Get>::Value) {}
    |              +++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `T: Get` is not satisfied
+  --> $DIR/associated-types-no-suitable-bound.rs:11:40
+   |
+LL |     fn uhoh<T>(foo: <T as Get>::Value) {}
+   |                                        ^^ the trait `Get` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
+   |
+LL |     fn uhoh<T: Get>(foo: <T as Get>::Value) {}
+   |              +++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs
index 17dfa1773dddb..5dc1ac88c8a9e 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs
+++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs
@@ -16,6 +16,7 @@ trait Get {
 trait Other {
     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
     //~^ ERROR the trait bound `Self: Get` is not satisfied
+    //~| ERROR the trait bound `Self: Get` is not satisfied
 }
 
 fn main() { }
diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
index b586053a5bc9c..c5dcfc00925d7 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
+++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
@@ -9,6 +9,17 @@ help: consider further restricting `Self`
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
    |                                                              +++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `Self: Get` is not satisfied
+  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:62
+   |
+LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+   |                                                              ^^ the trait `Get` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+   |                                                              +++++++++++++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs b/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs
index cc0101d63cf21..144812fa4d1c6 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs
+++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs
@@ -16,12 +16,14 @@ trait Get {
 trait Other {
     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
     //~^ ERROR the trait bound `Self: Get` is not satisfied
+    //~| ERROR the trait bound `Self: Get` is not satisfied
 }
 
 impl<T:Get> Other for T {
     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
     //~^ ERROR the trait bound `(T, U): Get` is not satisfied
     //~| ERROR the trait bound `(T, U): Get` is not satisfied
+    //~| ERROR the trait bound `(T, U): Get` is not satisfied
 }
 
 fn main() { }
diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr
index 5443699eb019f..46cebda078e46 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr
+++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(T, U): Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:22:5
+  --> $DIR/associated-types-no-suitable-supertrait.rs:23:5
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
@@ -11,7 +11,7 @@ LL | trait Get {
    | ^^^^^^^^^
 
 error[E0277]: the trait bound `(T, U): Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
+  --> $DIR/associated-types-no-suitable-supertrait.rs:23:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
    |                                        ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
@@ -33,6 +33,29 @@ help: consider further restricting `Self`
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
    |                                                              +++++++++++++++
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `Self: Get` is not satisfied
+  --> $DIR/associated-types-no-suitable-supertrait.rs:17:62
+   |
+LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+   |                                                              ^^ the trait `Get` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+   |                                                              +++++++++++++++
+
+error[E0277]: the trait bound `(T, U): Get` is not satisfied
+  --> $DIR/associated-types-no-suitable-supertrait.rs:23:64
+   |
+LL |     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
+   |                                                                ^^ the trait `Get` is not implemented for `(T, U)`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/associated-types-no-suitable-supertrait.rs:12:1
+   |
+LL | trait Get {
+   | ^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-1.rs b/tests/ui/associated-types/hr-associated-type-bound-1.rs
index db414164e1663..37c1a47fcd279 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-1.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-1.rs
@@ -15,4 +15,5 @@ impl X<'_> for i32 {
 
 fn main() {
     1i32.f("abc");
+    //~^ ERROR the trait bound `str: Clone`
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-1.stderr
index 01005b6b22d1f..8830048ed4e31 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-1.stderr
@@ -14,6 +14,22 @@ LL | where
 LL |     for<'b> <Self as X<'b>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-1.rs:17:10
+   |
+LL |     1i32.f("abc");
+   |          ^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X::f`
+  --> $DIR/hr-associated-type-bound-1.rs:3:33
+   |
+LL |     for<'b> <Self as X<'b>>::U: Clone,
+   |                                 ^^^^^ required by this bound in `X::f`
+...
+LL |     fn f(&self, x: &Self::U) {
+   |        - required by a bound in this associated function
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.rs b/tests/ui/associated-types/hr-associated-type-bound-object.rs
index e19c918c3dfe2..fec253f9289ac 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-object.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-object.rs
@@ -7,6 +7,9 @@ where
 fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) {
     //~^ ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
     <<T as X<'_>>::U>::clone(x);
+    //~^ ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
+    //~| ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
+    //~| ERROR the trait bound `<T as X<'_>>::U: Clone` is not satisfied
 }
 
 pub fn main() {
diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
index 87a048d0a134c..322d6e7b947c8 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
@@ -17,6 +17,55 @@ help: consider further restricting the associated type
 LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone {
    |                                                  ++++++++++++++++++++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-object.rs:9:7
+   |
+LL |     <<T as X<'_>>::U>::clone(x);
+   |       ^ the trait `for<'b> Clone` is not implemented for `<T as X<'b>>::U`
+   |
+note: required by a bound in `X::U`
+  --> $DIR/hr-associated-type-bound-object.rs:3:33
+   |
+LL |     for<'b> <Self as X<'b>>::U: Clone,
+   |                                 ^^^^^ required by this bound in `X::U`
+LL | {
+LL |     type U: ?Sized;
+   |          - required by a bound in this associated type
+help: consider further restricting the associated type
+   |
+LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone {
+   |                                                  ++++++++++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `<T as X<'_>>::U: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-object.rs:9:6
+   |
+LL |     <<T as X<'_>>::U>::clone(x);
+   |      ^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<T as X<'_>>::U`
+   |
+help: consider further restricting the associated type
+   |
+LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where <T as X<'_>>::U: Clone {
+   |                                                  ++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-object.rs:9:5
+   |
+LL |     <<T as X<'_>>::U>::clone(x);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Clone` is not implemented for `<T as X<'b>>::U`
+   |
+note: required by a bound in `X`
+  --> $DIR/hr-associated-type-bound-object.rs:3:33
+   |
+LL | trait X<'a>
+   |       - required by a bound in this trait
+LL | where
+LL |     for<'b> <Self as X<'b>>::U: Clone,
+   |                                 ^^^^^ required by this bound in `X`
+help: consider further restricting the associated type
+   |
+LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone {
+   |                                                  ++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-1.rs b/tests/ui/associated-types/hr-associated-type-bound-param-1.rs
index bbeeb145d1fe2..763d48252f7ac 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-1.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-1.rs
@@ -17,4 +17,5 @@ impl<'a> Y<'a, u8> for u8 {
 
 fn main() {
     1u8.g("abc");
+    //~^ ERROR the trait bound `str: Clone` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr
index 0031d205b8426..ad6d3e176843f 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr
@@ -14,6 +14,22 @@ LL | trait Y<'a, T: ?Sized>
 LL |     for<'b> <Self as Y<'b, T>>::V: Clone,
    |                                    ^^^^^ required by this bound in `Y`
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-1.rs:19:9
+   |
+LL |     1u8.g("abc");
+   |         ^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Y::g`
+  --> $DIR/hr-associated-type-bound-param-1.rs:4:36
+   |
+LL |     for<'b> <Self as Y<'b, T>>::V: Clone,
+   |                                    ^^^^^ required by this bound in `Y::g`
+...
+LL |     fn g(&self, x: &Self::V) {
+   |        - required by a bound in this associated function
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.rs b/tests/ui/associated-types/hr-associated-type-bound-param-2.rs
index f74c5a8590d1d..b1a6fe871594b 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-2.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.rs
@@ -8,6 +8,8 @@ where
     type W: ?Sized;
     fn h(&self, x: &T::W) {
         <T::W>::clone(x);
+        //~^ the trait bound `str: Clone` is not satisfied
+        //~| the trait bound `str: Clone` is not satisfied
     }
 }
 
@@ -18,4 +20,5 @@ impl<'a> Z<'a, u16> for u16 {
 
 fn main() {
     1u16.h("abc");
+    //~^ ERROR Clone` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr
index bb484da6a77b1..6a5729e7784f7 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr
@@ -15,7 +15,7 @@ LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
    |                                   ^^^^^ required by this bound in `Z`
 
 error[E0277]: the trait bound `str: Clone` is not satisfied
-  --> $DIR/hr-associated-type-bound-param-2.rs:15:14
+  --> $DIR/hr-associated-type-bound-param-2.rs:17:14
    |
 LL |     type W = str;
    |              ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <u16 as Z<'b, u16>>::W: Clone`
@@ -47,6 +47,54 @@ LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
    |                                   ^^^^^ required by this bound in `Z`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-2.rs:10:10
+   |
+LL |         <T::W>::clone(x);
+   |          ^^^^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Z::W`
+  --> $DIR/hr-associated-type-bound-param-2.rs:6:35
+   |
+LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
+   |                                   ^^^^^ required by this bound in `Z::W`
+LL | {
+LL |     type W: ?Sized;
+   |          - required by a bound in this associated type
+
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-2.rs:10:9
+   |
+LL |         <T::W>::clone(x);
+   |         ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Z`
+  --> $DIR/hr-associated-type-bound-param-2.rs:6:35
+   |
+LL | trait Z<'a, T: ?Sized>
+   |       - required by a bound in this trait
+...
+LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
+   |                                   ^^^^^ required by this bound in `Z`
+
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-2.rs:22:10
+   |
+LL |     1u16.h("abc");
+   |          ^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Z::h`
+  --> $DIR/hr-associated-type-bound-param-2.rs:6:35
+   |
+LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
+   |                                   ^^^^^ required by this bound in `Z::h`
+...
+LL |     fn h(&self, x: &T::W) {
+   |        - required by a bound in this associated function
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.rs b/tests/ui/associated-types/hr-associated-type-bound-param-3.rs
index fda7d8111856d..8b4c84aa349b5 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-3.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.rs
@@ -16,4 +16,5 @@ impl<S, T> X<'_, (T,)> for (S,) {
 
 pub fn main() {
     <(i32,) as X<(i32,)>>::f("abc");
+    //~^ ERROR the trait bound `str: Clone` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
index f4d2f43a9b4d9..70e030f2d1cfc 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
@@ -14,6 +14,22 @@ LL | trait X<'a, T>
 LL |     for<'b> <T as X<'b, T>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-3.rs:18:5
+   |
+LL |     <(i32,) as X<(i32,)>>::f("abc");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X::f`
+  --> $DIR/hr-associated-type-bound-param-3.rs:4:33
+   |
+LL |     for<'b> <T as X<'b, T>>::U: Clone,
+   |                                 ^^^^^ required by this bound in `X::f`
+...
+LL |     fn f(x: &<T as X<'_, T>>::U) {
+   |        - required by a bound in this associated function
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.rs b/tests/ui/associated-types/hr-associated-type-bound-param-4.rs
index 20c8157ed9749..b75bd896cc8b2 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-4.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.rs
@@ -16,4 +16,5 @@ impl<S, T> X<'_, T> for (S,) {
 
 pub fn main() {
     <(i32,) as X<i32>>::f("abc");
+    //~^ ERROR the trait bound `str: Clone` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
index 7f03d1553912d..cba12afd67471 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
@@ -14,6 +14,22 @@ LL | trait X<'a, T>
 LL |     for<'b> <(T,) as X<'b, T>>::U: Clone,
    |                                    ^^^^^ required by this bound in `X`
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-4.rs:18:5
+   |
+LL |     <(i32,) as X<i32>>::f("abc");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X::f`
+  --> $DIR/hr-associated-type-bound-param-4.rs:4:36
+   |
+LL |     for<'b> <(T,) as X<'b, T>>::U: Clone,
+   |                                    ^^^^^ required by this bound in `X::f`
+...
+LL |     fn f(x: &<(T,) as X<'_, T>>::U) {
+   |        - required by a bound in this associated function
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.rs b/tests/ui/associated-types/hr-associated-type-bound-param-5.rs
index d7f3151a502ee..672ade9aa5ee5 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-5.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.rs
@@ -34,4 +34,5 @@ impl<S, T> X<'_, Box<T>> for S {
 
 pub fn main() {
     <i32 as X<Box<i32>>>::f("abc");
+    //~^ ERROR the trait bound `str: Clone` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
index fbbc2f4577243..ac96187749a36 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
@@ -30,6 +30,22 @@ LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
 LL |     for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
    |                                             ^^^^^ required by this bound in `X`
 
-error: aborting due to 2 previous errors
+error[E0277]: the trait bound `str: Clone` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-5.rs:36:5
+   |
+LL |     <i32 as X<Box<i32>>>::f("abc");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |
+   = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X::f`
+  --> $DIR/hr-associated-type-bound-param-5.rs:15:33
+   |
+LL |     for<'b> <T as X<'b, T>>::U: Clone,
+   |                                 ^^^^^ required by this bound in `X::f`
+...
+LL |     fn f(x: &<T as X<'_, T>>::U) {
+   |        - required by a bound in this associated function
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs
index 482047b095925..f6639904ab33a 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs
@@ -16,4 +16,6 @@ impl<S, T> X<'_, T> for (S,) {
 
 pub fn main() {
     <(i32,) as X<i32>>::f("abc");
+    //~^ ERROR the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
+    //~| ERROR the trait bound `i32: X<'_, i32>` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr
index da988f4cfc1b6..cba83120fdc7d 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr
@@ -9,6 +9,22 @@ help: consider restricting type parameter `T`
 LL | impl<S, T: for<'b> X<'b, T>> X<'_, T> for (S,) {
    |          ++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-6.rs:18:5
+   |
+LL |     <(i32,) as X<i32>>::f("abc");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> X<'b, i32>` is not implemented for `i32`
+   |
+   = help: the trait `X<'_, T>` is implemented for `(S,)`
+
+error[E0277]: the trait bound `i32: X<'_, i32>` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-6.rs:18:27
+   |
+LL |     <(i32,) as X<i32>>::f("abc");
+   |                           ^^^^^ the trait `X<'_, i32>` is not implemented for `i32`
+   |
+   = help: the trait `X<'_, T>` is implemented for `(S,)`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.rs b/tests/ui/associated-types/hr-associated-type-projection-1.rs
index 951dd9e97d268..3df3f68ab1eed 100644
--- a/tests/ui/associated-types/hr-associated-type-projection-1.rs
+++ b/tests/ui/associated-types/hr-associated-type-projection-1.rs
@@ -17,4 +17,5 @@ impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
 
 pub fn main() {
     <&'static str>::bug(&"");
+    //~^ type mismatch resolving `<&str as Deref>::Target == &str`
 }
diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr
index 59b52521ef80b..65221718ee661 100644
--- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr
@@ -21,6 +21,21 @@ help: consider further restricting this bound
 LL | impl<T: Copy + std::ops::Deref<Target = T>> UnsafeCopy<'_, T> for T {
    |                               ++++++++++++
 
-error: aborting due to 1 previous error
+error[E0271]: type mismatch resolving `<&str as Deref>::Target == &str`
+  --> $DIR/hr-associated-type-projection-1.rs:19:6
+   |
+LL |     <&'static str>::bug(&"");
+   |      ^^^^^^^^^^^^ expected `&str`, found `str`
+   |
+note: required by a bound in `UnsafeCopy::bug`
+  --> $DIR/hr-associated-type-projection-1.rs:3:64
+   |
+LL |     for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
+   |                                                                ^^^^^^^^^^ required by this bound in `UnsafeCopy::bug`
+...
+LL |     fn bug(item: &Self::Item) -> () {
+   |        --- required by a bound in this associated function
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-types/issue-20005.rs b/tests/ui/associated-types/issue-20005.rs
index 36350bff100dd..e6e83d92061c3 100644
--- a/tests/ui/associated-types/issue-20005.rs
+++ b/tests/ui/associated-types/issue-20005.rs
@@ -6,9 +6,9 @@ trait From<Src> {
 
 trait To {
     fn to<Dst>(
-        self
+        self //~ ERROR the size for values of type
     ) -> <Dst as From<Self>>::Result where Dst: From<Self> { //~ ERROR the size for values of type
-        From::from(self)
+        From::from(self) //~ ERROR the size for values of type
     }
 }
 
diff --git a/tests/ui/associated-types/issue-20005.stderr b/tests/ui/associated-types/issue-20005.stderr
index f2983383fa623..1600227c82da9 100644
--- a/tests/ui/associated-types/issue-20005.stderr
+++ b/tests/ui/associated-types/issue-20005.stderr
@@ -18,6 +18,42 @@ help: consider relaxing the implicit `Sized` restriction
 LL | trait From<Src: ?Sized> {
    |               ++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/issue-20005.rs:9:9
+   |
+LL |         self
+   |         ^^^^ doesn't have a size known at compile-time
+   |
+   = help: unsized fn params are gated as an unstable feature
+help: consider further restricting `Self`
+   |
+LL |     ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized {
+   |                                                           +++++++++++++
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |         &self
+   |         +
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/issue-20005.rs:11:9
+   |
+LL |         From::from(self)
+   |         ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+note: required by an implicit `Sized` bound in `From`
+  --> $DIR/issue-20005.rs:1:12
+   |
+LL | trait From<Src> {
+   |            ^^^ required by the implicit `Sized` requirement on this type parameter in `From`
+help: consider further restricting `Self`
+   |
+LL |     ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized {
+   |                                                           +++++++++++++
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait From<Src: ?Sized> {
+   |               ++++++++
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/issue-38821.rs b/tests/ui/associated-types/issue-38821.rs
index 34c35d7acf1db..c9be1369f1634 100644
--- a/tests/ui/associated-types/issue-38821.rs
+++ b/tests/ui/associated-types/issue-38821.rs
@@ -35,6 +35,8 @@ pub trait Column: Expression {}
 //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
 //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
 //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
+//~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
+//~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
 pub enum ColumnInsertValue<Col, Expr> where
 //~^ ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
 //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr
index 50d622c89bb57..acf6bb2810c99 100644
--- a/tests/ui/associated-types/issue-38821.stderr
+++ b/tests/ui/associated-types/issue-38821.stderr
@@ -18,7 +18,7 @@ LL |     Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Co
    |                                                                       +++++++++++++++++++++++++++++++++++++++
 
 error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
-  --> $DIR/issue-38821.rs:38:1
+  --> $DIR/issue-38821.rs:40:1
    |
 LL | pub enum ColumnInsertValue<Col, Expr> where
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
@@ -36,7 +36,7 @@ LL |     Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Co
    |                                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
-  --> $DIR/issue-38821.rs:38:1
+  --> $DIR/issue-38821.rs:40:1
    |
 LL | / pub enum ColumnInsertValue<Col, Expr> where
 LL | |
@@ -283,6 +283,38 @@ LL | impl<T: NotNull> IntoNullable for T {
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 16 previous errors
+error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
+  --> $DIR/issue-38821.rs:23:10
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |          ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
+   |
+note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
+  --> $DIR/issue-38821.rs:9:18
+   |
+LL | impl<T: NotNull> IntoNullable for T {
+   |         -------  ^^^^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
+  --> $DIR/issue-38821.rs:23:23
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
+   |
+note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
+  --> $DIR/issue-38821.rs:9:18
+   |
+LL | impl<T: NotNull> IntoNullable for T {
+   |         -------  ^^^^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 18 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/issue-59324.rs b/tests/ui/associated-types/issue-59324.rs
index 551f13ee178da..7421e08c89888 100644
--- a/tests/ui/associated-types/issue-59324.rs
+++ b/tests/ui/associated-types/issue-59324.rs
@@ -22,5 +22,7 @@ pub trait ThriftService<Bug: NotFoo>:
 
 fn with_factory<H>(factory: dyn ThriftService<()>) {}
 //~^ ERROR the trait bound `(): Foo` is not satisfied
+//~| ERROR the trait bound `(): Foo` is not satisfied
+//~| ERROR cannot be known at compilation time
 
 fn main() {}
diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr
index 266e22d4726d0..f50d86580f8b0 100644
--- a/tests/ui/associated-types/issue-59324.stderr
+++ b/tests/ui/associated-types/issue-59324.stderr
@@ -66,6 +66,35 @@ help: consider further restricting this bound
 LL | pub trait ThriftService<Bug: NotFoo + Foo>:
    |                                     +++++
 
-error: aborting due to 5 previous errors
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/issue-59324.rs:23:52
+   |
+LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
+   |                                                    ^^ the trait `Foo` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-59324.rs:3:1
+   |
+LL | pub trait Foo: NotFoo {
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time
+  --> $DIR/issue-59324.rs:23:20
+   |
+LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
+   |                    ^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn ThriftService<(), AssocType = _> + 'static)`
+   = help: unsized fn params are gated as an unstable feature
+help: you can use `impl Trait` as the argument type
+   |
+LL | fn with_factory<H>(factory: impl ThriftService<()>) {}
+   |                             ~~~~
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL | fn with_factory<H>(factory: &dyn ThriftService<()>) {}
+   |                             +
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/auto-traits/issue-83857-ub.rs b/tests/ui/auto-traits/issue-83857-ub.rs
index 626e60c37f63f..f9b47d2b0c670 100644
--- a/tests/ui/auto-traits/issue-83857-ub.rs
+++ b/tests/ui/auto-traits/issue-83857-ub.rs
@@ -21,7 +21,9 @@ impl WithAssoc for Foo<u32, ()> {
 
 fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
     //~^ ERROR `Foo<T, U>` cannot be sent between threads safely
+    //~| ERROR `Foo<T, U>` cannot be sent between threads safely
     f(foo(v));
+    //~^ ERROR `Foo<T, U>` cannot be sent between threads safely
 }
 
 fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output {
diff --git a/tests/ui/auto-traits/issue-83857-ub.stderr b/tests/ui/auto-traits/issue-83857-ub.stderr
index 97f1a6032086e..6372bdfe762b0 100644
--- a/tests/ui/auto-traits/issue-83857-ub.stderr
+++ b/tests/ui/auto-traits/issue-83857-ub.stderr
@@ -17,6 +17,50 @@ help: consider introducing a `where` clause, but there might be an alternative b
 LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send {
    |                                                                                +++++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: `Foo<T, U>` cannot be sent between threads safely
+  --> $DIR/issue-83857-ub.rs:22:80
+   |
+LL |   fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
+   |  ________________________________________________________________________________^
+LL | |
+LL | |
+LL | |     f(foo(v));
+LL | |
+LL | | }
+   | |_^ `Foo<T, U>` cannot be sent between threads safely
+   |
+   = help: the trait `Send` is not implemented for `Foo<T, U>`, which is required by `Foo<T, U>: WithAssoc`
+note: required for `Foo<T, U>` to implement `WithAssoc`
+  --> $DIR/issue-83857-ub.rs:15:15
+   |
+LL | impl<T: Send> WithAssoc for T {
+   |         ----  ^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send {
+   |                                                                                +++++++++++++++++++++
+
+error[E0277]: `Foo<T, U>` cannot be sent between threads safely
+  --> $DIR/issue-83857-ub.rs:25:11
+   |
+LL |     f(foo(v));
+   |       --- ^ `Foo<T, U>` cannot be sent between threads safely
+   |       |
+   |       required by a bound introduced by this call
+   |
+   = help: the trait `Send` is not implemented for `Foo<T, U>`
+note: required by a bound in `foo`
+  --> $DIR/issue-83857-ub.rs:29:11
+   |
+LL | fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output {
+   |           ^^^^ required by this bound in `foo`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send {
+   |                                                                                +++++++++++++++++++++
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs
index 6fba87b31975a..05b51e969a0e2 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs
@@ -14,4 +14,5 @@ fn main() {
     let (tx, rx) = channel();
     1193182.foo(tx);
     assert_eq!(rx.recv(), 1193182);
+    //~^ ERROR: mismatched types
 }
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
index d0102635315f1..22e72b6245cec 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
@@ -17,6 +17,20 @@ help: consider adding an explicit lifetime bound
 LL | impl <T: Sync + 'static> Foo for T { }
    |               +++++++++
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/builtin-superkinds-self-type.rs:16:27
+   |
+LL |     assert_eq!(rx.recv(), 1193182);
+   |                           ^^^^^^^ expected `Result<{integer}, RecvError>`, found integer
+   |
+   = note: expected enum `Result<{integer}, RecvError>`
+              found type `{integer}`
+help: try wrapping the expression in `Ok`
+   |
+LL |     assert_eq!(rx.recv(), Ok(1193182));
+   |                           +++       +
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0310`.
+Some errors have detailed explanations: E0308, E0310.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs
index 039cf3e04648a..84aaa5f85e4d9 100644
--- a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs
+++ b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs
@@ -5,6 +5,7 @@ struct X<F> where F: FnOnce() + 'static + Send {
 fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
     //~^ ERROR `F` cannot be sent between threads safely
     return X { field: blk };
+    //~^ ERROR `F` cannot be sent between threads safely
 }
 
 fn main() {
diff --git a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
index e98f05b470e77..8157590bd9e8e 100644
--- a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
+++ b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
@@ -14,6 +14,22 @@ help: consider further restricting this bound
 LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static + std::marker::Send {
    |                                                       +++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: `F` cannot be sent between threads safely
+  --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:7:23
+   |
+LL |     return X { field: blk };
+   |                       ^^^ `F` cannot be sent between threads safely
+   |
+note: required by a bound in `X`
+  --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:1:43
+   |
+LL | struct X<F> where F: FnOnce() + 'static + Send {
+   |                                           ^^^^ required by this bound in `X`
+help: consider further restricting this bound
+   |
+LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static + std::marker::Send {
+   |                                                       +++++++++++++++++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
index cdec81271d090..8426748fd52ee 100644
--- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
@@ -23,6 +23,7 @@ impl MyTrait<MyType> for MyType {
 //~^ ERROR E0119
     fn get(&self) -> usize { (*self).clone() }
     //~^ ERROR incompatible type
+    //~| ERROR mismatched types
 }
 
 fn main() { }
diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
index 471dfe1cae79d..0653009409c5b 100644
--- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
@@ -24,7 +24,15 @@ LL |     fn get(&self) -> T;
    = note: expected signature `fn(&MyType) -> MyType`
               found signature `fn(&MyType) -> usize`
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:30
+   |
+LL |     fn get(&self) -> usize { (*self).clone() }
+   |                      -----   ^^^^^^^^^^^^^^^ expected `usize`, found `MyType`
+   |                      |
+   |                      expected `usize` because of return type
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0053, E0119.
+Some errors have detailed explanations: E0053, E0119, E0308.
 For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/coherence/coherence-tuple-conflict.rs b/tests/ui/coherence/coherence-tuple-conflict.rs
index 8cc829726681f..8dd09598c30bf 100644
--- a/tests/ui/coherence/coherence-tuple-conflict.rs
+++ b/tests/ui/coherence/coherence-tuple-conflict.rs
@@ -15,6 +15,7 @@ impl<T> MyTrait for (T,T) {
 impl<A,B> MyTrait for (A,B) {
 //~^ ERROR E0119
     fn get(&self) -> usize { self.dummy }
+    //~^ ERROR: no field `dummy`
 }
 
 fn main() { }
diff --git a/tests/ui/coherence/coherence-tuple-conflict.stderr b/tests/ui/coherence/coherence-tuple-conflict.stderr
index 4e02c0eb43c7c..95f9a1a8841c8 100644
--- a/tests/ui/coherence/coherence-tuple-conflict.stderr
+++ b/tests/ui/coherence/coherence-tuple-conflict.stderr
@@ -7,6 +7,13 @@ LL | impl<T> MyTrait for (T,T) {
 LL | impl<A,B> MyTrait for (A,B) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_, _)`
 
-error: aborting due to 1 previous error
+error[E0609]: no field `dummy` on type `&(A, B)`
+  --> $DIR/coherence-tuple-conflict.rs:17:35
+   |
+LL |     fn get(&self) -> usize { self.dummy }
+   |                                   ^^^^^ unknown field
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0609.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr
index f64e8b397987b..65be4a9c884fa 100644
--- a/tests/ui/coherence/occurs-check/associated-type.next.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -20,6 +20,13 @@ LL | |     for<'a> *const T: ToUnit<'a>,
    |
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
-error: aborting due to 1 previous error
+error[E0284]: type annotations needed: cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
+  --> $DIR/associated-type.rs:44:59
+   |
+LL |     foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
+   |                                                           ^^^^^^ cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0284.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs
index 227b668478513..3df8fe10a8368 100644
--- a/tests/ui/coherence/occurs-check/associated-type.rs
+++ b/tests/ui/coherence/occurs-check/associated-type.rs
@@ -42,4 +42,5 @@ fn foo<T: Overlap<U>, U>(x: T::Assoc) -> T::Assoc {
 
 fn main() {
     foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
+    //[next]~^ ERROR: cannot satisfy
 }
diff --git a/tests/ui/const-generics/const-argument-if-length.full.stderr b/tests/ui/const-generics/const-argument-if-length.full.stderr
index 315b0f0a06485..db3d88392bd57 100644
--- a/tests/ui/const-generics/const-argument-if-length.full.stderr
+++ b/tests/ui/const-generics/const-argument-if-length.full.stderr
@@ -1,5 +1,5 @@
 error: unconstrained generic constant
-  --> $DIR/const-argument-if-length.rs:17:10
+  --> $DIR/const-argument-if-length.rs:18:10
    |
 LL |     pad: [u8; is_zst::<T>()],
    |          ^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     pad: [u8; is_zst::<T>()],
    = help: try adding a `where` bound using this expression: `where [(); is_zst::<T>()]:`
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/const-argument-if-length.rs:15:12
+  --> $DIR/const-argument-if-length.rs:16:12
    |
 LL | pub struct AtLeastByte<T: ?Sized> {
    |                        - this type parameter needs to be `Sized`
@@ -30,6 +30,22 @@ help: the `Box` type always has a statically known size and allocates its conten
 LL |     value: Box<T>,
    |            ++++ +
 
-error: aborting due to 2 previous errors
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/const-argument-if-length.rs:7:28
+   |
+LL | pub const fn is_zst<T: ?Sized>() -> usize {
+   |                     - this type parameter needs to be `Sized`
+LL |     if std::mem::size_of::<T>() == 0 {
+   |                            ^ doesn't have a size known at compile-time
+   |
+note: required by an implicit `Sized` bound in `std::mem::size_of`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL - pub const fn is_zst<T: ?Sized>() -> usize {
+LL + pub const fn is_zst<T>() -> usize {
+   |
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/const-argument-if-length.min.stderr b/tests/ui/const-generics/const-argument-if-length.min.stderr
index b9d9bcc927069..fdc3f58447631 100644
--- a/tests/ui/const-generics/const-argument-if-length.min.stderr
+++ b/tests/ui/const-generics/const-argument-if-length.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/const-argument-if-length.rs:17:24
+  --> $DIR/const-argument-if-length.rs:18:24
    |
 LL |     pad: [u8; is_zst::<T>()],
    |                        ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     pad: [u8; is_zst::<T>()],
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/const-argument-if-length.rs:15:12
+  --> $DIR/const-argument-if-length.rs:16:12
    |
 LL | pub struct AtLeastByte<T: ?Sized> {
    |                        - this type parameter needs to be `Sized`
@@ -31,6 +31,22 @@ help: the `Box` type always has a statically known size and allocates its conten
 LL |     value: Box<T>,
    |            ++++ +
 
-error: aborting due to 2 previous errors
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/const-argument-if-length.rs:7:28
+   |
+LL | pub const fn is_zst<T: ?Sized>() -> usize {
+   |                     - this type parameter needs to be `Sized`
+LL |     if std::mem::size_of::<T>() == 0 {
+   |                            ^ doesn't have a size known at compile-time
+   |
+note: required by an implicit `Sized` bound in `std::mem::size_of`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL - pub const fn is_zst<T: ?Sized>() -> usize {
+LL + pub const fn is_zst<T>() -> usize {
+   |
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/const-argument-if-length.rs b/tests/ui/const-generics/const-argument-if-length.rs
index db1eafca2c722..c5ff86fbfb7f0 100644
--- a/tests/ui/const-generics/const-argument-if-length.rs
+++ b/tests/ui/const-generics/const-argument-if-length.rs
@@ -5,6 +5,7 @@
 
 pub const fn is_zst<T: ?Sized>() -> usize {
     if std::mem::size_of::<T>() == 0 {
+        //~^ ERROR the size for values of type `T` cannot be known at compilation time
         1
     } else {
         0
diff --git a/tests/ui/const-generics/fn-const-param-infer.full.stderr b/tests/ui/const-generics/fn-const-param-infer.full.stderr
index 48d4a45345af8..753558636e1ef 100644
--- a/tests/ui/const-generics/fn-const-param-infer.full.stderr
+++ b/tests/ui/const-generics/fn-const-param-infer.full.stderr
@@ -4,6 +4,27 @@ error[E0741]: using function pointers as const generic parameters is forbidden
 LL | struct Checked<const F: fn(usize) -> bool>;
    |                         ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/fn-const-param-infer.rs:23:24
+   |
+LL |     let _ = Checked::<{generic_arg::<u32>}>;
+   |                        ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
+   |
+   = note: expected fn pointer `fn(usize) -> _`
+                 found fn item `fn(u32) -> _ {generic_arg::<u32>}`
+
+error[E0282]: type annotations needed
+  --> $DIR/fn-const-param-infer.rs:25:23
+   |
+LL |     let _ = Checked::<generic>;
+   |                       ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
+   |
+help: consider specifying the generic argument
+   |
+LL |     let _ = Checked::<generic::<T>>;
+   |                              +++++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0741`.
+Some errors have detailed explanations: E0282, E0308, E0741.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/const-generics/fn-const-param-infer.min.stderr b/tests/ui/const-generics/fn-const-param-infer.min.stderr
index f6d41809d67da..01e224f8d9ca7 100644
--- a/tests/ui/const-generics/fn-const-param-infer.min.stderr
+++ b/tests/ui/const-generics/fn-const-param-infer.min.stderr
@@ -6,5 +6,27 @@ LL | struct Checked<const F: fn(usize) -> bool>;
    |
    = note: the only supported types are integers, `bool` and `char`
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/fn-const-param-infer.rs:23:24
+   |
+LL |     let _ = Checked::<{generic_arg::<u32>}>;
+   |                        ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
+   |
+   = note: expected fn pointer `fn(usize) -> _`
+                 found fn item `fn(u32) -> _ {generic_arg::<u32>}`
+
+error[E0282]: type annotations needed
+  --> $DIR/fn-const-param-infer.rs:25:23
+   |
+LL |     let _ = Checked::<generic>;
+   |                       ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
+   |
+help: consider specifying the generic argument
+   |
+LL |     let _ = Checked::<generic::<T>>;
+   |                              +++++
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/const-generics/fn-const-param-infer.rs b/tests/ui/const-generics/fn-const-param-infer.rs
index 22f5f529c76ab..d80e18067e239 100644
--- a/tests/ui/const-generics/fn-const-param-infer.rs
+++ b/tests/ui/const-generics/fn-const-param-infer.rs
@@ -20,9 +20,9 @@ fn main() {
 
     let _ = Checked::<generic_arg>;
     let _ = Checked::<{generic_arg::<usize>}>;
-    let _ = Checked::<{generic_arg::<u32>}>;
+    let _ = Checked::<{generic_arg::<u32>}>; //~ ERROR: mismatched types
 
-    let _ = Checked::<generic>;
+    let _ = Checked::<generic>; //~ ERROR: type annotations needed
     let _ = Checked::<{generic::<u16>}>;
     let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>;
     let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>;
diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs
index 9c5de03170b10..77cce66e4ec6b 100644
--- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs
+++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs
@@ -16,6 +16,7 @@ impl<const N: usize> Example<N> {
     Self {
       a: [0.; N],
       b: [0.; complex_maths(N)],
+      //~^ ERROR: unconstrained generic constant
     }
   }
 }
diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
index 100cf3f8b6299..4a87649f43de9 100644
--- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
@@ -6,5 +6,13 @@ LL |   b: [f32; complex_maths(N)],
    |
    = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
 
-error: aborting due to 1 previous error
+error: unconstrained generic constant
+  --> $DIR/no_where_clause.rs:18:15
+   |
+LL |       b: [0.; complex_maths(N)],
+   |               ^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs
index 24d333aba0fde..1620e257667bb 100644
--- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs
+++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs
@@ -15,7 +15,7 @@ impl Foo for () {
 }
 
 fn use_dyn(v: &dyn Foo) { //~ERROR the trait `Foo` cannot be made into an object
-    v.test();
+    v.test(); //~ERROR the trait `Foo` cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
index 6f0a6b04333e3..31f271cc7ba39 100644
--- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
@@ -16,6 +16,24 @@ LL |     fn test(&self) -> [u8; bar::<Self>()];
    = help: consider moving `test` to another trait
    = help: only type `()` implements the trait, consider using it directly instead
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety-err-ret.rs:18:5
+   |
+LL |     v.test();
+   |     ^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-err-ret.rs:8:8
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn test(&self) -> [u8; bar::<Self>()];
+   |        ^^^^           ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
+   |        |
+   |        ...because method `test` references the `Self` type in its `where` clause
+   = help: consider moving `test` to another trait
+   = help: only type `()` implements the trait, consider using it directly instead
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
index eb71ebb62ebbf..77a7da17c131c 100644
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -34,6 +34,47 @@ LL + #[derive(ConstParamTy)]
 LL | struct Foo(u8);
    |
 
-error: aborting due to 3 previous errors
+error: unconstrained generic constant
+  --> $DIR/unify-op-with-fn-call.rs:30:12
+   |
+LL |     bar2::<{ std::ops::Add::add(N, N) }>();
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:`
+
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/unify-op-with-fn-call.rs:20:39
+   |
+LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
+   |                                       ^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/unify-op-with-fn-call.rs:10:1
+   |
+LL | impl const std::ops::Add for Foo {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const fn `<Foo as Add>::add` in constants
+  --> $DIR/unify-op-with-fn-call.rs:21:13
+   |
+LL |     bar::<{ std::ops::Add::add(N, N) }>();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const fn `<usize as Add>::add` in constants
+  --> $DIR/unify-op-with-fn-call.rs:30:14
+   |
+LL |     bar2::<{ std::ops::Add::add(N, N) }>();
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0741`.
+Some errors have detailed explanations: E0015, E0741.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr
index eb8b9732f58c8..984381d1669ad 100644
--- a/tests/ui/const-generics/issues/issue-62878.min.stderr
+++ b/tests/ui/const-generics/issues/issue-62878.min.stderr
@@ -15,6 +15,16 @@ LL | fn foo<const N: usize, const A: [u8; N]>() {}
    = note: the only supported types are integers, `bool` and `char`
    = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
-error: aborting due to 2 previous errors
+error[E0747]: type provided when a constant was expected
+  --> $DIR/issue-62878.rs:10:11
+   |
+LL |     foo::<_, { [1] }>();
+   |           ^
+   |
+   = help: const arguments cannot yet be inferred with `_`
+   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0770`.
+Some errors have detailed explanations: E0747, E0770.
+For more information about an error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/issues/issue-62878.rs b/tests/ui/const-generics/issues/issue-62878.rs
index 4c08a484ef47b..d226551ef8a97 100644
--- a/tests/ui/const-generics/issues/issue-62878.rs
+++ b/tests/ui/const-generics/issues/issue-62878.rs
@@ -8,4 +8,5 @@ fn foo<const N: usize, const A: [u8; N]>() {}
 
 fn main() {
     foo::<_, { [1] }>();
+    //[min]~^ ERROR: type provided when a constant was expected
 }
diff --git a/tests/ui/const-generics/raw-ptr-const-param.full.stderr b/tests/ui/const-generics/raw-ptr-const-param.full.stderr
index aef95bdaa8809..7ba9ac15bf3ac 100644
--- a/tests/ui/const-generics/raw-ptr-const-param.full.stderr
+++ b/tests/ui/const-generics/raw-ptr-const-param.full.stderr
@@ -4,6 +4,18 @@ error[E0741]: using raw pointers as const generic parameters is forbidden
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/raw-ptr-const-param.rs:9:40
+   |
+LL |     let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>;
+   |            -------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{0xf as *const u32}`, found `{0xa as *const u32}`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `Const<{0xf as *const u32}>`
+              found struct `Const<{0xa as *const u32}>`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0741`.
+Some errors have detailed explanations: E0308, E0741.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/raw-ptr-const-param.min.stderr b/tests/ui/const-generics/raw-ptr-const-param.min.stderr
index 4de98191d5b77..18bbcc33c4df6 100644
--- a/tests/ui/const-generics/raw-ptr-const-param.min.stderr
+++ b/tests/ui/const-generics/raw-ptr-const-param.min.stderr
@@ -6,5 +6,17 @@ LL | struct Const<const P: *const u32>;
    |
    = note: the only supported types are integers, `bool` and `char`
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/raw-ptr-const-param.rs:9:40
+   |
+LL |     let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>;
+   |            -------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{0xf as *const u32}`, found `{0xa as *const u32}`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `Const<{0xf as *const u32}>`
+              found struct `Const<{0xa as *const u32}>`
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/raw-ptr-const-param.rs b/tests/ui/const-generics/raw-ptr-const-param.rs
index 27ef9e7d96c9f..9cc46c769e7c1 100644
--- a/tests/ui/const-generics/raw-ptr-const-param.rs
+++ b/tests/ui/const-generics/raw-ptr-const-param.rs
@@ -7,5 +7,6 @@ struct Const<const P: *const u32>; //~ ERROR: using raw pointers as const generi
 
 fn main() {
     let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>;
+    //~^ ERROR: mismatched types
     let _: Const<{ 10 as *const _ }> = Const::<{ 10 as *const _ }>;
 }
diff --git a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr
index 3c086f59b2788..26f5af6c831c1 100644
--- a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr
+++ b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr
@@ -16,5 +16,39 @@ LL | struct ConstBytes<const T: &'static [u8]>;
    = note: the only supported types are integers, `bool` and `char`
    = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/slice-const-param-mismatch.rs:14:35
+   |
+LL |     let _: ConstString<"Hello"> = ConstString::<"World">;
+   |            --------------------   ^^^^^^^^^^^^^^^^^^^^^^ expected `"Hello"`, found `"World"`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `ConstString<"Hello">`
+              found struct `ConstString<"World">`
+
+error[E0308]: mismatched types
+  --> $DIR/slice-const-param-mismatch.rs:16:33
+   |
+LL |     let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">;
+   |            -------------------   ^^^^^^^^^^^^^^^^^^^^^ expected `"ℇ㇈↦"`, found `"ℇ㇈↥"`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `ConstString<"ℇ㇈↦">`
+              found struct `ConstString<"ℇ㇈↥">`
+
+error[E0308]: mismatched types
+  --> $DIR/slice-const-param-mismatch.rs:18:33
+   |
+LL |     let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">;
+   |            ------------------   ^^^^^^^^^^^^^^^^^^^^ expected `b"AAA"`, found `b"BBB"`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `ConstBytes<b"AAA">`
+              found struct `ConstBytes<b"BBB">`
+
+error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/slice-const-param-mismatch.rs b/tests/ui/const-generics/slice-const-param-mismatch.rs
index 7127323e5babe..24c05d7bea5e1 100644
--- a/tests/ui/const-generics/slice-const-param-mismatch.rs
+++ b/tests/ui/const-generics/slice-const-param-mismatch.rs
@@ -11,9 +11,9 @@ struct ConstBytes<const T: &'static [u8]>;
 
 pub fn main() {
     let _: ConstString<"Hello"> = ConstString::<"Hello">;
-    let _: ConstString<"Hello"> = ConstString::<"World">; //[full]~ ERROR mismatched types
+    let _: ConstString<"Hello"> = ConstString::<"World">; //~ ERROR mismatched types
     let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↦">;
-    let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; //[full]~ ERROR mismatched types
+    let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; //~ ERROR mismatched types
     let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
-    let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">; //[full]~ ERROR mismatched types
+    let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">; //~ ERROR mismatched types
 }
diff --git a/tests/ui/consts/const-unsized.rs b/tests/ui/consts/const-unsized.rs
index e0b06a27109b7..18682aa6eb61f 100644
--- a/tests/ui/consts/const-unsized.rs
+++ b/tests/ui/consts/const-unsized.rs
@@ -18,4 +18,6 @@ static STATIC_BAR: str = *"bar";
 
 fn main() {
     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
+    //~^ ERROR: cannot move a value of type `str`
+    //~| ERROR: cannot move a value of type `dyn Debug + Sync`
 }
diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr
index f70c9b2e0774f..0b69cad96510c 100644
--- a/tests/ui/consts/const-unsized.stderr
+++ b/tests/ui/consts/const-unsized.stderr
@@ -66,6 +66,19 @@ LL | static STATIC_BAR: str = *"bar";
    = help: the trait `Sized` is not implemented for `str`
    = note: constant expressions must have a statically known size
 
-error: aborting due to 8 previous errors
+error[E0161]: cannot move a value of type `str`
+  --> $DIR/const-unsized.rs:20:48
+   |
+LL |     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
+   |                                                ^^^^^^^^^ the size of `str` cannot be statically determined
+
+error[E0161]: cannot move a value of type `dyn Debug + Sync`
+  --> $DIR/const-unsized.rs:20:38
+   |
+LL |     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
+   |                                      ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined
+
+error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0161, E0277.
+For more information about an error, try `rustc --explain E0161`.
diff --git a/tests/ui/consts/is_val_statically_known.rs b/tests/ui/consts/is_val_statically_known.rs
index b0565842eb4e2..7362978301a0d 100644
--- a/tests/ui/consts/is_val_statically_known.rs
+++ b/tests/ui/consts/is_val_statically_known.rs
@@ -1,11 +1,10 @@
 // run-pass
 
-#![feature(core_intrinsics)]
-#![feature(is_val_statically_known)]
+#![feature(core_intrinsics, is_val_statically_known)]
 
 use std::intrinsics::is_val_statically_known;
 
-const CONST_TEST: bool = unsafe { is_val_statically_known(0) };
+const CONST_TEST: bool = is_val_statically_known(0);
 
 fn main() {
     if CONST_TEST {
diff --git a/tests/ui/cross/cross-fn-cache-hole.rs b/tests/ui/cross/cross-fn-cache-hole.rs
index c38a5001ac86d..4aa08ea2e1792 100644
--- a/tests/ui/cross/cross-fn-cache-hole.rs
+++ b/tests/ui/cross/cross-fn-cache-hole.rs
@@ -28,4 +28,5 @@ fn require<A,B>()
 
 fn main() {
     require::<i32, u32>();
+    //~^ ERROR `i32: Bar<u32>` is not satisfied
 }
diff --git a/tests/ui/cross/cross-fn-cache-hole.stderr b/tests/ui/cross/cross-fn-cache-hole.stderr
index ae944387f57a3..dec2f2553c2c2 100644
--- a/tests/ui/cross/cross-fn-cache-hole.stderr
+++ b/tests/ui/cross/cross-fn-cache-hole.stderr
@@ -12,6 +12,25 @@ LL | trait Bar<X> { }
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `i32: Bar<u32>` is not satisfied
+  --> $DIR/cross-fn-cache-hole.rs:30:15
+   |
+LL |     require::<i32, u32>();
+   |               ^^^ the trait `Bar<u32>` is not implemented for `i32`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/cross-fn-cache-hole.rs:11:1
+   |
+LL | trait Bar<X> { }
+   | ^^^^^^^^^^^^
+note: required by a bound in `require`
+  --> $DIR/cross-fn-cache-hole.rs:25:14
+   |
+LL | fn require<A,B>()
+   |    ------- required by a bound in this function
+LL |     where A: Bar<B>
+   |              ^^^^^^ required by this bound in `require`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr
index 3c474d19d1d05..4a119f673c8ee 100644
--- a/tests/ui/did_you_mean/bad-assoc-ty.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr
@@ -182,7 +182,7 @@ LL | type H = Fn(u8) -> (u8)::Output;
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | type H = <dyn Fn(u8) -> (u8)>::Output;
    |          ++++               +
diff --git a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
index 65d44604dc9fc..711bfa188ecd8 100644
--- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #[deny(bare_trait_objects)]
    |        ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
    |                 +++
@@ -24,7 +24,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
    |
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
    |                                   +++
@@ -37,7 +37,7 @@ LL |     let _x: &SomeTrait = todo!();
    |
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _x: &dyn SomeTrait = todo!();
    |              +++
diff --git a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
index 0b194cb8364c6..41298cc73c818 100644
--- a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
+++ b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |         <dyn fmt::Debug>::fmt(self, f)
    |          +++
diff --git a/tests/ui/error-codes/E0038.rs b/tests/ui/error-codes/E0038.rs
index 9757e2ab10c7a..a467767c3faaa 100644
--- a/tests/ui/error-codes/E0038.rs
+++ b/tests/ui/error-codes/E0038.rs
@@ -5,6 +5,8 @@ trait Trait {
 fn call_foo(x: Box<dyn Trait>) {
     //~^ ERROR E0038
     let y = x.foo();
+    //~^ ERROR E0038
+    //~| ERROR E0277
 }
 
 fn main() {
diff --git a/tests/ui/error-codes/E0038.stderr b/tests/ui/error-codes/E0038.stderr
index 99130396e0282..6e8eaab8ddf43 100644
--- a/tests/ui/error-codes/E0038.stderr
+++ b/tests/ui/error-codes/E0038.stderr
@@ -13,6 +13,32 @@ LL |     fn foo(&self) -> Self;
    |                      ^^^^ ...because method `foo` references the `Self` type in its return type
    = help: consider moving `foo` to another trait
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/E0038.rs:7:13
+   |
+LL |     let y = x.foo();
+   |             ^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/E0038.rs:2:22
+   |
+LL | trait Trait {
+   |       ----- this trait cannot be made into an object...
+LL |     fn foo(&self) -> Self;
+   |                      ^^^^ ...because method `foo` references the `Self` type in its return type
+   = help: consider moving `foo` to another trait
+
+error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
+  --> $DIR/E0038.rs:7:9
+   |
+LL |     let y = x.foo();
+   |         ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn Trait`
+   = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0038, E0277.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/error-codes/E0059.rs b/tests/ui/error-codes/E0059.rs
index f775089bfb944..a04cc0cb2b980 100644
--- a/tests/ui/error-codes/E0059.rs
+++ b/tests/ui/error-codes/E0059.rs
@@ -1,6 +1,8 @@
 #![feature(unboxed_closures)]
 
 fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } //~ ERROR E0059
+//~^ ERROR `i32` is not a tuple
+//~| ERROR cannot use call notation
 
 fn main() {
 }
diff --git a/tests/ui/error-codes/E0059.stderr b/tests/ui/error-codes/E0059.stderr
index a7591d2b04bef..d26fadcdbfa77 100644
--- a/tests/ui/error-codes/E0059.stderr
+++ b/tests/ui/error-codes/E0059.stderr
@@ -7,6 +7,19 @@ LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) }
 note: required by a bound in `Fn`
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
-error: aborting due to 1 previous error
+error[E0277]: `i32` is not a tuple
+  --> $DIR/E0059.rs:3:41
+   |
+LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) }
+   |                                         ^^^^ the trait `Tuple` is not implemented for `i32`
+
+error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
+  --> $DIR/E0059.rs:3:41
+   |
+LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) }
+   |                                         ^^^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0059`.
+Some errors have detailed explanations: E0059, E0277.
+For more information about an error, try `rustc --explain E0059`.
diff --git a/tests/ui/error-codes/E0229.rs b/tests/ui/error-codes/E0229.rs
index b7cdb1737b00b..558baae37f767 100644
--- a/tests/ui/error-codes/E0229.rs
+++ b/tests/ui/error-codes/E0229.rs
@@ -15,6 +15,7 @@ fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
 //~| ERROR associated type bindings are not allowed here [E0229]
 //~| ERROR associated type bindings are not allowed here [E0229]
 //~| ERROR the trait bound `I: Foo` is not satisfied
+//~| ERROR the trait bound `I: Foo` is not satisfied
 
 fn main() {
 }
diff --git a/tests/ui/error-codes/E0229.stderr b/tests/ui/error-codes/E0229.stderr
index a7a2904bb898c..bd8e1955ac684 100644
--- a/tests/ui/error-codes/E0229.stderr
+++ b/tests/ui/error-codes/E0229.stderr
@@ -31,7 +31,18 @@ help: consider restricting type parameter `I`
 LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
    |         +++++
 
-error: aborting due to 4 previous errors
+error[E0277]: the trait bound `I: Foo` is not satisfied
+  --> $DIR/E0229.rs:13:37
+   |
+LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
+   |                                     ^^ the trait `Foo` is not implemented for `I`
+   |
+help: consider restricting type parameter `I`
+   |
+LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
+   |         +++++
+
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0229, E0277.
 For more information about an error, try `rustc --explain E0229`.
diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.rs b/tests/ui/extern/issue-36122-accessing-externed-dst.rs
index 5f886ff57379a..9fb7780e3d769 100644
--- a/tests/ui/extern/issue-36122-accessing-externed-dst.rs
+++ b/tests/ui/extern/issue-36122-accessing-externed-dst.rs
@@ -3,4 +3,5 @@ fn main() {
         static symbol: [usize]; //~ ERROR: the size for values of type
     }
     println!("{}", symbol[0]);
+    //~^ ERROR: extern static is unsafe
 }
diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr
index 25348b64002fa..64178e6f84390 100644
--- a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr
+++ b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr
@@ -6,6 +6,15 @@ LL |         static symbol: [usize];
    |
    = help: the trait `Sized` is not implemented for `[usize]`
 
-error: aborting due to 1 previous error
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-36122-accessing-externed-dst.rs:5:20
+   |
+LL |     println!("{}", symbol[0]);
+   |                    ^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0133, E0277.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs
index 712655f9775d6..39f98ac908bda 100644
--- a/tests/ui/feature-gates/feature-gate-abi.rs
+++ b/tests/ui/feature-gates/feature-gate-abi.rs
@@ -14,8 +14,10 @@ trait Tuple { }
 // Functions
 extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
                                    //~^ ERROR intrinsic must be in
+                                   //~| ERROR unrecognized intrinsic function: `f1`
 extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
                                        //~^ ERROR intrinsic must be in
+                                       //~| ERROR unrecognized intrinsic function: `f2`
 extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
 
 // Methods in trait definition
diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr
index d031c2adf50cc..aa60434d9fe6c 100644
--- a/tests/ui/feature-gates/feature-gate-abi.stderr
+++ b/tests/ui/feature-gates/feature-gate-abi.stderr
@@ -8,7 +8,7 @@ LL | extern "rust-intrinsic" fn f1() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:17:8
+  --> $DIR/feature-gate-abi.rs:18:8
    |
 LL | extern "platform-intrinsic" fn f2() {}
    |        ^^^^^^^^^^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL | extern "platform-intrinsic" fn f2() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:19:8
+  --> $DIR/feature-gate-abi.rs:21:8
    |
 LL | extern "rust-call" fn f4(_: ()) {}
    |        ^^^^^^^^^^^
@@ -28,7 +28,7 @@ LL | extern "rust-call" fn f4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:23:12
+  --> $DIR/feature-gate-abi.rs:25:12
    |
 LL |     extern "rust-intrinsic" fn m1();
    |            ^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL |     extern "rust-intrinsic" fn m1();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:25:12
+  --> $DIR/feature-gate-abi.rs:27:12
    |
 LL |     extern "platform-intrinsic" fn m2();
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL |     extern "platform-intrinsic" fn m2();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:27:12
+  --> $DIR/feature-gate-abi.rs:29:12
    |
 LL |     extern "rust-call" fn m4(_: ());
    |            ^^^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     extern "rust-call" fn m4(_: ());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:29:12
+  --> $DIR/feature-gate-abi.rs:31:12
    |
 LL |     extern "rust-call" fn dm4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -67,7 +67,7 @@ LL |     extern "rust-call" fn dm4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:36:12
+  --> $DIR/feature-gate-abi.rs:38:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -76,7 +76,7 @@ LL |     extern "rust-intrinsic" fn m1() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:38:12
+  --> $DIR/feature-gate-abi.rs:40:12
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -86,7 +86,7 @@ LL |     extern "platform-intrinsic" fn m2() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:40:12
+  --> $DIR/feature-gate-abi.rs:42:12
    |
 LL |     extern "rust-call" fn m4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     extern "rust-call" fn m4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:45:12
+  --> $DIR/feature-gate-abi.rs:47:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     extern "rust-intrinsic" fn im1() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:47:12
+  --> $DIR/feature-gate-abi.rs:49:12
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -115,7 +115,7 @@ LL |     extern "platform-intrinsic" fn im2() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:49:12
+  --> $DIR/feature-gate-abi.rs:51:12
    |
 LL |     extern "rust-call" fn im4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     extern "rust-call" fn im4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:53:18
+  --> $DIR/feature-gate-abi.rs:55:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^
@@ -134,7 +134,7 @@ LL | type A1 = extern "rust-intrinsic" fn();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:54:18
+  --> $DIR/feature-gate-abi.rs:56:18
    |
 LL | type A2 = extern "platform-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL | type A2 = extern "platform-intrinsic" fn();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:55:18
+  --> $DIR/feature-gate-abi.rs:57:18
    |
 LL | type A4 = extern "rust-call" fn(_: ());
    |                  ^^^^^^^^^^^
@@ -154,7 +154,7 @@ LL | type A4 = extern "rust-call" fn(_: ());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:58:8
+  --> $DIR/feature-gate-abi.rs:60:8
    |
 LL | extern "rust-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^
@@ -163,7 +163,7 @@ LL | extern "rust-intrinsic" {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:59:8
+  --> $DIR/feature-gate-abi.rs:61:8
    |
 LL | extern "platform-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^^^^^
@@ -173,7 +173,7 @@ LL | extern "platform-intrinsic" {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:60:8
+  --> $DIR/feature-gate-abi.rs:62:8
    |
 LL | extern "rust-call" {}
    |        ^^^^^^^^^^^
@@ -182,14 +182,26 @@ LL | extern "rust-call" {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error[E0093]: unrecognized intrinsic function: `f1`
+  --> $DIR/feature-gate-abi.rs:15:28
+   |
+LL | extern "rust-intrinsic" fn f1() {}
+   |                            ^^ unrecognized intrinsic
+
+error[E0093]: unrecognized intrinsic function: `f2`
+  --> $DIR/feature-gate-abi.rs:18:32
+   |
+LL | extern "platform-intrinsic" fn f2() {}
+   |                                ^^ unrecognized intrinsic
+
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:23:32
+  --> $DIR/feature-gate-abi.rs:25:32
    |
 LL |     extern "rust-intrinsic" fn m1();
    |                                ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:25:36
+  --> $DIR/feature-gate-abi.rs:27:36
    |
 LL |     extern "platform-intrinsic" fn m2();
    |                                    ^^
@@ -201,35 +213,36 @@ LL | extern "rust-intrinsic" fn f1() {}
    |                                 ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:17:37
+  --> $DIR/feature-gate-abi.rs:18:37
    |
 LL | extern "platform-intrinsic" fn f2() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:36:37
+  --> $DIR/feature-gate-abi.rs:38:37
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:38:41
+  --> $DIR/feature-gate-abi.rs:40:41
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |                                         ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:45:38
+  --> $DIR/feature-gate-abi.rs:47:38
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |                                      ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:47:42
+  --> $DIR/feature-gate-abi.rs:49:42
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |                                          ^^
 
-error: aborting due to 27 previous errors
+error: aborting due to 29 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0093, E0658.
+For more information about an error, try `rustc --explain E0093`.
diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.rs b/tests/ui/feature-gates/feature-gate-intrinsics.rs
index e0dc3cc579d79..725d968d24c30 100644
--- a/tests/ui/feature-gates/feature-gate-intrinsics.rs
+++ b/tests/ui/feature-gates/feature-gate-intrinsics.rs
@@ -4,5 +4,6 @@ extern "rust-intrinsic" {   //~ ERROR intrinsics are subject to change
 
 extern "rust-intrinsic" fn baz() {} //~ ERROR intrinsics are subject to change
 //~^ ERROR intrinsic must be in
+//~| ERROR unrecognized intrinsic function: `baz`
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.stderr b/tests/ui/feature-gates/feature-gate-intrinsics.stderr
index ebd0f41715ea6..78c21843adb08 100644
--- a/tests/ui/feature-gates/feature-gate-intrinsics.stderr
+++ b/tests/ui/feature-gates/feature-gate-intrinsics.stderr
@@ -22,13 +22,19 @@ error[E0093]: unrecognized intrinsic function: `bar`
 LL |     fn bar();
    |     ^^^^^^^^^ unrecognized intrinsic
 
+error[E0093]: unrecognized intrinsic function: `baz`
+  --> $DIR/feature-gate-intrinsics.rs:5:28
+   |
+LL | extern "rust-intrinsic" fn baz() {}
+   |                            ^^^ unrecognized intrinsic
+
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
   --> $DIR/feature-gate-intrinsics.rs:5:34
    |
 LL | extern "rust-intrinsic" fn baz() {}
    |                                  ^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0093, E0658.
 For more information about an error, try `rustc --explain E0093`.
diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs
index 2a9a6a8cc6c81..a7489f6fbaff4 100644
--- a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs
+++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs
@@ -18,6 +18,6 @@ where
 fn main() {
     let x = String::from("Hello World!");
     let y = f(&x, ());
-    drop(x);
+    drop(x); //~ ERROR cannot move out of `x`
     println!("{}", y);
 }
diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr
index 4662eb32abb7a..bf6d77b626993 100644
--- a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr
+++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr
@@ -16,6 +16,19 @@ help: consider adding an explicit lifetime bound
 LL | impl<'a, T: 'a> Trait<'a> for T {
    |           ++++
 
-error: aborting due to 1 previous error
+error[E0505]: cannot move out of `x` because it is borrowed
+  --> $DIR/implied-bounds-unnorm-associated-type-5.rs:21:10
+   |
+LL |     let x = String::from("Hello World!");
+   |         - binding `x` declared here
+LL |     let y = f(&x, ());
+   |               -- borrow of `x` occurs here
+LL |     drop(x);
+   |          ^ move out of `x` occurs here
+LL |     println!("{}", y);
+   |                    - borrow later used here
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0309`.
+Some errors have detailed explanations: E0309, E0505.
+For more information about an error, try `rustc --explain E0309`.
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
index e05c83ebc762d..4205c5c5ef779 100644
--- a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
+++ b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
@@ -16,6 +16,43 @@ LL |     type A<'a> where Self: 'a;
              Fooer<T>
              Fooy
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/gat-in-trait-path.rs:32:5
+   |
+LL |   f(Box::new(foo));
+   |     ^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/gat-in-trait-path.rs:10:10
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     type A<'a> where Self: 'a;
+   |          ^ ...because it contains the generic associated type `A`
+   = help: consider moving `A` to another trait
+   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
+             Fooer<T>
+             Fooy
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/gat-in-trait-path.rs:32:5
+   |
+LL |   f(Box::new(foo));
+   |     ^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/gat-in-trait-path.rs:10:10
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     type A<'a> where Self: 'a;
+   |          ^ ...because it contains the generic associated type `A`
+   = help: consider moving `A` to another trait
+   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
+             Fooer<T>
+             Fooy
+   = note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A = &'a ()> + 'static)>`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.rs b/tests/ui/generic-associated-types/gat-in-trait-path.rs
index c55f5a726bdcb..c1ce7d69f10f0 100644
--- a/tests/ui/generic-associated-types/gat-in-trait-path.rs
+++ b/tests/ui/generic-associated-types/gat-in-trait-path.rs
@@ -30,4 +30,6 @@ fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
 fn main() {
   let foo = Fooer(5);
   f(Box::new(foo));
+  //[base]~^ the trait `Foo` cannot be made into an object
+  //[base]~| the trait `Foo` cannot be made into an object
 }
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
index 285493132b64d..671d17f36f13d 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
@@ -9,6 +9,7 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
     //~^ ERROR missing generics for associated type
     //~^^ ERROR missing generics for associated type
     //~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+    //~| ERROR may not live long enough
     t
   }
 }
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
index 74ce93a613cff..8589d008a6b89 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
@@ -51,7 +51,16 @@ LL |   type Y<'a>;
 LL | impl<T> X for T {
    | ^^^^^^^^^^^^^^^ missing `Y` in implementation
 
-error: aborting due to 4 previous errors
+error: lifetime may not live long enough
+  --> $DIR/gat-trait-path-missing-lifetime.rs:8:3
+   |
+LL |   fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+   |   ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |   |      |
+   |   |      lifetime `'a` defined here
+   |   requires that `'a` must outlive `'static`
+
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0046, E0049, E0107.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/generic-associated-types/trait-objects.base.stderr b/tests/ui/generic-associated-types/trait-objects.base.stderr
index e3cfd46524ea9..2b5060289ab2f 100644
--- a/tests/ui/generic-associated-types/trait-objects.base.stderr
+++ b/tests/ui/generic-associated-types/trait-objects.base.stderr
@@ -13,6 +13,36 @@ LL |     type Item<'a> where Self: 'a;
    |          ^^^^ ...because it contains the generic associated type `Item`
    = help: consider moving `Item` to another trait
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `StreamingIterator` cannot be made into an object
+  --> $DIR/trait-objects.rs:15:7
+   |
+LL |     x.size_hint().0
+   |       ^^^^^^^^^ `StreamingIterator` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-objects.rs:7:10
+   |
+LL | trait StreamingIterator {
+   |       ----------------- this trait cannot be made into an object...
+LL |     type Item<'a> where Self: 'a;
+   |          ^^^^ ...because it contains the generic associated type `Item`
+   = help: consider moving `Item` to another trait
+
+error[E0038]: the trait `StreamingIterator` cannot be made into an object
+  --> $DIR/trait-objects.rs:15:5
+   |
+LL |     x.size_hint().0
+   |     ^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-objects.rs:7:10
+   |
+LL | trait StreamingIterator {
+   |       ----------------- this trait cannot be made into an object...
+LL |     type Item<'a> where Self: 'a;
+   |          ^^^^ ...because it contains the generic associated type `Item`
+   = help: consider moving `Item` to another trait
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/trait-objects.rs b/tests/ui/generic-associated-types/trait-objects.rs
index 17fed11bac360..674bee919bfe1 100644
--- a/tests/ui/generic-associated-types/trait-objects.rs
+++ b/tests/ui/generic-associated-types/trait-objects.rs
@@ -14,6 +14,8 @@ fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize
     //[base]~^ the trait `StreamingIterator` cannot be made into an object
     x.size_hint().0
     //[extended]~^ borrowed data escapes
+    //[base]~^^ the trait `StreamingIterator` cannot be made into an object
+    //[base]~| the trait `StreamingIterator` cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
index 84aaedf183815..3cb3af89bfc25 100644
--- a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
+++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
@@ -7,7 +7,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn ice() -> impl AsRef<dyn Fn(&())> {
    |                        +++
diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs
index ab3086c78b3a1..068f7d3eea6da 100644
--- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs
+++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs
@@ -19,6 +19,7 @@ impl NotObjectSafe for B {
 }
 
 fn car() -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be made into an object
+//~^ ERROR return type cannot have an unboxed trait object
     if true {
         return A;
     }
@@ -27,9 +28,9 @@ fn car() -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be ma
 
 fn cat() -> Box<dyn NotObjectSafe> { //~ ERROR the trait `NotObjectSafe` cannot be made into an
     if true {
-        return Box::new(A);
+        return Box::new(A); //~ ERROR cannot be made into an object
     }
-    Box::new(B)
+    Box::new(B) //~ ERROR cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
index 37c96d9bc4e95..fc9c30abf1336 100644
--- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
+++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
@@ -24,7 +24,7 @@ LL |     fn foo() -> Self where Self: Sized;
    |                      +++++++++++++++++
 
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
-  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:17
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:29:17
    |
 LL | fn cat() -> Box<dyn NotObjectSafe> {
    |                 ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
@@ -48,6 +48,79 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
 LL |     fn foo() -> Self where Self: Sized;
    |                      +++++++++++++++++
 
-error: aborting due to 2 previous errors
+error[E0746]: return type cannot have an unboxed trait object
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13
+   |
+LL | fn car() -> dyn NotObjectSafe {
+   |             ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
+   |
+LL | fn car() -> impl NotObjectSafe {
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn car() -> Box<dyn NotObjectSafe> {
+LL |
+LL |     if true {
+LL ~         return Box::new(A);
+LL |     }
+LL ~     Box::new(B)
+   |
+
+error[E0038]: the trait `NotObjectSafe` cannot be made into an object
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:31:16
+   |
+LL |         return Box::new(A);
+   |                ^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8
+   |
+LL | trait NotObjectSafe {
+   |       ------------- this trait cannot be made into an object...
+LL |     fn foo() -> Self;
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead:
+             A
+             B
+   = note: required for the cast from `Box<A>` to `Box<(dyn NotObjectSafe + 'static)>`
+help: consider turning `foo` into a method by giving it a `&self` argument
+   |
+LL |     fn foo(&self) -> Self;
+   |            +++++
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
+   |
+LL |     fn foo() -> Self where Self: Sized;
+   |                      +++++++++++++++++
+
+error[E0038]: the trait `NotObjectSafe` cannot be made into an object
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:33:5
+   |
+LL |     Box::new(B)
+   |     ^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8
+   |
+LL | trait NotObjectSafe {
+   |       ------------- this trait cannot be made into an object...
+LL |     fn foo() -> Self;
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead:
+             A
+             B
+   = note: required for the cast from `Box<B>` to `Box<(dyn NotObjectSafe + 'static)>`
+help: consider turning `foo` into a method by giving it a `&self` argument
+   |
+LL |     fn foo(&self) -> Self;
+   |            +++++
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
+   |
+LL |     fn foo() -> Self where Self: Sized;
+   |                      +++++++++++++++++
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0038, E0746.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
index 27c8f30ec3269..eba4ecd3a28a1 100644
--- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
+++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
@@ -29,16 +29,19 @@ impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
 fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
     //~^ ERROR lifetime mismatch
     sadness.cast()
+    //~^ ERROR may not live long enough
 }
 
 fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
     //~^ ERROR lifetime mismatch
     let _: &'out T = sadness.cast();
+    //~^ ERROR may not live long enough
 }
 
 fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) {
     //~^ ERROR lifetime mismatch
     let _: &'out T = sadness.cast();
+    //~^ ERROR may not live long enough
 }
 
 fn bad<'short, T>(value: &'short T) -> &'static T {
diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
index 0c00bbc380e8a..c9dc820fd60da 100644
--- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
+++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
@@ -8,7 +8,7 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out
    |                             ...but data from `x` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/hrlt-implied-trait-bounds-guard.rs:34:30
+  --> $DIR/hrlt-implied-trait-bounds-guard.rs:35:30
    |
 LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
    |                              ^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
    |                              ...but data with one lifetime flows into the other here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/hrlt-implied-trait-bounds-guard.rs:39:30
+  --> $DIR/hrlt-implied-trait-bounds-guard.rs:41:30
    |
 LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) {
    |                              ^^^^^^^^^^^^^^^^^-------^^-------^^
@@ -25,6 +25,45 @@ LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness:
    |                              |                these two types are declared with different lifetimes...
    |                              ...but data from `a` flows into `a` here
 
-error: aborting due to 3 previous errors
+error: lifetime may not live long enough
+  --> $DIR/hrlt-implied-trait-bounds-guard.rs:31:5
+   |
+LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
+   |           ----  ---- lifetime `'out` defined here
+   |           |
+   |           lifetime `'in_` defined here
+LL |
+LL |     sadness.cast()
+   |     ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'out` but it is returning data with lifetime `'in_`
+   |
+   = help: consider adding the following bound: `'in_: 'out`
+
+error: lifetime may not live long enough
+  --> $DIR/hrlt-implied-trait-bounds-guard.rs:37:12
+   |
+LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
+   |            ----  ---- lifetime `'out` defined here
+   |            |
+   |            lifetime `'in_` defined here
+LL |
+LL |     let _: &'out T = sadness.cast();
+   |            ^^^^^^^ type annotation requires that `'in_` must outlive `'out`
+   |
+   = help: consider adding the following bound: `'in_: 'out`
+
+error: lifetime may not live long enough
+  --> $DIR/hrlt-implied-trait-bounds-guard.rs:43:12
+   |
+LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) {
+   |            ----  ---- lifetime `'out` defined here
+   |            |
+   |            lifetime `'in_` defined here
+LL |
+LL |     let _: &'out T = sadness.cast();
+   |            ^^^^^^^ type annotation requires that `'in_` must outlive `'out`
+   |
+   = help: consider adding the following bound: `'in_: 'out`
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0623`.
diff --git a/tests/ui/inference/issue-107090.rs b/tests/ui/inference/issue-107090.rs
index 799c3641833b6..d1c86fb03d78e 100644
--- a/tests/ui/inference/issue-107090.rs
+++ b/tests/ui/inference/issue-107090.rs
@@ -19,7 +19,7 @@ impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> {
 
 fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T {
     //~^ ERROR use of undeclared lifetime name
-    sadness.cast()
+    sadness.cast() //~ ERROR: mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/inference/issue-107090.stderr b/tests/ui/inference/issue-107090.stderr
index e509e262fb1bd..55825f7765bb4 100644
--- a/tests/ui/inference/issue-107090.stderr
+++ b/tests/ui/inference/issue-107090.stderr
@@ -66,6 +66,19 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short,
    |           |
    |           help: consider introducing lifetime `'short` here: `'short,`
 
-error: aborting due to 6 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-107090.rs:22:5
+   |
+LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T {
+   |                       - expected this type parameter                                    ------- expected `&'out T` because of return type
+LL |
+LL |     sadness.cast()
+   |     ^^^^^^^^^^^^^^ expected `&T`, found `&Foo<'_, '_, T>`
+   |
+   = note: expected reference `&'out T`
+              found reference `&Foo<'_, '_, T>`
+
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0261`.
+Some errors have detailed explanations: E0261, E0308.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/intrinsics-always-extern.rs b/tests/ui/intrinsics-always-extern.rs
index 22951147d7d87..0afd8353455f2 100644
--- a/tests/ui/intrinsics-always-extern.rs
+++ b/tests/ui/intrinsics-always-extern.rs
@@ -10,6 +10,7 @@ impl Foo for () {
 }
 
 extern "rust-intrinsic" fn hello() {//~ ERROR intrinsic must
+    //~^ ERROR unrecognized intrinsic function: `hello`
 }
 
 fn main() {
diff --git a/tests/ui/intrinsics-always-extern.stderr b/tests/ui/intrinsics-always-extern.stderr
index 24b6da16096e6..32468f99197f3 100644
--- a/tests/ui/intrinsics-always-extern.stderr
+++ b/tests/ui/intrinsics-always-extern.stderr
@@ -4,6 +4,12 @@ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
 LL |     extern "rust-intrinsic" fn foo(&self);
    |                                ^^^
 
+error[E0093]: unrecognized intrinsic function: `hello`
+  --> $DIR/intrinsics-always-extern.rs:12:28
+   |
+LL | extern "rust-intrinsic" fn hello() {
+   |                            ^^^^^ unrecognized intrinsic
+
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
   --> $DIR/intrinsics-always-extern.rs:8:43
    |
@@ -17,8 +23,10 @@ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
    |
 LL |   extern "rust-intrinsic" fn hello() {
    |  ____________________________________^
+LL | |
 LL | | }
    | |_^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0093`.
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
index b0688e530ae71..fcd6612f1259d 100644
--- a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
@@ -1,5 +1,6 @@
 #![feature(intrinsics)]
 #![feature(rustc_attrs)]
+#![feature(effects)]
 
 extern "rust-intrinsic" {
     fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch
@@ -10,4 +11,15 @@ extern "rust-intrinsic" {
     //~^ ERROR intrinsic safety mismatch
 }
 
+#[rustc_intrinsic]
+const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+//~^ ERROR intrinsic safety mismatch
+//~| ERROR intrinsic has wrong type
+
+mod foo {
+    #[rustc_intrinsic]
+    unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+    //~^ ERROR wrong number of const parameters
+}
+
 fn main() {}
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
index b6961275e1885..0b579121ac18e 100644
--- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
@@ -1,17 +1,17 @@
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
-  --> $DIR/safe-intrinsic-mismatch.rs:5:5
+  --> $DIR/safe-intrinsic-mismatch.rs:6:5
    |
 LL |     fn size_of<T>() -> usize;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
-  --> $DIR/safe-intrinsic-mismatch.rs:9:5
+  --> $DIR/safe-intrinsic-mismatch.rs:10:5
    |
 LL |     fn assume(b: bool);
    |     ^^^^^^^^^^^^^^^^^^
 
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
-  --> $DIR/safe-intrinsic-mismatch.rs:5:5
+  --> $DIR/safe-intrinsic-mismatch.rs:6:5
    |
 LL |     fn size_of<T>() -> usize;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,12 +19,35 @@ LL |     fn size_of<T>() -> usize;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
-  --> $DIR/safe-intrinsic-mismatch.rs:9:5
+  --> $DIR/safe-intrinsic-mismatch.rs:10:5
    |
 LL |     fn assume(b: bool);
    |     ^^^^^^^^^^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 4 previous errors
+error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate`
+  --> $DIR/safe-intrinsic-mismatch.rs:15:1
+   |
+LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: intrinsic has wrong type
+  --> $DIR/safe-intrinsic-mismatch.rs:15:26
+   |
+LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+   |                          ^ expected unsafe fn, found normal fn
+   |
+   = note: expected signature `unsafe fn(_, _, _)`
+              found signature `fn(_, _, _)`
+
+error[E0094]: intrinsic has wrong number of const parameters: found 0, expected 1
+  --> $DIR/safe-intrinsic-mismatch.rs:21:31
+   |
+LL |     unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
+   |                               ^ expected 1 const parameter
+
+error: aborting due to 7 previous errors
 
+Some errors have detailed explanations: E0094, E0308.
+For more information about an error, try `rustc --explain E0094`.
diff --git a/tests/ui/issues/issue-18611.rs b/tests/ui/issues/issue-18611.rs
index 91a765f34efc3..57da57d83537c 100644
--- a/tests/ui/issues/issue-18611.rs
+++ b/tests/ui/issues/issue-18611.rs
@@ -1,5 +1,6 @@
 fn add_state(op: <isize as HasState>::State) {
 //~^ ERROR `isize: HasState` is not satisfied
+//~| ERROR `isize: HasState` is not satisfied
 }
 
 trait HasState {
diff --git a/tests/ui/issues/issue-18611.stderr b/tests/ui/issues/issue-18611.stderr
index ab2374586e4e5..76848201f7327 100644
--- a/tests/ui/issues/issue-18611.stderr
+++ b/tests/ui/issues/issue-18611.stderr
@@ -5,11 +5,27 @@ LL | fn add_state(op: <isize as HasState>::State) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/issue-18611.rs:5:1
+  --> $DIR/issue-18611.rs:6:1
    |
 LL | trait HasState {
    | ^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `isize: HasState` is not satisfied
+  --> $DIR/issue-18611.rs:1:46
+   |
+LL |   fn add_state(op: <isize as HasState>::State) {
+   |  ______________________________________________^
+LL | |
+LL | |
+LL | | }
+   | |_^ the trait `HasState` is not implemented for `isize`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-18611.rs:6:1
+   |
+LL | trait HasState {
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-18959.rs b/tests/ui/issues/issue-18959.rs
index 4b6f04e251b94..f4cab630f2e95 100644
--- a/tests/ui/issues/issue-18959.rs
+++ b/tests/ui/issues/issue-18959.rs
@@ -11,10 +11,14 @@ impl Foo for Thing {
 fn foo(b: &dyn Bar) {
     //~^ ERROR E0038
     b.foo(&0)
+    //~^ ERROR E0038
 }
 
 fn main() {
     let mut thing = Thing;
     let test: &dyn Bar = &mut thing;
+    //~^ ERROR E0038
+    //~| ERROR E0038
     foo(test);
+    //~^ ERROR E0038
 }
diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/issues/issue-18959.stderr
index 76082dadd374e..83d46f0331ca7 100644
--- a/tests/ui/issues/issue-18959.stderr
+++ b/tests/ui/issues/issue-18959.stderr
@@ -13,6 +13,67 @@ LL | pub trait Bar: Foo { }
    |           --- this trait cannot be made into an object...
    = help: consider moving `foo` to another trait
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/issue-18959.rs:13:5
+   |
+LL |     b.foo(&0)
+   |     ^^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-18959.rs:1:20
+   |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    ^^^ ...because method `foo` has generic type parameters
+LL | pub trait Bar: Foo { }
+   |           --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
+
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/issue-18959.rs:19:15
+   |
+LL |     let test: &dyn Bar = &mut thing;
+   |               ^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-18959.rs:1:20
+   |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    ^^^ ...because method `foo` has generic type parameters
+LL | pub trait Bar: Foo { }
+   |           --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
+
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/issue-18959.rs:19:26
+   |
+LL |     let test: &dyn Bar = &mut thing;
+   |                          ^^^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-18959.rs:1:20
+   |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    ^^^ ...because method `foo` has generic type parameters
+LL | pub trait Bar: Foo { }
+   |           --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
+   = note: required for the cast from `&mut Thing` to `&dyn Bar`
+
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/issue-18959.rs:22:9
+   |
+LL |     foo(test);
+   |         ^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-18959.rs:1:20
+   |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    ^^^ ...because method `foo` has generic type parameters
+LL | pub trait Bar: Foo { }
+   |           --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/issues/issue-20831-debruijn.rs b/tests/ui/issues/issue-20831-debruijn.rs
index 20d980763ea9c..f3286af0ae5e4 100644
--- a/tests/ui/issues/issue-20831-debruijn.rs
+++ b/tests/ui/issues/issue-20831-debruijn.rs
@@ -28,6 +28,8 @@ impl<'a> Publisher<'a> for MyStruct<'a> {
     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
         // Not obvious, but there is an implicit lifetime here -------^
         //~^^ ERROR cannot infer
+        //~| ERROR may not live long enough
+        //~| ERROR may not live long enough
         //
         // The fact that `Publisher` is using an implicit lifetime is
         // what was causing the debruijn accounting to be off, so
diff --git a/tests/ui/issues/issue-20831-debruijn.stderr b/tests/ui/issues/issue-20831-debruijn.stderr
index bd3ff5d59c622..7d1e19b7e4759 100644
--- a/tests/ui/issues/issue-20831-debruijn.stderr
+++ b/tests/ui/issues/issue-20831-debruijn.stderr
@@ -22,6 +22,30 @@ LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher
    = note: expected `<MyStruct<'a> as Publisher<'_>>`
               found `<MyStruct<'_> as Publisher<'_>>`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/issue-20831-debruijn.rs:28:5
+   |
+LL | impl<'a> Publisher<'a> for MyStruct<'a> {
+   |      -- lifetime `'a` defined here
+LL |     type Output = u64;
+LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |                       |
+   |     |                       has type `Box<dyn Subscriber<Input = <MyStruct<'_> as Publisher<'1>>::Output>>`
+   |     requires that `'a` must outlive `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/issue-20831-debruijn.rs:28:5
+   |
+LL | impl<'a> Publisher<'a> for MyStruct<'a> {
+   |      -- lifetime `'a` defined here
+LL |     type Output = u64;
+LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |                       |
+   |     |                       has type `Box<dyn Subscriber<Input = <MyStruct<'_> as Publisher<'1>>::Output>>`
+   |     requires that `'1` must outlive `'a`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/issues/issue-21974.rs b/tests/ui/issues/issue-21974.rs
index f7c659be148db..24e92ce7b9177 100644
--- a/tests/ui/issues/issue-21974.rs
+++ b/tests/ui/issues/issue-21974.rs
@@ -11,7 +11,7 @@ fn foo<'a,'b,T>(x: &'a T, y: &'b T)
     where &'a T : Foo, //~ ERROR type annotations needed
           &'b T : Foo
 {
-    x.foo();
+    x.foo(); //~ ERROR type annotations needed
     y.foo();
 }
 
diff --git a/tests/ui/issues/issue-21974.stderr b/tests/ui/issues/issue-21974.stderr
index 3934846ea0280..cc9164e5621b8 100644
--- a/tests/ui/issues/issue-21974.stderr
+++ b/tests/ui/issues/issue-21974.stderr
@@ -12,6 +12,20 @@ LL |     where &'a T : Foo,
 LL |           &'b T : Foo
    |                   ^^^
 
-error: aborting due to 1 previous error
+error[E0283]: type annotations needed: cannot satisfy `&T: Foo`
+  --> $DIR/issue-21974.rs:14:7
+   |
+LL |     x.foo();
+   |       ^^^
+   |
+note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found
+  --> $DIR/issue-21974.rs:11:19
+   |
+LL |     where &'a T : Foo,
+   |                   ^^^
+LL |           &'b T : Foo
+   |                   ^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/issues/issue-22874.rs b/tests/ui/issues/issue-22874.rs
index 37c6c8143524a..c4500aacb6184 100644
--- a/tests/ui/issues/issue-22874.rs
+++ b/tests/ui/issues/issue-22874.rs
@@ -5,6 +5,7 @@ struct Table {
 
 fn f(table: &Table) -> &[String] {
     &table.rows[0]
+    //~^ ERROR the size for values of type
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-22874.stderr b/tests/ui/issues/issue-22874.stderr
index 717ce72b9c140..29ddf9756ff8f 100644
--- a/tests/ui/issues/issue-22874.stderr
+++ b/tests/ui/issues/issue-22874.stderr
@@ -7,6 +7,15 @@ LL |     rows: [[String]],
    = help: the trait `Sized` is not implemented for `[String]`
    = note: slice and array elements must have `Sized` type
 
-error: aborting due to 1 previous error
+error[E0277]: the size for values of type `[String]` cannot be known at compilation time
+  --> $DIR/issue-22874.rs:7:6
+   |
+LL |     &table.rows[0]
+   |      ^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[String]`, which is required by `[_]: Index<_>`
+   = note: required for `[[String]]` to implement `Index<_>`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-27340.rs b/tests/ui/issues/issue-27340.rs
index aff37d95a3f3e..53ca2bc973ff8 100644
--- a/tests/ui/issues/issue-27340.rs
+++ b/tests/ui/issues/issue-27340.rs
@@ -2,5 +2,6 @@ struct Foo;
 #[derive(Copy, Clone)]
 //~^ ERROR the trait `Copy` cannot be implemented for this type
 struct Bar(Foo);
+//~^ ERROR `Foo: Clone` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/issues/issue-27340.stderr
index 3353b83f4e560..61ae660f4cf70 100644
--- a/tests/ui/issues/issue-27340.stderr
+++ b/tests/ui/issues/issue-27340.stderr
@@ -9,6 +9,25 @@ LL | struct Bar(Foo);
    |
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `Foo: Clone` is not satisfied
+  --> $DIR/issue-27340.rs:4:12
+   |
+LL | #[derive(Copy, Clone)]
+   |                ----- in this derive macro expansion
+LL |
+LL | struct Bar(Foo);
+   |            ^^^ the trait `Clone` is not implemented for `Foo`
+   |
+note: required by a bound in `AssertParamIsClone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider annotating `Foo` with `#[derive(Clone)]`
+   |
+LL + #[derive(Clone)]
+LL | struct Foo;
+   |
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0204`.
+Some errors have detailed explanations: E0204, E0277.
+For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr
index 71d642109ac8c..8b427b692a79c 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -7,7 +7,7 @@ LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
    |                 ++++       +
@@ -35,7 +35,7 @@ LL |     let g = BitXor::bitor;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let g = <dyn BitXor>::bitor;
    |             ++++       +
diff --git a/tests/ui/issues/issue-35570.rs b/tests/ui/issues/issue-35570.rs
index 42bdb423f8f5c..a2b0222d4f395 100644
--- a/tests/ui/issues/issue-35570.rs
+++ b/tests/ui/issues/issue-35570.rs
@@ -7,6 +7,7 @@ trait Trait2<'a> {
 
 fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
     //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
+    //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
     let _e: (usize, usize) = unsafe{mem::transmute(param)};
 }
 
diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/issues/issue-35570.stderr
index f23b55689e3e4..0aa6b5e402e44 100644
--- a/tests/ui/issues/issue-35570.stderr
+++ b/tests/ui/issues/issue-35570.stderr
@@ -10,6 +10,23 @@ help: this trait has no implementations, consider adding one
 LL | trait Trait2<'a> {
    | ^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
+  --> $DIR/issue-35570.rs:8:66
+   |
+LL |   fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
+   |  __________________________________________________________________^
+LL | |
+LL | |
+LL | |     let _e: (usize, usize) = unsafe{mem::transmute(param)};
+LL | | }
+   | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-35570.rs:4:1
+   |
+LL | trait Trait2<'a> {
+   | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-54410.rs b/tests/ui/issues/issue-54410.rs
index e3e8ca985b970..51eea3ad9ac43 100644
--- a/tests/ui/issues/issue-54410.rs
+++ b/tests/ui/issues/issue-54410.rs
@@ -5,4 +5,5 @@ extern "C" {
 
 fn main() {
     println!("{:p}", unsafe { &symbol });
+    //~^ WARN: shared reference of mutable static is discouraged
 }
diff --git a/tests/ui/issues/issue-54410.stderr b/tests/ui/issues/issue-54410.stderr
index 97e5990750e3c..941c1be3eab5f 100644
--- a/tests/ui/issues/issue-54410.stderr
+++ b/tests/ui/issues/issue-54410.stderr
@@ -6,6 +6,21 @@ LL |     pub static mut symbol: [i8];
    |
    = help: the trait `Sized` is not implemented for `[i8]`
 
-error: aborting due to 1 previous error
+warning: shared reference of mutable static is discouraged
+  --> $DIR/issue-54410.rs:7:31
+   |
+LL |     println!("{:p}", unsafe { &symbol });
+   |                               ^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     println!("{:p}", unsafe { addr_of!(symbol) });
+   |                               ~~~~~~~~~~~~~~~~
+
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-58734.stderr b/tests/ui/issues/issue-58734.stderr
index 5ae1ec7cac8f8..71581e96844ee 100644
--- a/tests/ui/issues/issue-58734.stderr
+++ b/tests/ui/issues/issue-58734.stderr
@@ -7,7 +7,7 @@ LL |     Trait::nonexistent(());
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn Trait>::nonexistent(());
    |     ++++      +
diff --git a/tests/ui/issues/issue-7364.rs b/tests/ui/issues/issue-7364.rs
index 79642bd411b38..0608f902fde08 100644
--- a/tests/ui/issues/issue-7364.rs
+++ b/tests/ui/issues/issue-7364.rs
@@ -3,5 +3,6 @@ use std::cell::RefCell;
 // Regression test for issue 7364
 static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
 //~^ ERROR `RefCell<isize>` cannot be shared between threads safely [E0277]
+//~| ERROR cannot call non-const fn
 
 fn main() { }
diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr
index 15cb2d875c13c..3bf59a6d7114b 100644
--- a/tests/ui/issues/issue-7364.stderr
+++ b/tests/ui/issues/issue-7364.stderr
@@ -11,6 +11,16 @@ note: required because it appears within the type `Box<RefCell<isize>>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
    = note: shared static variables must have a type that implements `Sync`
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const fn `Box::<RefCell<isize>>::new` in statics
+  --> $DIR/issue-7364.rs:4:37
+   |
+LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0015, E0277.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/issues/issue-86756.stderr
index bfa7459ab4a39..d0906a6fa74f4 100644
--- a/tests/ui/issues/issue-86756.stderr
+++ b/tests/ui/issues/issue-86756.stderr
@@ -21,7 +21,7 @@ LL |     eq::<dyn, Foo>
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     eq::<dyn, dyn Foo>
    |               +++
diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs
index 1a2ff8c47058e..d2b6e1d8eba66 100644
--- a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs
+++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs
@@ -16,8 +16,7 @@ struct Other {
 
 fn main() {
     unsafe {
-        // FIXME(oli-obk): make this report a transmute error again.
         std::mem::transmute::<Option<()>, Option<&Other>>(None);
-        //^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+        //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
     }
 }
diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr
index d17564a1ecaef..dd5119318ff4b 100644
--- a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr
+++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr
@@ -4,6 +4,16 @@ error[E0412]: cannot find type `Missing` in this scope
 LL |     Missing: Trait,
    |     ^^^^^^^ not found in this scope
 
-error: aborting due to 1 previous error
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/cannot-transmute-unnormalizable-type.rs:19:9
+   |
+LL |         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `Option<()>` (8 bits)
+   = note: target type: `Option<&Other>` (unable to determine layout for `Other` because `<() as Trait>::RefTarget` cannot be normalized)
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0412, E0512.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/ui/lifetimes/issue-95023.rs b/tests/ui/lifetimes/issue-95023.rs
index e35f1a36e2a25..ee39a8c49c054 100644
--- a/tests/ui/lifetimes/issue-95023.rs
+++ b/tests/ui/lifetimes/issue-95023.rs
@@ -9,5 +9,6 @@ impl Fn(&isize) for Error {
     //~^ ERROR associated function in `impl` without body
     //~^^ ERROR method `foo` is not a member of trait `Fn` [E0407]
     //~^^^ ERROR associated type `B` not found for `Self` [E0220]
+    //~| ERROR associated type `B` not found for `Self` [E0220]
 }
 fn main() {}
diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr
index b9c95d3e49a44..0c67d7328f2bc 100644
--- a/tests/ui/lifetimes/issue-95023.stderr
+++ b/tests/ui/lifetimes/issue-95023.stderr
@@ -56,7 +56,15 @@ LL | impl Fn(&isize) for Error {
    |
    = help: implement the missing item: `fn call(&self, _: (&isize,)) -> <Self as FnOnce<(&isize,)>>::Output { todo!() }`
 
-error: aborting due to 7 previous errors
+error[E0220]: associated type `B` not found for `Self`
+  --> $DIR/issue-95023.rs:8:44
+   |
+LL |     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
+   |                                            ^ help: `Self` has the following associated type: `Output`
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0046, E0183, E0220, E0229, E0277, E0407.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr
index c5d72707f80e8..da1d9f248a01f 100644
--- a/tests/ui/lint/bare-trait-objects-path.stderr
+++ b/tests/ui/lint/bare-trait-objects-path.stderr
@@ -7,7 +7,7 @@ LL |     let _: Dyn::Ty;
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: <dyn Dyn>::Ty;
    |            ++++    +
@@ -26,7 +26,7 @@ LL |     Dyn::func();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn Dyn>::func();
    |     ++++    +
@@ -39,7 +39,7 @@ LL |     ::Dyn::func();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn (::Dyn)>::func();
    |     ++++++     ++
@@ -52,7 +52,7 @@ LL |     Dyn::CONST;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn Dyn>::CONST;
    |     ++++    +
diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
index e9b7b248e612f..388dc6160cb95 100644
--- a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
@@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: requested on the command line with `--force-warn bare-trait-objects`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
diff --git a/tests/ui/lint/force-warn/cap-lints-allow.stderr b/tests/ui/lint/force-warn/cap-lints-allow.stderr
index e569b2f9f1ae9..a037fb671af29 100644
--- a/tests/ui/lint/force-warn/cap-lints-allow.stderr
+++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr
@@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: requested on the command line with `--force-warn bare-trait-objects`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
index c971e4d0d4d21..a74cda2239f50 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
@@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
index 97b8694984dd7..c9472a3b9b9d3 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
@@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
index cd030cc1fcd18..558d5cbb53156 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
@@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
diff --git a/tests/ui/nll/normalization-bounds-error.rs b/tests/ui/nll/normalization-bounds-error.rs
index b6cfcd98732b4..e7744b53f75c7 100644
--- a/tests/ui/nll/normalization-bounds-error.rs
+++ b/tests/ui/nll/normalization-bounds-error.rs
@@ -10,6 +10,7 @@ impl<'a, 'd: 'a> Visitor<'d> for &'a () {
 }
 
 fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
-//~^ ERROR
+//~^ ERROR lifetime may not live long enough
+//~| ERROR cannot infer
 
 fn main() {}
diff --git a/tests/ui/nll/normalization-bounds-error.stderr b/tests/ui/nll/normalization-bounds-error.stderr
index c6f3f2fd018f7..d4254881863ff 100644
--- a/tests/ui/nll/normalization-bounds-error.stderr
+++ b/tests/ui/nll/normalization-bounds-error.stderr
@@ -22,6 +22,18 @@ LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
    = note: expected `Visitor<'d>`
               found `Visitor<'_>`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/normalization-bounds-error.rs:12:1
+   |
+LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
+   | ^^^^^^^^^^^^^--^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |            |   |
+   | |            |   lifetime `'a` defined here
+   | |            lifetime `'d` defined here
+   | requires that `'d` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'d: 'a`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
index 7aec3a73fe964..0bc396390d7d2 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
@@ -7,6 +7,35 @@ LL | fn id<F>(f: Copy) -> usize {
    = note: the trait cannot be made into an object because it requires `Self: Sized`
    = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 
-error: aborting due to 1 previous error
+error[E0618]: expected function, found `(dyn Copy + 'static)`
+  --> $DIR/avoid-ice-on-warning-2.rs:11:5
+   |
+LL | fn id<F>(f: Copy) -> usize {
+   |          - `f` has type `(dyn Copy + 'static)`
+...
+LL |     f()
+   |     ^--
+   |     |
+   |     call expression requires function
+
+error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time
+  --> $DIR/avoid-ice-on-warning-2.rs:4:10
+   |
+LL | fn id<F>(f: Copy) -> usize {
+   |          ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)`
+   = help: unsized fn params are gated as an unstable feature
+help: you can use `impl Trait` as the argument type
+   |
+LL | fn id<F>(f: impl Copy) -> usize {
+   |             ++++
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL | fn id<F>(f: &dyn Copy) -> usize {
+   |             ++++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0038, E0277, E0618.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
index 41c09b7df6289..f1f33a6c6d671 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
@@ -7,7 +7,7 @@ LL | fn id<F>(f: Copy) -> usize {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn id<F>(f: dyn Copy) -> usize {
    |             +++
@@ -21,7 +21,7 @@ LL | fn id<F>(f: Copy) -> usize {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn id<F>(f: dyn Copy) -> usize {
    |             +++
@@ -35,6 +35,35 @@ LL | fn id<F>(f: Copy) -> usize {
    = note: the trait cannot be made into an object because it requires `Self: Sized`
    = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 
-error: aborting due to 1 previous error; 2 warnings emitted
+error[E0618]: expected function, found `(dyn Copy + 'static)`
+  --> $DIR/avoid-ice-on-warning-2.rs:11:5
+   |
+LL | fn id<F>(f: Copy) -> usize {
+   |          - `f` has type `(dyn Copy + 'static)`
+...
+LL |     f()
+   |     ^--
+   |     |
+   |     call expression requires function
+
+error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time
+  --> $DIR/avoid-ice-on-warning-2.rs:4:10
+   |
+LL | fn id<F>(f: Copy) -> usize {
+   |          ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)`
+   = help: unsized fn params are gated as an unstable feature
+help: you can use `impl Trait` as the argument type
+   |
+LL | fn id<F>(f: impl Copy) -> usize {
+   |             ++++
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL | fn id<F>(f: &dyn Copy) -> usize {
+   |             ++++
+
+error: aborting due to 3 previous errors; 2 warnings emitted
 
-For more information about this error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0038, E0277, E0618.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.rs b/tests/ui/object-safety/avoid-ice-on-warning-2.rs
index 9a6a4378fa383..eabfd31dda66b 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-2.rs
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.rs
@@ -3,10 +3,12 @@
 //[new] edition:2021
 fn id<F>(f: Copy) -> usize {
 //~^ ERROR the trait `Copy` cannot be made into an object
+//~| ERROR: the size for values of type `(dyn Copy + 'static)`
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     f()
+    //~^ ERROR: expected function, found `(dyn Copy + 'static)`
 }
 fn main() {}
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
index a36e2519c804d..f499e2d946ffe 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
@@ -7,7 +7,7 @@ LL | trait B { fn f(a: A) -> A; }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait B { fn f(a: dyn A) -> A; }
    |                   +++
@@ -20,7 +20,7 @@ LL | trait B { fn f(a: A) -> A; }
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait B { fn f(a: A) -> dyn A; }
    |                         +++
@@ -33,7 +33,7 @@ LL | trait A { fn g(b: B) -> B; }
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait A { fn g(b: dyn B) -> B; }
    |                   +++
@@ -46,7 +46,7 @@ LL | trait A { fn g(b: B) -> B; }
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait A { fn g(b: B) -> dyn B; }
    |                         +++
@@ -60,7 +60,7 @@ LL | trait B { fn f(a: A) -> A; }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait B { fn f(a: dyn A) -> A; }
    |                   +++
@@ -96,7 +96,7 @@ LL | trait A { fn g(b: B) -> B; }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait A { fn g(b: dyn B) -> B; }
    |                   +++
diff --git a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
index 7c7af9682800f..3939c06eabe5b 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
@@ -19,7 +19,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
    |                         +++
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
index 274d5a639a43b..f795e910d2152 100644
--- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
+++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn ord_prefer_dot(s: String) -> dyn Ord {
    |                                 +++
diff --git a/tests/ui/object-safety/issue-102762.rs b/tests/ui/object-safety/issue-102762.rs
index 4f4c3634528a1..ed0bee5d37e77 100644
--- a/tests/ui/object-safety/issue-102762.rs
+++ b/tests/ui/object-safety/issue-102762.rs
@@ -22,5 +22,7 @@ fn fetcher() -> Box<dyn Fetcher> {
 
 pub fn foo() {
     let fetcher = fetcher();
+    //~^ ERROR the trait `Fetcher` cannot be made into an object
     let _ = fetcher.get();
+    //~^ ERROR the trait `Fetcher` cannot be made into an object
 }
diff --git a/tests/ui/object-safety/issue-102762.stderr b/tests/ui/object-safety/issue-102762.stderr
index 2215ec677c57a..e746628aa3774 100644
--- a/tests/ui/object-safety/issue-102762.stderr
+++ b/tests/ui/object-safety/issue-102762.stderr
@@ -15,6 +15,40 @@ LL | pub trait Fetcher: Send + Sync {
 LL |     fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
    |                      ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Fetcher` cannot be made into an object
+  --> $DIR/issue-102762.rs:24:19
+   |
+LL |     fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+   |                      ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self`
+...
+LL |     let fetcher = fetcher();
+   |                   ^^^^^^^^^ `Fetcher` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-102762.rs:10:22
+   |
+LL | pub trait Fetcher: Send + Sync {
+   |           ------- this trait cannot be made into an object...
+LL |     fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+   |                      ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
+
+error[E0038]: the trait `Fetcher` cannot be made into an object
+  --> $DIR/issue-102762.rs:26:13
+   |
+LL |     fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+   |                      ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self`
+...
+LL |     let _ = fetcher.get();
+   |             ^^^^^^^^^^^^^ `Fetcher` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-102762.rs:10:22
+   |
+LL | pub trait Fetcher: Send + Sync {
+   |           ------- this trait cannot be made into an object...
+LL |     fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+   |                      ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-associated-consts.curr.stderr b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr
index 462d3d95f13ee..bd558d36f73fc 100644
--- a/tests/ui/object-safety/object-safety-associated-consts.curr.stderr
+++ b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr
@@ -13,6 +13,22 @@ LL |     const X: usize;
    |           ^ ...because it contains this associated `const`
    = help: consider moving `X` to another trait
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-associated-consts.rs:14:5
+   |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-associated-consts.rs:9:11
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     const X: usize;
+   |           ^ ...because it contains this associated `const`
+   = help: consider moving `X` to another trait
+   = note: required for the cast from `&T` to `&dyn Bar`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-associated-consts.rs b/tests/ui/object-safety/object-safety-associated-consts.rs
index e1a772e5ab2f3..622f3a0f92e7c 100644
--- a/tests/ui/object-safety/object-safety-associated-consts.rs
+++ b/tests/ui/object-safety/object-safety-associated-consts.rs
@@ -12,7 +12,7 @@ trait Bar {
 fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
     //[curr]~^ ERROR E0038
     t
-    //[object_safe_for_dispatch]~^ ERROR E0038
+    //~^ ERROR E0038
 }
 
 fn main() {
diff --git a/tests/ui/object-safety/object-safety-generics.curr.stderr b/tests/ui/object-safety/object-safety-generics.curr.stderr
index 4581037526397..85adeace3c7f0 100644
--- a/tests/ui/object-safety/object-safety-generics.curr.stderr
+++ b/tests/ui/object-safety/object-safety-generics.curr.stderr
@@ -14,7 +14,7 @@ LL |     fn bar<T>(&self, t: T);
    = help: consider moving `bar` to another trait
 
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-generics.rs:24:40
+  --> $DIR/object-safety-generics.rs:25:40
    |
 LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
    |                                        ^^^^^^^ `Bar` cannot be made into an object
@@ -28,6 +28,53 @@ LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
    = help: consider moving `bar` to another trait
 
-error: aborting due to 2 previous errors
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-generics.rs:20:5
+   |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar<T>(&self, t: T);
+   |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
+   = note: required for the cast from `&T` to `&dyn Bar`
+
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-generics.rs:27:10
+   |
+LL |     t as &dyn Bar
+   |          ^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar<T>(&self, t: T);
+   |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
+
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-generics.rs:27:5
+   |
+LL |     t as &dyn Bar
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar<T>(&self, t: T);
+   |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
+   = note: required for the cast from `&T` to `&dyn Bar`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
index b200b64a1f077..498ad0d8a5e01 100644
--- a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -15,7 +15,7 @@ LL |     fn bar<T>(&self, t: T);
    = note: required for the cast from `&T` to `&dyn Bar`
 
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-generics.rs:26:5
+  --> $DIR/object-safety-generics.rs:27:5
    |
 LL |     t as &dyn Bar
    |     ^ `Bar` cannot be made into an object
diff --git a/tests/ui/object-safety/object-safety-generics.rs b/tests/ui/object-safety/object-safety-generics.rs
index 63dcd169925e4..4528b4ea6e0d4 100644
--- a/tests/ui/object-safety/object-safety-generics.rs
+++ b/tests/ui/object-safety/object-safety-generics.rs
@@ -19,12 +19,15 @@ fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
     //[curr]~^ ERROR E0038
     t
     //[object_safe_for_dispatch]~^ ERROR E0038
+    //[curr]~^^ ERROR E0038
 }
 
 fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
     //[curr]~^ ERROR E0038
     t as &dyn Bar
     //[object_safe_for_dispatch]~^ ERROR E0038
+    //[curr]~^^ ERROR E0038
+    //[curr]~| ERROR E0038
 }
 
 fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
diff --git a/tests/ui/object-safety/object-safety-issue-22040.rs b/tests/ui/object-safety/object-safety-issue-22040.rs
index 1fc5c5442c21b..c9ec44cc0b815 100644
--- a/tests/ui/object-safety/object-safety-issue-22040.rs
+++ b/tests/ui/object-safety/object-safety-issue-22040.rs
@@ -36,7 +36,9 @@ impl <'x> Expr for SExpr<'x> {
 
 fn main() {
     let a: Box<dyn Expr> = Box::new(SExpr::new());
+    //~^ ERROR: `Expr` cannot be made into an object
     let b: Box<dyn Expr> = Box::new(SExpr::new());
+    //~^ ERROR: `Expr` cannot be made into an object
 
     // assert_eq!(a , b);
 }
diff --git a/tests/ui/object-safety/object-safety-issue-22040.stderr b/tests/ui/object-safety/object-safety-issue-22040.stderr
index c9c1437a26192..767c232c6ce27 100644
--- a/tests/ui/object-safety/object-safety-issue-22040.stderr
+++ b/tests/ui/object-safety/object-safety-issue-22040.stderr
@@ -13,6 +13,36 @@ LL | trait Expr: Debug + PartialEq {
    |       this trait cannot be made into an object...
    = help: only type `SExpr<'x>` implements the trait, consider using it directly instead
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Expr` cannot be made into an object
+  --> $DIR/object-safety-issue-22040.rs:38:16
+   |
+LL |     let a: Box<dyn Expr> = Box::new(SExpr::new());
+   |                ^^^^^^^^ `Expr` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-issue-22040.rs:5:21
+   |
+LL | trait Expr: Debug + PartialEq {
+   |       ----          ^^^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
+   = help: only type `SExpr<'x>` implements the trait, consider using it directly instead
+
+error[E0038]: the trait `Expr` cannot be made into an object
+  --> $DIR/object-safety-issue-22040.rs:40:16
+   |
+LL |     let b: Box<dyn Expr> = Box::new(SExpr::new());
+   |                ^^^^^^^^ `Expr` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-issue-22040.rs:5:21
+   |
+LL | trait Expr: Debug + PartialEq {
+   |       ----          ^^^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
+   = help: only type `SExpr<'x>` implements the trait, consider using it directly instead
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr
index de430a89bf82b..28c9c9d64a06c 100644
--- a/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr
+++ b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr
@@ -28,6 +28,38 @@ LL |     fn baz(&self) -> Self;
    |                      ^^^^ ...because method `baz` references the `Self` type in its return type
    = help: consider moving `baz` to another trait
 
-error: aborting due to 2 previous errors
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-mentions-Self.rs:24:5
+   |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-mentions-Self.rs:11:22
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar(&self, x: &Self);
+   |                      ^^^^^ ...because method `bar` references the `Self` type in this parameter
+   = help: consider moving `bar` to another trait
+   = note: required for the cast from `&T` to `&dyn Bar`
+
+error[E0038]: the trait `Baz` cannot be made into an object
+  --> $DIR/object-safety-mentions-Self.rs:30:5
+   |
+LL |     t
+   |     ^ `Baz` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-mentions-Self.rs:15:22
+   |
+LL | trait Baz {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> Self;
+   |                      ^^^^ ...because method `baz` references the `Self` type in its return type
+   = help: consider moving `baz` to another trait
+   = note: required for the cast from `&T` to `&dyn Baz`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-mentions-Self.rs b/tests/ui/object-safety/object-safety-mentions-Self.rs
index 412d16ff3c7ce..91582aa6a048e 100644
--- a/tests/ui/object-safety/object-safety-mentions-Self.rs
+++ b/tests/ui/object-safety/object-safety-mentions-Self.rs
@@ -22,13 +22,13 @@ trait Quux {
 fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
     //[curr]~^ ERROR E0038
     t
-    //[object_safe_for_dispatch]~^ ERROR E0038
+    //~^ ERROR E0038
 }
 
 fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
     //[curr]~^ ERROR E0038
     t
-    //[object_safe_for_dispatch]~^ ERROR E0038
+    //~^ ERROR E0038
 }
 
 fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
diff --git a/tests/ui/object-safety/object-safety-no-static.curr.stderr b/tests/ui/object-safety/object-safety-no-static.curr.stderr
index c9e076c65779c..8e5b0cbf9ddcb 100644
--- a/tests/ui/object-safety/object-safety-no-static.curr.stderr
+++ b/tests/ui/object-safety/object-safety-no-static.curr.stderr
@@ -21,6 +21,53 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
 LL |     fn foo() where Self: Sized {}
    |              +++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety-no-static.rs:22:12
+   |
+LL |     let b: Box<dyn Foo> = Box::new(Bar);
+   |            ^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-no-static.rs:9:8
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn foo() {}
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+   = help: only type `Bar` implements the trait, consider using it directly instead
+help: consider turning `foo` into a method by giving it a `&self` argument
+   |
+LL |     fn foo(&self) {}
+   |            +++++
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
+   |
+LL |     fn foo() where Self: Sized {}
+   |              +++++++++++++++++
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety-no-static.rs:22:27
+   |
+LL |     let b: Box<dyn Foo> = Box::new(Bar);
+   |                           ^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-no-static.rs:9:8
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn foo() {}
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+   = help: only type `Bar` implements the trait, consider using it directly instead
+   = note: required for the cast from `Box<Bar>` to `Box<dyn Foo>`
+help: consider turning `foo` into a method by giving it a `&self` argument
+   |
+LL |     fn foo(&self) {}
+   |            +++++
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
+   |
+LL |     fn foo() where Self: Sized {}
+   |              +++++++++++++++++
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-no-static.rs b/tests/ui/object-safety/object-safety-no-static.rs
index 03b6221748388..abfaa11c9e47f 100644
--- a/tests/ui/object-safety/object-safety-no-static.rs
+++ b/tests/ui/object-safety/object-safety-no-static.rs
@@ -20,5 +20,6 @@ impl Foo for Bar {}
 
 fn main() {
     let b: Box<dyn Foo> = Box::new(Bar);
-    //[object_safe_for_dispatch]~^ ERROR E0038
+    //~^ ERROR E0038
+    //[curr]~| ERROR E0038
 }
diff --git a/tests/ui/object-safety/object-safety-sized-2.curr.stderr b/tests/ui/object-safety/object-safety-sized-2.curr.stderr
index 7b91c4d665cfe..03b078c2a44e2 100644
--- a/tests/ui/object-safety/object-safety-sized-2.curr.stderr
+++ b/tests/ui/object-safety/object-safety-sized-2.curr.stderr
@@ -12,6 +12,21 @@ LL | trait Bar
 LL |     where Self : Sized
    |                  ^^^^^ ...because it requires `Self: Sized`
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-sized-2.rs:16:5
+   |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-sized-2.rs:9:18
+   |
+LL | trait Bar
+   |       --- this trait cannot be made into an object...
+LL |     where Self : Sized
+   |                  ^^^^^ ...because it requires `Self: Sized`
+   = note: required for the cast from `&T` to `&dyn Bar`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-sized-2.rs b/tests/ui/object-safety/object-safety-sized-2.rs
index 1e79b8cd917c7..607b7c68f7f38 100644
--- a/tests/ui/object-safety/object-safety-sized-2.rs
+++ b/tests/ui/object-safety/object-safety-sized-2.rs
@@ -14,7 +14,7 @@ trait Bar
 fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
     //[curr]~^ ERROR E0038
     t
-    //[object_safe_for_dispatch]~^ ERROR E0038
+    //~^ ERROR E0038
 }
 
 fn main() {
diff --git a/tests/ui/object-safety/object-safety-sized.curr.stderr b/tests/ui/object-safety/object-safety-sized.curr.stderr
index 66b5239745b6d..0513780a81f1d 100644
--- a/tests/ui/object-safety/object-safety-sized.curr.stderr
+++ b/tests/ui/object-safety/object-safety-sized.curr.stderr
@@ -1,17 +1,32 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-sized.rs:12:31
+  --> $DIR/object-safety-sized.rs:12:32
    |
-LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-   |                               ^^^^^^^ `Bar` cannot be made into an object
+LL | fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
+   |                                ^^^^^^^ `Bar` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety-sized.rs:8:13
+  --> $DIR/object-safety-sized.rs:8:12
    |
-LL | trait Bar : Sized {
-   |       ---   ^^^^^ ...because it requires `Self: Sized`
+LL | trait Bar: Sized {
+   |       ---  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
 
-error: aborting due to 1 previous error
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-sized.rs:14:5
+   |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-sized.rs:8:12
+   |
+LL | trait Bar: Sized {
+   |       ---  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+   = note: required for the cast from `&T` to `&dyn Bar`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
index 1d0ffcffd0459..d988293c0e9a2 100644
--- a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
+++ b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -5,10 +5,10 @@ LL |     t
    |     ^ `Bar` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety-sized.rs:8:13
+  --> $DIR/object-safety-sized.rs:8:12
    |
-LL | trait Bar : Sized {
-   |       ---   ^^^^^ ...because it requires `Self: Sized`
+LL | trait Bar: Sized {
+   |       ---  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
    = note: required for the cast from `&T` to `&dyn Bar`
diff --git a/tests/ui/object-safety/object-safety-sized.rs b/tests/ui/object-safety/object-safety-sized.rs
index b424b892d3b45..ab7aa57611d68 100644
--- a/tests/ui/object-safety/object-safety-sized.rs
+++ b/tests/ui/object-safety/object-safety-sized.rs
@@ -5,15 +5,14 @@
 
 #![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
 
-trait Bar : Sized {
+trait Bar: Sized {
     fn bar<T>(&self, t: T);
 }
 
-fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
     //[curr]~^ ERROR E0038
     t
-    //[object_safe_for_dispatch]~^ ERROR E0038
+    //~^ ERROR E0038
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.rs b/tests/ui/overloaded/overloaded-calls-nontuple.rs
index 32a3b93e0a1e5..aaae39d8506c7 100644
--- a/tests/ui/overloaded/overloaded-calls-nontuple.rs
+++ b/tests/ui/overloaded/overloaded-calls-nontuple.rs
@@ -20,11 +20,12 @@ impl FnOnce<isize> for S {
     type Output = isize;
     extern "rust-call" fn call_once(mut self, z: isize) -> isize {
         //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
-        self.call_mut(z)
+        self.call_mut(z) //~ ERROR `isize` is not a tuple
     }
 }
 
 fn main() {
     let mut s = S { x: 1, y: 2 };
-    drop(s(3))
+    drop(s(3)) //~ ERROR `isize` is not a tuple
+    //~^ ERROR cannot use call notation
 }
diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.stderr b/tests/ui/overloaded/overloaded-calls-nontuple.stderr
index 2e16007825935..45a84fc4d7b0e 100644
--- a/tests/ui/overloaded/overloaded-calls-nontuple.stderr
+++ b/tests/ui/overloaded/overloaded-calls-nontuple.stderr
@@ -28,7 +28,30 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
 LL |     extern "rust-call" fn call_once(mut self, z: isize) -> isize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize`
 
-error: aborting due to 4 previous errors
+error[E0277]: `isize` is not a tuple
+  --> $DIR/overloaded-calls-nontuple.rs:23:23
+   |
+LL |         self.call_mut(z)
+   |              -------- ^ the trait `Tuple` is not implemented for `isize`
+   |              |
+   |              required by a bound introduced by this call
+   |
+note: required by a bound in `call_mut`
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+
+error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
+  --> $DIR/overloaded-calls-nontuple.rs:29:10
+   |
+LL |     drop(s(3))
+   |          ^^^^
+
+error[E0277]: `isize` is not a tuple
+  --> $DIR/overloaded-calls-nontuple.rs:29:10
+   |
+LL |     drop(s(3))
+   |          ^^^^ the trait `Tuple` is not implemented for `isize`
+
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0059, E0277.
 For more information about an error, try `rustc --explain E0059`.
diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr
index 5e07a3fe6c740..3134746b930ac 100644
--- a/tests/ui/parser/trait-object-trait-parens.stderr
+++ b/tests/ui/parser/trait-object-trait-parens.stderr
@@ -25,7 +25,7 @@ LL |     let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    |                +++
@@ -49,7 +49,7 @@ LL |     let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
    |                +++
@@ -73,7 +73,7 @@ LL |     let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
    |                +++
diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs
index f1238ec240f8f..4da9ad84bab71 100644
--- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs
+++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs
@@ -5,9 +5,6 @@ fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
 //~^ ERROR C-variadic type `...` may not be nested inside another type
 
 fn main() {
-    // While this is an error, wf-checks happen before typeck, and if any wf-checks
-    // encountered errors, we do not continue to typeck, even if the items are
-    // unrelated.
-    // FIXME(oli-obk): make this report a type mismatch again.
     let _recovery_witness: () = 0;
+    //~^ ERROR: mismatched types
 }
diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
index 7ca6a6d1bbfea..8b9d676a45dae 100644
--- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
+++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
@@ -10,6 +10,15 @@ error[E0743]: C-variadic type `...` may not be nested inside another type
 LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
    |                             ^^^
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0743`.
+Some errors have detailed explanations: E0308, E0743.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/proc-macro/bad-projection.rs b/tests/ui/proc-macro/bad-projection.rs
index c7cffdc9b4794..c3ac624b6004f 100644
--- a/tests/ui/proc-macro/bad-projection.rs
+++ b/tests/ui/proc-macro/bad-projection.rs
@@ -14,4 +14,5 @@ trait Project {
 pub fn uwu() -> <() as Project>::Assoc {}
 //~^ ERROR the trait bound `(): Project` is not satisfied
 //~| ERROR the trait bound `(): Project` is not satisfied
+//~| ERROR the trait bound `(): Project` is not satisfied
 //~| ERROR function is expected to take 1 argument, but it takes 0 arguments
diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr
index aea5d6d7c8439..8e0d8461849b4 100644
--- a/tests/ui/proc-macro/bad-projection.stderr
+++ b/tests/ui/proc-macro/bad-projection.stderr
@@ -35,7 +35,19 @@ help: this trait has no implementations, consider adding one
 LL | trait Project {
    | ^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `(): Project` is not satisfied
+  --> $DIR/bad-projection.rs:14:40
+   |
+LL | pub fn uwu() -> <() as Project>::Assoc {}
+   |                                        ^^ the trait `Project` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/bad-projection.rs:9:1
+   |
+LL | trait Project {
+   | ^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0593.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs
index a0d619c456644..1e387326b2e6e 100644
--- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs
+++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs
@@ -14,7 +14,9 @@ struct PriorityQueueEntry<T> {
 //~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>`
 //~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied
 //~| ERROR can't compare `T` with `T`
+//~| ERROR `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator
+//~| ERROR no field `height` on type `&PriorityQueue<T>`
 
 struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);
-
+//~^ ERROR can't compare `BinaryHeap<PriorityQueueEntry<T>>` with `_`
 fn main() {}
diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr
index 3b2a5e701886b..6fa639877d3b1 100644
--- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr
+++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr
@@ -34,6 +34,38 @@ note: required by a bound in `Ord`
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    = note: this error originates in the derive macro `AddImpl` which comes from the expansion of the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 3 previous errors
+error[E0277]: can't compare `BinaryHeap<PriorityQueueEntry<T>>` with `_`
+  --> $DIR/issue-104884-trait-impl-sugg-err.rs:20:25
+   |
+LL | #[derive(PartialOrd, AddImpl)]
+   |          ---------- in this derive macro expansion
+...
+LL | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `BinaryHeap<PriorityQueueEntry<T>> < _` and `BinaryHeap<PriorityQueueEntry<T>> > _`
+   |
+   = help: the trait `PartialOrd<_>` is not implemented for `BinaryHeap<PriorityQueueEntry<T>>`
+   = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0599]: `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator
+  --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22
+   |
+LL | #[derive(PartialOrd, AddImpl)]
+   |                      ^^^^^^^ `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator
+   |
+   = note: the following trait bounds were not satisfied:
+           `BinaryHeap<PriorityQueueEntry<T>>: Iterator`
+           which is required by `&mut BinaryHeap<PriorityQueueEntry<T>>: Iterator`
+   = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0609]: no field `height` on type `&PriorityQueue<T>`
+  --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22
+   |
+LL | #[derive(PartialOrd, AddImpl)]
+   |                      ^^^^^^^ unknown field
+   |
+   = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0277, E0599, E0609.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/regions/regions-free-region-ordering-callee-4.rs b/tests/ui/regions/regions-free-region-ordering-callee-4.rs
index de58dd0b10f24..af9f3124cc7a8 100644
--- a/tests/ui/regions/regions-free-region-ordering-callee-4.rs
+++ b/tests/ui/regions/regions-free-region-ordering-callee-4.rs
@@ -6,6 +6,7 @@ fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'
     //~^ ERROR reference has a longer lifetime than the data it references
     // Do not infer ordering from closure argument types.
     let z: Option<&'a &'b usize> = None;
+    //~^ ERROR may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/regions/regions-free-region-ordering-callee-4.stderr b/tests/ui/regions/regions-free-region-ordering-callee-4.stderr
index 1c8f1c1e472f2..e6218079952f7 100644
--- a/tests/ui/regions/regions-free-region-ordering-callee-4.stderr
+++ b/tests/ui/regions/regions-free-region-ordering-callee-4.stderr
@@ -15,6 +15,19 @@ note: but the referenced data is only valid for the lifetime `'b` as defined her
 LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) {
    |                  ^^
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/regions-free-region-ordering-callee-4.rs:8:12
+   |
+LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) {
+   |              --  -- lifetime `'b` defined here
+   |              |
+   |              lifetime `'a` defined here
+...
+LL |     let z: Option<&'a &'b usize> = None;
+   |            ^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
index 429548f119b14..4d77a551f6472 100644
--- a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
+++ b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
@@ -21,6 +21,7 @@ trait Trait2<'a, 'b> {
 fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
     //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
 {
+    //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
 }
 
 fn main() { }
diff --git a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
index 1555e5981c5c7..b17d1e0ab1136 100644
--- a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
+++ b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
@@ -9,6 +9,19 @@ help: consider restricting type parameter `T`
 LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
    |                    ++++++++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
+  --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:23:1
+   |
+LL | / {
+LL | |
+LL | | }
+   | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
+   |                    ++++++++++++++++++++++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/resolve/issue-3907-2.rs b/tests/ui/resolve/issue-3907-2.rs
index 46f145e63e157..0ebaea08e1890 100644
--- a/tests/ui/resolve/issue-3907-2.rs
+++ b/tests/ui/resolve/issue-3907-2.rs
@@ -10,5 +10,6 @@ struct S {
 
 fn bar(_x: Foo) {}
 //~^ ERROR E0038
+//~| ERROR E0277
 
 fn main() {}
diff --git a/tests/ui/resolve/issue-3907-2.stderr b/tests/ui/resolve/issue-3907-2.stderr
index 2693daa3c7a5c..364edb788c68a 100644
--- a/tests/ui/resolve/issue-3907-2.stderr
+++ b/tests/ui/resolve/issue-3907-2.stderr
@@ -10,6 +10,20 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all
 LL |     fn bar();
    |        ^^^ the trait cannot be made into an object because associated function `bar` has no `self` parameter
 
-error: aborting due to 1 previous error
+error[E0277]: the size for values of type `(dyn issue_3907::Foo + 'static)` cannot be known at compilation time
+  --> $DIR/issue-3907-2.rs:11:8
+   |
+LL | fn bar(_x: Foo) {}
+   |        ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn issue_3907::Foo + 'static)`
+   = help: unsized fn params are gated as an unstable feature
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL | fn bar(_x: &Foo) {}
+   |            +
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0038, E0277.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
index 5210a6942010d..e5b9493b3ce11 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
@@ -7,6 +7,16 @@ LL | impl<T: Default> A for T {
 LL | impl<T: Default + ~const Sup> const A for T {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/specializing-constness-2.rs:27:5
+   |
+LL |     <T as A>::a();
+   |     ^^^^^^^^^^^^^ expected `host`, found `true`
+   |
+   = note: expected constant `host`
+              found constant `true`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0308.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
index 4cc69666b8876..bd0519f66c0de 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
@@ -9,6 +9,7 @@ LL |     fn get<R: Deref<Target = Self>>(self: R) -> u32 {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
+ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not?
 error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs
index 883d718c49ba4..27a7df17d666d 100644
--- a/tests/ui/simd/array-trait.rs
+++ b/tests/ui/simd/array-trait.rs
@@ -23,6 +23,7 @@ impl Simd for i32x4 {
 pub struct T<S: Simd>([S::Lane; S::SIZE]);
 //~^ ERROR unconstrained generic constant
 //~| ERROR SIMD vector element type should be a primitive scalar
+//~| ERROR unconstrained generic constant
 
 extern "platform-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
@@ -37,6 +38,7 @@ pub fn main() {
         }
         for i in 0_i32..4 {
             assert_eq!(i, simd_extract(t, i as u32));
+            //~^ ERROR: use of moved value: `t`
         }
     }
 }
diff --git a/tests/ui/simd/array-trait.stderr b/tests/ui/simd/array-trait.stderr
index cf6026912aaed..bbaead569dfc4 100644
--- a/tests/ui/simd/array-trait.stderr
+++ b/tests/ui/simd/array-trait.stderr
@@ -12,6 +12,29 @@ error[E0077]: SIMD vector element type should be a primitive scalar (integer/flo
 LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
    | ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: unconstrained generic constant
+  --> $DIR/array-trait.rs:23:23
+   |
+LL | #[derive(Copy, Clone)]
+   |                ----- in this derive macro expansion
+LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
+   |                       ^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/array-trait.rs:40:40
+   |
+LL |     let mut t = T::<i32x4>([0; 4]);
+   |         ----- move occurs because `t` has type `T<i32x4>`, which does not implement the `Copy` trait
+...
+LL |         for i in 0_i32..4 {
+   |         ----------------- inside of this loop
+LL |             assert_eq!(i, simd_extract(t, i as u32));
+   |                                        ^ value moved here, in previous iteration of loop
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0077`.
+Some errors have detailed explanations: E0077, E0382.
+For more information about an error, try `rustc --explain E0077`.
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
index a0ee771441772..f89a463bc5805 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
@@ -6,6 +6,7 @@
 struct S<const L: usize>;
 
 impl<const N: i32> Copy for S<N> {}
+//~^ ERROR: mismatched types
 impl<const M: usize> Copy for S<M> {}
 //~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>`
 
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
index 2953bc95917c9..1dac58e1f694e 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
@@ -1,11 +1,19 @@
 error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
-  --> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1
    |
 LL | impl<const N: i32> Copy for S<N> {}
    | -------------------------------- first implementation here
+LL |
 LL | impl<const M: usize> Copy for S<M> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31
+   |
+LL | impl<const N: i32> Copy for S<N> {}
+   |                               ^ expected `usize`, found `i32`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0308.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/min_specialization/issue-79224.rs b/tests/ui/specialization/min_specialization/issue-79224.rs
index a118cb28b381a..6ddd3d79ccf75 100644
--- a/tests/ui/specialization/min_specialization/issue-79224.rs
+++ b/tests/ui/specialization/min_specialization/issue-79224.rs
@@ -20,6 +20,7 @@ impl<B: ?Sized> Display for Cow<'_, B> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
         //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+        //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277]
         write!(f, "foo")
     }
 }
diff --git a/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr
index da19ed44ce6f1..db88be88a8128 100644
--- a/tests/ui/specialization/min_specialization/issue-79224.stderr
+++ b/tests/ui/specialization/min_specialization/issue-79224.stderr
@@ -34,6 +34,24 @@ help: consider further restricting this bound
 LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
    |                +++++++++++++++++++
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `B: Clone` is not satisfied
+  --> $DIR/issue-79224.rs:20:62
+   |
+LL |       fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+   |  ______________________________________________________________^
+LL | |
+LL | |
+LL | |
+LL | |         write!(f, "foo")
+LL | |     }
+   | |_____^ the trait `Clone` is not implemented for `B`, which is required by `B: ToOwned`
+   |
+   = note: required for `B` to implement `ToOwned`
+help: consider further restricting this bound
+   |
+LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
+   |                +++++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/suggestions/fn-trait-notation.fixed b/tests/ui/suggestions/fn-trait-notation.fixed
index 6cb97df4a8597..fcf00a17002dd 100644
--- a/tests/ui/suggestions/fn-trait-notation.fixed
+++ b/tests/ui/suggestions/fn-trait-notation.fixed
@@ -7,12 +7,14 @@ where
     H: Fn(i32) -> i32, //~ ERROR E0658
 {
     f(3);
+    //~^ ERROR: cannot use call notation
+    //~| ERROR: `i32` is not a tuple
     g(3, 4);
     h(3)
 }
 
 fn main() {
-    e0658(
+    e0658( //~ ERROR: mismatched types
         |a| a,
         |a, b| (b, a),
         |a| a,
diff --git a/tests/ui/suggestions/fn-trait-notation.rs b/tests/ui/suggestions/fn-trait-notation.rs
index 9125161493011..715bcf71d4720 100644
--- a/tests/ui/suggestions/fn-trait-notation.rs
+++ b/tests/ui/suggestions/fn-trait-notation.rs
@@ -7,12 +7,14 @@ where
     H: Fn<(i32,), Output = i32>, //~ ERROR E0658
 {
     f(3);
+    //~^ ERROR: cannot use call notation
+    //~| ERROR: `i32` is not a tuple
     g(3, 4);
     h(3)
 }
 
 fn main() {
-    e0658(
+    e0658( //~ ERROR: mismatched types
         |a| a,
         |a, b| (b, a),
         |a| a,
diff --git a/tests/ui/suggestions/fn-trait-notation.stderr b/tests/ui/suggestions/fn-trait-notation.stderr
index b221af18bfc34..9b47c8c02a782 100644
--- a/tests/ui/suggestions/fn-trait-notation.stderr
+++ b/tests/ui/suggestions/fn-trait-notation.stderr
@@ -37,7 +37,40 @@ LL |     F: Fn<i32, Output = i32>,
 note: required by a bound in `Fn`
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
-error: aborting due to 4 previous errors
+error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
+  --> $DIR/fn-trait-notation.rs:9:5
+   |
+LL |     f(3);
+   |     ^^^^
+
+error[E0277]: `i32` is not a tuple
+  --> $DIR/fn-trait-notation.rs:9:5
+   |
+LL |     f(3);
+   |     ^^^^ the trait `Tuple` is not implemented for `i32`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-trait-notation.rs:17:5
+   |
+LL | /     e0658(
+LL | |         |a| a,
+LL | |         |a, b| (b, a),
+LL | |         |a| a,
+LL | |     );
+   | |_____^ types differ
+   |
+   = note: expected trait `Fn<i32>`
+              found trait `Fn(_)`
+note: required by a bound in `e0658`
+  --> $DIR/fn-trait-notation.rs:4:8
+   |
+LL | fn e0658<F, G, H>(f: F, g: G, h: H) -> i32
+   |    ----- required by a bound in this function
+LL | where
+LL |     F: Fn<i32, Output = i32>,
+   |        ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `e0658`
+
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0059, E0658.
+Some errors have detailed explanations: E0059, E0277, E0308, E0658.
 For more information about an error, try `rustc --explain E0059`.
diff --git a/tests/ui/suggestions/issue-116434-2015.rs b/tests/ui/suggestions/issue-116434-2015.rs
new file mode 100644
index 0000000000000..614fc27b77187
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2015.rs
@@ -0,0 +1,23 @@
+trait Foo {
+    type Clone;
+    fn foo() -> Clone;
+    //~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| ERROR the trait `Clone` cannot be made into an object [E0038]
+}
+
+trait DbHandle: Sized {}
+
+trait DbInterface {
+    type DbHandle;
+    fn handle() -> DbHandle;
+    //~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| ERROR the trait `DbHandle` cannot be made into an object [E0038]
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr
new file mode 100644
index 0000000000000..2d87029b6eb11
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2015.stderr
@@ -0,0 +1,81 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:3:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
+help: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn foo() -> dyn Clone;
+   |                 +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:15:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn handle() -> dyn DbHandle;
+   |                    +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:3:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn foo() -> dyn Clone;
+   |                 +++
+
+error[E0038]: the trait `Clone` cannot be made into an object
+  --> $DIR/issue-116434-2015.rs:3:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^ `Clone` cannot be made into an object
+   |
+   = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:15:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn handle() -> dyn DbHandle;
+   |                    +++
+
+error[E0038]: the trait `DbHandle` cannot be made into an object
+  --> $DIR/issue-116434-2015.rs:15:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^ `DbHandle` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-116434-2015.rs:11:17
+   |
+LL | trait DbHandle: Sized {}
+   |       --------  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+
+error: aborting due to 2 previous errors; 4 warnings emitted
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/suggestions/issue-116434-2021.rs b/tests/ui/suggestions/issue-116434-2021.rs
new file mode 100644
index 0000000000000..74c30e0cc1fbe
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2021.rs
@@ -0,0 +1,17 @@
+// edition:2021
+
+trait Foo {
+    type Clone;
+    fn foo() -> Clone;
+    //~^ ERROR the trait `Clone` cannot be made into an object [E0038]
+}
+
+trait DbHandle: Sized {}
+
+trait DbInterface {
+    type DbHandle;
+    fn handle() -> DbHandle;
+    //~^ ERROR the trait `DbHandle` cannot be made into an object [E0038]
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-116434-2021.stderr b/tests/ui/suggestions/issue-116434-2021.stderr
new file mode 100644
index 0000000000000..43ad82d484a66
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2021.stderr
@@ -0,0 +1,26 @@
+error[E0038]: the trait `Clone` cannot be made into an object
+  --> $DIR/issue-116434-2021.rs:5:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^ `Clone` cannot be made into an object
+   |
+   = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+error[E0038]: the trait `DbHandle` cannot be made into an object
+  --> $DIR/issue-116434-2021.rs:13:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^ `DbHandle` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-116434-2021.rs:9:17
+   |
+LL | trait DbHandle: Sized {}
+   |       --------  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/suggestions/issue-61963.stderr b/tests/ui/suggestions/issue-61963.stderr
index 754d02b1c021b..084b0cbeef292 100644
--- a/tests/ui/suggestions/issue-61963.stderr
+++ b/tests/ui/suggestions/issue-61963.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     bar: Box<dyn Bar>,
    |              +++
@@ -24,7 +24,7 @@ LL | pub struct Foo {
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | dyn pub struct Foo {
    | +++
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed
index ac0b14fba83b6..269ebd2b75ada 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed
@@ -2,15 +2,17 @@
 use std::fmt::Debug;
 
 #[derive(Debug, Copy, Clone)]
-pub struct Vector2<T: Debug + Copy + Clone>{
+pub struct Vector2<T: Debug + Copy + Clone> {
     pub x: T,
-    pub y: T
+    pub y: T,
 }
 
 #[derive(Debug, Copy, Clone)]
-pub struct AABB<K: Debug + std::marker::Copy>{
+pub struct AABB<K: Debug + std::marker::Copy + std::marker::Copy + std::marker::Copy + std::marker::Copy> {
     pub loc: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied
-    pub size: Vector2<K>
+    //~^ ERROR the trait bound `K: Copy` is not satisfied
+    //~| ERROR the trait bound `K: Copy` is not satisfied
+    pub size: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs
index 31f8cd6fcf79e..e9455f918bca4 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs
@@ -2,15 +2,17 @@
 use std::fmt::Debug;
 
 #[derive(Debug, Copy, Clone)]
-pub struct Vector2<T: Debug + Copy + Clone>{
+pub struct Vector2<T: Debug + Copy + Clone> {
     pub x: T,
-    pub y: T
+    pub y: T,
 }
 
 #[derive(Debug, Copy, Clone)]
-pub struct AABB<K: Debug>{
+pub struct AABB<K: Debug> {
     pub loc: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied
-    pub size: Vector2<K>
+    //~^ ERROR the trait bound `K: Copy` is not satisfied
+    //~| ERROR the trait bound `K: Copy` is not satisfied
+    pub size: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr
index f9db1e1ec008f..a2a78ddc70590 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr
@@ -7,13 +7,80 @@ LL |     pub loc: Vector2<K>,
 note: required by a bound in `Vector2`
   --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:31
    |
-LL | pub struct Vector2<T: Debug + Copy + Clone>{
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
    |                               ^^^^ required by this bound in `Vector2`
 help: consider further restricting this bound
    |
-LL | pub struct AABB<K: Debug + std::marker::Copy>{
+LL | pub struct AABB<K: Debug + std::marker::Copy> {
    |                          +++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl-2.rs:12:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |          ----- in this derive macro expansion
+LL | pub struct AABB<K: Debug> {
+LL |     pub loc: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Debug`
+   |
+note: required for `Vector2<K>` to implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:10
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |          ^^^^^
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
+   |                               ---- unsatisfied trait bound introduced in this `derive` macro
+   = note: required for the cast from `&Vector2<K>` to `&dyn Debug`
+   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider further restricting this bound
+   |
+LL | pub struct AABB<K: Debug + std::marker::Copy> {
+   |                          +++++++++++++++++++
+
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl-2.rs:12:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+LL | pub struct AABB<K: Debug> {
+LL |     pub loc: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone`
+   |
+note: required for `Vector2<K>` to implement `Clone`
+  --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ^^^^^
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
+   |                               ---- unsatisfied trait bound introduced in this `derive` macro
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider further restricting this bound
+   |
+LL | pub struct AABB<K: Debug + std::marker::Copy> {
+   |                          +++++++++++++++++++
+
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl-2.rs:15:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+...
+LL |     pub size: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone`
+   |
+note: required for `Vector2<K>` to implement `Clone`
+  --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ^^^^^
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
+   |                               ---- unsatisfied trait bound introduced in this `derive` macro
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider further restricting this bound
+   |
+LL | pub struct AABB<K: Debug + std::marker::Copy> {
+   |                          +++++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
index 53476ee8c5936..8a91e2d5f0d09 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
@@ -8,9 +8,10 @@ pub struct Vector2<T: Debug + Copy + Clone>{
 }
 
 #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
-pub struct AABB<K: Copy + Debug + std::fmt::Debug>{
+pub struct AABB<K: Copy + Debug + std::fmt::Debug + std::fmt::Debug + std::fmt::Debug>{
     pub loc: Vector2<K>, //~ ERROR `K` doesn't implement `Debug`
-    pub size: Vector2<K>
+    //~^ ERROR `K` doesn't implement `Debug`
+    pub size: Vector2<K> //~ ERROR `K` doesn't implement `Debug`
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
index 08c4f344e4ef0..c10f9d46010a0 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
@@ -10,7 +10,8 @@ pub struct Vector2<T: Debug + Copy + Clone>{
 #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
 pub struct AABB<K: Copy>{
     pub loc: Vector2<K>, //~ ERROR `K` doesn't implement `Debug`
-    pub size: Vector2<K>
+    //~^ ERROR `K` doesn't implement `Debug`
+    pub size: Vector2<K> //~ ERROR `K` doesn't implement `Debug`
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
index bfb96b4076b0f..2ade0e974e495 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
@@ -34,7 +34,37 @@ help: consider further restricting this bound
 LL | pub struct AABB<K: Copy + std::fmt::Debug>{
    |                         +++++++++++++++++
 
-error: aborting due to 2 previous errors
+error[E0277]: `K` doesn't implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+LL | pub struct AABB<K: Copy>{
+LL |     pub loc: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider further restricting this bound
+   |
+LL | pub struct AABB<K: Copy + std::fmt::Debug>{
+   |                         +++++++++++++++++
+
+error[E0277]: `K` doesn't implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl-3.rs:14:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+...
+LL |     pub size: Vector2<K>
+   |     ^^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider further restricting this bound
+   |
+LL | pub struct AABB<K: Copy + std::fmt::Debug>{
+   |                         +++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0204, E0277.
 For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
index 2f1ebc1f133d6..0ffc1b8f7a25e 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
@@ -1,17 +1,22 @@
 use std::fmt::Debug;
 
 #[derive(Debug, Copy, Clone)]
-pub struct Vector2<T: Debug + Copy + Clone>{
+pub struct Vector2<T: Debug + Copy + Clone> {
     pub x: T,
-    pub y: T
+    pub y: T,
 }
 
 #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
-pub struct AABB<K>{
+pub struct AABB<K> {
     pub loc: Vector2<K>,
     //~^ ERROR doesn't implement `Debug`
     //~| ERROR `K: Copy` is not satisfied
-    pub size: Vector2<K>
+    //~| ERROR doesn't implement `Debug`
+    //~| ERROR `K: Copy` is not satisfied
+    //~| ERROR `K: Copy` is not satisfied
+    pub size: Vector2<K>,
+    //~^ ERROR doesn't implement `Debug`
+    //~| ERROR `K: Copy` is not satisfied
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
index f3213e1a4c818..2ae0871b815e4 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
@@ -3,7 +3,7 @@ error[E0204]: the trait `Copy` cannot be implemented for this type
    |
 LL | #[derive(Debug, Copy, Clone)]
    |                 ^^^^
-LL | pub struct AABB<K>{
+LL | pub struct AABB<K> {
 LL |     pub loc: Vector2<K>,
    |     ------------------- this field does not implement `Copy`
    |
@@ -15,7 +15,7 @@ LL |     pub loc: Vector2<K>,
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `K`
    |
-LL | pub struct AABB<K: Debug>{
+LL | pub struct AABB<K: Debug> {
    |                  +++++++
 
 error[E0277]: `K` doesn't implement `Debug`
@@ -27,11 +27,11 @@ LL |     pub loc: Vector2<K>,
 note: required by a bound in `Vector2`
   --> $DIR/missing-bound-in-derive-copy-impl.rs:4:23
    |
-LL | pub struct Vector2<T: Debug + Copy + Clone>{
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
    |                       ^^^^^ required by this bound in `Vector2`
 help: consider restricting type parameter `K`
    |
-LL | pub struct AABB<K: std::fmt::Debug>{
+LL | pub struct AABB<K: std::fmt::Debug> {
    |                  +++++++++++++++++
 
 error[E0277]: the trait bound `K: Copy` is not satisfied
@@ -43,14 +43,111 @@ LL |     pub loc: Vector2<K>,
 note: required by a bound in `Vector2`
   --> $DIR/missing-bound-in-derive-copy-impl.rs:4:31
    |
-LL | pub struct Vector2<T: Debug + Copy + Clone>{
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
    |                               ^^^^ required by this bound in `Vector2`
 help: consider restricting type parameter `K`
    |
-LL | pub struct AABB<K: std::marker::Copy>{
+LL | pub struct AABB<K: std::marker::Copy> {
    |                  +++++++++++++++++++
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:11:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |          ----- in this derive macro expansion
+LL | pub struct AABB<K> {
+LL |     pub loc: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Debug`
+   |
+note: required for `Vector2<K>` to implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:3:10
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |          ^^^^^
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
+   |                               ---- unsatisfied trait bound introduced in this `derive` macro
+   = note: required for the cast from `&Vector2<K>` to `&dyn Debug`
+   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::marker::Copy> {
+   |                  +++++++++++++++++++
+
+error[E0277]: `K` doesn't implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:11:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+LL | pub struct AABB<K> {
+LL |     pub loc: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::fmt::Debug> {
+   |                  +++++++++++++++++
+
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:11:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+LL | pub struct AABB<K> {
+LL |     pub loc: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone`
+   |
+note: required for `Vector2<K>` to implement `Clone`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ^^^^^
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
+   |                               ---- unsatisfied trait bound introduced in this `derive` macro
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::marker::Copy> {
+   |                  +++++++++++++++++++
+
+error[E0277]: `K` doesn't implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:17:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+...
+LL |     pub size: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::fmt::Debug> {
+   |                  +++++++++++++++++
+
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:17:5
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ----- in this derive macro expansion
+...
+LL |     pub size: Vector2<K>,
+   |     ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone`
+   |
+note: required for `Vector2<K>` to implement `Clone`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                       ^^^^^
+LL | pub struct Vector2<T: Debug + Copy + Clone> {
+   |                               ---- unsatisfied trait bound introduced in this `derive` macro
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::marker::Copy> {
+   |                  +++++++++++++++++++
+
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0204, E0277.
 For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/suggestions/object-unsafe-trait-references-self.rs b/tests/ui/suggestions/object-unsafe-trait-references-self.rs
index 07bf053e99665..4b3d5faba4655 100644
--- a/tests/ui/suggestions/object-unsafe-trait-references-self.rs
+++ b/tests/ui/suggestions/object-unsafe-trait-references-self.rs
@@ -1,6 +1,9 @@
 trait Trait {
     fn baz(&self, _: Self) {}
+    //~^ ERROR the size for values of type `Self` cannot be known
     fn bat(&self) -> Self {}
+    //~^ ERROR mismatched types
+    //~| ERROR the size for values of type `Self` cannot be known
 }
 
 fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object
diff --git a/tests/ui/suggestions/object-unsafe-trait-references-self.stderr b/tests/ui/suggestions/object-unsafe-trait-references-self.stderr
index 54f19fe9da445..6427006847115 100644
--- a/tests/ui/suggestions/object-unsafe-trait-references-self.stderr
+++ b/tests/ui/suggestions/object-unsafe-trait-references-self.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/object-unsafe-trait-references-self.rs:6:12
+  --> $DIR/object-unsafe-trait-references-self.rs:9:12
    |
 LL | fn bar(x: &dyn Trait) {}
    |            ^^^^^^^^^ `Trait` cannot be made into an object
@@ -11,25 +11,67 @@ LL | trait Trait {
    |       ----- this trait cannot be made into an object...
 LL |     fn baz(&self, _: Self) {}
    |                      ^^^^ ...because method `baz` references the `Self` type in this parameter
+LL |
 LL |     fn bat(&self) -> Self {}
    |                      ^^^^ ...because method `bat` references the `Self` type in its return type
    = help: consider moving `baz` to another trait
    = help: consider moving `bat` to another trait
 
 error[E0038]: the trait `Other` cannot be made into an object
-  --> $DIR/object-unsafe-trait-references-self.rs:10:12
+  --> $DIR/object-unsafe-trait-references-self.rs:13:12
    |
 LL | fn foo(x: &dyn Other) {}
    |            ^^^^^^^^^ `Other` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-unsafe-trait-references-self.rs:8:14
+  --> $DIR/object-unsafe-trait-references-self.rs:11:14
    |
 LL | trait Other: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
 
-error: aborting due to 2 previous errors
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/object-unsafe-trait-references-self.rs:2:19
+   |
+LL |     fn baz(&self, _: Self) {}
+   |                   ^ doesn't have a size known at compile-time
+   |
+   = help: unsized fn params are gated as an unstable feature
+help: consider further restricting `Self`
+   |
+LL |     fn baz(&self, _: Self) where Self: Sized {}
+   |                            +++++++++++++++++
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |     fn baz(&self, _: &Self) {}
+   |                      +
+
+error[E0308]: mismatched types
+  --> $DIR/object-unsafe-trait-references-self.rs:4:27
+   |
+LL | trait Trait {
+   | ----------- expected this type parameter
+...
+LL |     fn bat(&self) -> Self {}
+   |                           ^^ expected type parameter `Self`, found `()`
+   |
+   = note: expected type parameter `Self`
+                   found unit type `()`
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/object-unsafe-trait-references-self.rs:4:22
+   |
+LL |     fn bat(&self) -> Self {}
+   |                      ^^^^ doesn't have a size known at compile-time
+   |
+   = note: the return type of a function must have a statically known size
+help: consider further restricting `Self`
+   |
+LL |     fn bat(&self) -> Self where Self: Sized {}
+   |                           +++++++++++++++++
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0038, E0277, E0308.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index ffd505fffb48e..0098814f81e78 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -40,7 +40,7 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    |                           +++
diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.rs b/tests/ui/trait-bounds/impl-bound-with-references-error.rs
index e5d0a1aaed049..5ba35da83839e 100644
--- a/tests/ui/trait-bounds/impl-bound-with-references-error.rs
+++ b/tests/ui/trait-bounds/impl-bound-with-references-error.rs
@@ -13,7 +13,7 @@ where
     //~^ ERROR cannot find type `Cow` in this scope [E0412]
 {
     fn from(text: T) -> Self {
-        LabelText::Plain(text.into())
+        LabelText::Plain(text.into()) //~ ERROR expected function, found `LabelText`
     }
 }
 
diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr
index 63280b8616fe5..b3ac5544e38f5 100644
--- a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr
+++ b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr
@@ -21,7 +21,18 @@ LL | |     T: Into<Cow<'static, str>>,
    = note: conflicting implementation in crate `core`:
            - impl<T> From<T> for T;
 
-error: aborting due to 2 previous errors
+error[E0618]: expected function, found `LabelText`
+  --> $DIR/impl-bound-with-references-error.rs:16:9
+   |
+LL |     Plain,
+   |     ----- `LabelText::Plain` defined here
+...
+LL |         LabelText::Plain(text.into())
+   |         ^^^^^^^^^^^^^^^^-------------
+   |         |
+   |         call expression requires function
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0119, E0412.
+Some errors have detailed explanations: E0119, E0412, E0618.
 For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/trait-impl-bound-suggestions.fixed b/tests/ui/trait-impl-bound-suggestions.fixed
index fb11286a175e5..342841b483859 100644
--- a/tests/ui/trait-impl-bound-suggestions.fixed
+++ b/tests/ui/trait-impl-bound-suggestions.fixed
@@ -10,19 +10,21 @@ struct ConstrainedStruct<X: Copy> {
 }
 
 #[allow(dead_code)]
-trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy {
+trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized, X: std::marker::Copy, X: std::marker::Copy {
     fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> {
         //~^ ERROR the trait bound `X: Copy` is not satisfied
         ConstrainedStruct { x }
+        //~^ ERROR the trait bound `X: Copy` is not satisfied
     }
 }
 
 // Regression test for #120838
 #[allow(dead_code)]
-trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where X: std::marker::Copy {
+trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized, X: std::marker::Copy, X: std::marker::Copy {
     fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> {
         //~^ ERROR the trait bound `X: Copy` is not satisfied
         ConstrainedStruct { x }
+        //~^ ERROR the trait bound `X: Copy` is not satisfied
     }
 }
 
diff --git a/tests/ui/trait-impl-bound-suggestions.rs b/tests/ui/trait-impl-bound-suggestions.rs
index 46130a5e76671..9a494402260b0 100644
--- a/tests/ui/trait-impl-bound-suggestions.rs
+++ b/tests/ui/trait-impl-bound-suggestions.rs
@@ -10,19 +10,21 @@ struct ConstrainedStruct<X: Copy> {
 }
 
 #[allow(dead_code)]
-trait InsufficientlyConstrainedGeneric<X=()> {
+trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized {
     fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> {
         //~^ ERROR the trait bound `X: Copy` is not satisfied
         ConstrainedStruct { x }
+        //~^ ERROR the trait bound `X: Copy` is not satisfied
     }
 }
 
 // Regression test for #120838
 #[allow(dead_code)]
-trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where {
+trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized {
     fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> {
         //~^ ERROR the trait bound `X: Copy` is not satisfied
         ConstrainedStruct { x }
+        //~^ ERROR the trait bound `X: Copy` is not satisfied
     }
 }
 
diff --git a/tests/ui/trait-impl-bound-suggestions.stderr b/tests/ui/trait-impl-bound-suggestions.stderr
index 9883c5bda017f..6a75cbdf63974 100644
--- a/tests/ui/trait-impl-bound-suggestions.stderr
+++ b/tests/ui/trait-impl-bound-suggestions.stderr
@@ -11,11 +11,11 @@ LL | struct ConstrainedStruct<X: Copy> {
    |                             ^^^^ required by this bound in `ConstrainedStruct`
 help: consider further restricting type parameter `X`
    |
-LL | trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy {
-   |                                              ++++++++++++++++++++++++++
+LL | trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized, X: std::marker::Copy {
+   |                                                               ++++++++++++++++++++++
 
 error[E0277]: the trait bound `X: Copy` is not satisfied
-  --> $DIR/trait-impl-bound-suggestions.rs:23:52
+  --> $DIR/trait-impl-bound-suggestions.rs:24:52
    |
 LL |     fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> {
    |                                                    ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `X`
@@ -27,9 +27,41 @@ LL | struct ConstrainedStruct<X: Copy> {
    |                             ^^^^ required by this bound in `ConstrainedStruct`
 help: consider further restricting type parameter `X`
    |
-LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where X: std::marker::Copy {
-   |                                                                  ++++++++++++++++++++
+LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized, X: std::marker::Copy {
+   |                                                                             ++++++++++++++++++++++
 
-error: aborting due to 2 previous errors
+error[E0277]: the trait bound `X: Copy` is not satisfied
+  --> $DIR/trait-impl-bound-suggestions.rs:16:29
+   |
+LL |         ConstrainedStruct { x }
+   |                             ^ the trait `Copy` is not implemented for `X`
+   |
+note: required by a bound in `ConstrainedStruct`
+  --> $DIR/trait-impl-bound-suggestions.rs:8:29
+   |
+LL | struct ConstrainedStruct<X: Copy> {
+   |                             ^^^^ required by this bound in `ConstrainedStruct`
+help: consider further restricting type parameter `X`
+   |
+LL | trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized, X: std::marker::Copy {
+   |                                                               ++++++++++++++++++++++
+
+error[E0277]: the trait bound `X: Copy` is not satisfied
+  --> $DIR/trait-impl-bound-suggestions.rs:26:29
+   |
+LL |         ConstrainedStruct { x }
+   |                             ^ the trait `Copy` is not implemented for `X`
+   |
+note: required by a bound in `ConstrainedStruct`
+  --> $DIR/trait-impl-bound-suggestions.rs:8:29
+   |
+LL | struct ConstrainedStruct<X: Copy> {
+   |                             ^^^^ required by this bound in `ConstrainedStruct`
+help: consider further restricting type parameter `X`
+   |
+LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized, X: std::marker::Copy {
+   |                                                                             ++++++++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr
index 6d56851bf3495..f1e7a28654a74 100644
--- a/tests/ui/traits/bound/not-on-bare-trait.stderr
+++ b/tests/ui/traits/bound/not-on-bare-trait.stderr
@@ -7,7 +7,7 @@ LL | fn foo(_x: Foo + Send) {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn foo(_x: dyn Foo + Send) {
    |            +++
diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs
index d38d3c3b28653..8adbac46a5bd8 100644
--- a/tests/ui/traits/issue-106072.rs
+++ b/tests/ui/traits/issue-106072.rs
@@ -1,5 +1,6 @@
 #[derive(Clone)] //~  trait objects must include the `dyn` keyword
 //~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known
+//~| ERROR: return type cannot have an unboxed trait object
 struct Foo;
 trait Foo {} //~ the name `Foo` is defined multiple times
 fn main() {}
diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr
index aadadc45f21cb..6476c8b3237ac 100644
--- a/tests/ui/traits/issue-106072.stderr
+++ b/tests/ui/traits/issue-106072.stderr
@@ -1,5 +1,5 @@
 error[E0428]: the name `Foo` is defined multiple times
-  --> $DIR/issue-106072.rs:4:1
+  --> $DIR/issue-106072.rs:5:1
    |
 LL | struct Foo;
    | ----------- previous definition of the type `Foo` here
@@ -19,6 +19,14 @@ note: required by a bound in `Clone`
   --> $SRC_DIR/core/src/clone.rs:LL:COL
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error[E0746]: return type cannot have an unboxed trait object
+  --> $DIR/issue-106072.rs:1:10
+   |
+LL | #[derive(Clone)]
+   |          ^^^^^ doesn't have a size known at compile-time
+   |
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error[E0782]: trait objects must include the `dyn` keyword
   --> $DIR/issue-106072.rs:1:10
    |
@@ -27,7 +35,7 @@ LL | #[derive(Clone)]
    |
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0277, E0428, E0782.
+Some errors have detailed explanations: E0277, E0428, E0746, E0782.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs
index cc7ea32eb3a5c..ccd35a850f2d7 100644
--- a/tests/ui/traits/issue-50480.rs
+++ b/tests/ui/traits/issue-50480.rs
@@ -6,12 +6,15 @@ struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~| ERROR cannot find type `N` in this scope
 //~| ERROR cannot find type `N` in this scope
 //~| ERROR `i32` is not an iterator
+//~| ERROR `i32` is not an iterator
 
 #[derive(Clone, Copy)]
 //~^ ERROR the trait `Copy` cannot be implemented for this type
+//~| ERROR `i32` is not an iterator
 struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~^ ERROR cannot find type `NotDefined` in this scope
 //~| ERROR cannot find type `N` in this scope
 //~| ERROR `i32` is not an iterator
+//~| ERROR `i32` is not an iterator
 
 fn main() {}
diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr
index 68d3d5c80d0d2..6c019f59b0992 100644
--- a/tests/ui/traits/issue-50480.stderr
+++ b/tests/ui/traits/issue-50480.stderr
@@ -38,7 +38,7 @@ LL | struct Foo<NotDefined>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, St
    |           ++++++++++++
 
 error[E0412]: cannot find type `N` in this scope
-  --> $DIR/issue-50480.rs:12:18
+  --> $DIR/issue-50480.rs:14:18
    |
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |            -     ^
@@ -55,7 +55,7 @@ LL | struct Bar<T, N>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, Strin
    |             +++
 
 error[E0412]: cannot find type `NotDefined` in this scope
-  --> $DIR/issue-50480.rs:12:21
+  --> $DIR/issue-50480.rs:14:21
    |
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |                     ^^^^^^^^^^ not found in this scope
@@ -74,11 +74,11 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0204]: the trait `Copy` cannot be implemented for this type
-  --> $DIR/issue-50480.rs:10:17
+  --> $DIR/issue-50480.rs:11:17
    |
 LL | #[derive(Clone, Copy)]
    |                 ^^^^
-LL |
+...
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |                                                          --------  ------ this field does not implement `Copy`
    |                                                          |
@@ -96,15 +96,47 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
 
 error[E0277]: `i32` is not an iterator
-  --> $DIR/issue-50480.rs:12:33
+  --> $DIR/issue-50480.rs:14:33
+   |
+LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `i32`
+   = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
+
+error[E0277]: `i32` is not an iterator
+  --> $DIR/issue-50480.rs:3:28
+   |
+LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
+   |                            ^^^ `i32` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `i32`
+   = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
+
+error[E0277]: `i32` is not an iterator
+  --> $DIR/issue-50480.rs:11:10
+   |
+LL | #[derive(Clone, Copy)]
+   |          ^^^^^ `i32` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `i32`
+   = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: `i32` is not an iterator
+  --> $DIR/issue-50480.rs:14:33
    |
+LL | #[derive(Clone, Copy)]
+   |          ----- in this derive macro expansion
+...
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `i32`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 10 previous errors
+error: aborting due to 13 previous errors
 
 Some errors have detailed explanations: E0204, E0277, E0412.
 For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/traits/next-solver/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize-param-env-2.stderr
index a52022e539eb7..86729eb8a4b92 100644
--- a/tests/ui/traits/next-solver/normalize-param-env-2.stderr
+++ b/tests/ui/traits/next-solver/normalize-param-env-2.stderr
@@ -30,6 +30,30 @@ LL |         Self::Assoc: A<T>,
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
 
-error: aborting due to 3 previous errors
+error[E0275]: overflow evaluating the requirement `(): A<T>`
+  --> $DIR/normalize-param-env-2.rs:27:10
+   |
+LL |         <() as A<T>>::f();
+   |          ^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
+
+error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
+  --> $DIR/normalize-param-env-2.rs:27:9
+   |
+LL |         <() as A<T>>::f();
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
+note: required by a bound in `A::f`
+  --> $DIR/normalize-param-env-2.rs:14:22
+   |
+LL |     fn f()
+   |        - required by a bound in this associated function
+LL |     where
+LL |         Self::Assoc: A<T>,
+   |                      ^^^^ required by this bound in `A::f`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
index dec820c61b06d..2a017fac10428 100644
--- a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
+++ b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
@@ -14,6 +14,19 @@ LL |     <T as Trait>::Assoc: Trait,
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
 
-error: aborting due to 2 previous errors
+error[E0275]: overflow evaluating the requirement `T: Trait`
+  --> $DIR/normalize-param-env-4.rs:31:19
+   |
+LL |     impls_trait::<T>();
+   |                   ^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
+note: required by a bound in `impls_trait`
+  --> $DIR/normalize-param-env-4.rs:14:19
+   |
+LL | fn impls_trait<T: Trait>() {}
+   |                   ^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs
index d96936f60f7a9..9b35a2677438a 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.rs
+++ b/tests/ui/traits/next-solver/specialization-transmute.rs
@@ -15,7 +15,7 @@ impl<T> Default for T {
     // This will be fixed by #111994
     fn intu(&self) -> &Self::Id {
         //~^ ERROR type annotations needed
-        self
+        self //~ ERROR cannot satisfy
     }
 }
 
@@ -25,6 +25,6 @@ fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
 
 use std::num::NonZeroU8;
 fn main() {
-    let s = transmute::<u8, Option<NonZeroU8>>(0); // this call should then error
+    let s = transmute::<u8, Option<NonZeroU8>>(0); //~ ERROR cannot satisfy
     assert_eq!(s, None);
 }
diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr
index ea1ae387f56a6..c87612d6a26ec 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.stderr
+++ b/tests/ui/traits/next-solver/specialization-transmute.stderr
@@ -16,13 +16,31 @@ error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _`
 LL |     fn intu(&self) -> &Self::Id {
    |                       ^^^^^^^^^ cannot satisfy `<T as Default>::Id == _`
 
+error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id`
+  --> $DIR/specialization-transmute.rs:18:9
+   |
+LL |         self
+   |         ^^^^ cannot satisfy `T <: <T as Default>::Id`
+
+error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
+  --> $DIR/specialization-transmute.rs:28:13
+   |
+LL |     let s = transmute::<u8, Option<NonZeroU8>>(0);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
+   |
+note: required by a bound in `transmute`
+  --> $DIR/specialization-transmute.rs:22:25
+   |
+LL | fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
+   |                         ^^^^^^ required by this bound in `transmute`
+
 error[E0282]: type annotations needed
   --> $DIR/specialization-transmute.rs:14:23
    |
 LL |     default type Id = T;
    |                       ^ cannot infer type for associated type `<T as Default>::Id`
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0282, E0284.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/unspecified-self-in-trait-ref.stderr b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
index b5e8e88676c61..3614348ceedc7 100644
--- a/tests/ui/traits/unspecified-self-in-trait-ref.stderr
+++ b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
@@ -7,7 +7,7 @@ LL |     let a = Foo::lol();
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let a = <dyn Foo>::lol();
    |             ++++    +
@@ -26,7 +26,7 @@ LL |     let b = Foo::<_>::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let b = <dyn Foo::<_>>::lol();
    |             ++++         +
@@ -45,7 +45,7 @@ LL |     let c = Bar::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let c = <dyn Bar>::lol();
    |             ++++    +
@@ -64,7 +64,7 @@ LL |     let d = Bar::<usize, _>::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let d = <dyn Bar::<usize, _>>::lol();
    |             ++++                +
@@ -83,7 +83,7 @@ LL |     let e = Bar::<usize>::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let e = <dyn Bar::<usize>>::lol();
    |             ++++             +
diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs
index 2b966609108bf..f2c2a471f7212 100644
--- a/tests/ui/transmutability/issue-101739-1.rs
+++ b/tests/ui/transmutability/issue-101739-1.rs
@@ -7,6 +7,7 @@ mod assert {
     where
         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
         //~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume`
+        //~| ERROR: mismatched types
     {
     }
 }
diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr
index bf947d0ea4a6c..e87693f247d36 100644
--- a/tests/ui/transmutability/issue-101739-1.stderr
+++ b/tests/ui/transmutability/issue-101739-1.stderr
@@ -13,6 +13,13 @@ LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
 note: required by a bound in `BikeshedIntrinsicFrom`
   --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-101739-1.rs:8:50
+   |
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
+   |                                                  ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0308, E0412.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs
index 4cde9152032c8..8d670ec17ca9a 100644
--- a/tests/ui/transmutability/issue-101739-2.rs
+++ b/tests/ui/transmutability/issue-101739-2.rs
@@ -19,7 +19,7 @@ mod assert {
         //~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
             Src,
             Context,
-            ASSUME_ALIGNMENT,
+            ASSUME_ALIGNMENT, //~ ERROR: mismatched types
             ASSUME_LIFETIMES,
             ASSUME_VALIDITY,
             ASSUME_VISIBILITY,
diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr
index aed47f33f0d96..adbb5ff5aff03 100644
--- a/tests/ui/transmutability/issue-101739-2.stderr
+++ b/tests/ui/transmutability/issue-101739-2.stderr
@@ -25,6 +25,13 @@ LL | |         >,
 note: required by a bound in `BikeshedIntrinsicFrom`
   --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-101739-2.rs:22:13
+   |
+LL |             ASSUME_ALIGNMENT,
+   |             ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.rs b/tests/ui/treat-err-as-bug/eagerly-emit.rs
deleted file mode 100644
index ede190575d529..0000000000000
--- a/tests/ui/treat-err-as-bug/eagerly-emit.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// compile-flags: -Zeagerly-emit-delayed-bugs
-
-trait Foo {}
-
-fn main() {}
-
-fn f() -> impl Foo {
-    //~^ ERROR the trait bound `i32: Foo` is not satisfied
-    1i32
-}
diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.stderr b/tests/ui/treat-err-as-bug/eagerly-emit.stderr
deleted file mode 100644
index 4ae596435aa7f..0000000000000
--- a/tests/ui/treat-err-as-bug/eagerly-emit.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging
-
-error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/eagerly-emit.rs:7:11
-   |
-LL | fn f() -> impl Foo {
-   |           ^^^^^^^^ the trait `Foo` is not implemented for `i32`
-LL |
-LL |     1i32
-   |     ---- return type was inferred to be `i32` here
-   |
-help: this trait has no implementations, consider adding one
-  --> $DIR/eagerly-emit.rs:3:1
-   |
-LL | trait Foo {}
-   | ^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type/type-check/issue-40294.rs b/tests/ui/type/type-check/issue-40294.rs
index 5493a4e5f10a8..46ba22961639d 100644
--- a/tests/ui/type/type-check/issue-40294.rs
+++ b/tests/ui/type/type-check/issue-40294.rs
@@ -6,7 +6,7 @@ fn foo<'a,'b,T>(x: &'a T, y: &'b T)
     where &'a T : Foo, //~ ERROR type annotations needed
           &'b T : Foo
 {
-    x.foo();
+    x.foo(); //~ ERROR type annotations needed
     y.foo();
 }
 
diff --git a/tests/ui/type/type-check/issue-40294.stderr b/tests/ui/type/type-check/issue-40294.stderr
index c6c1d6893243e..178ea69563a0a 100644
--- a/tests/ui/type/type-check/issue-40294.stderr
+++ b/tests/ui/type/type-check/issue-40294.stderr
@@ -12,6 +12,20 @@ LL |     where &'a T : Foo,
 LL |           &'b T : Foo
    |                   ^^^
 
-error: aborting due to 1 previous error
+error[E0283]: type annotations needed: cannot satisfy `&T: Foo`
+  --> $DIR/issue-40294.rs:9:7
+   |
+LL |     x.foo();
+   |       ^^^
+   |
+note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found
+  --> $DIR/issue-40294.rs:6:19
+   |
+LL |     where &'a T : Foo,
+   |                   ^^^
+LL |           &'b T : Foo
+   |                   ^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index 591a7278ddcf6..a95b44e807c5d 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -47,7 +47,7 @@ impl Test9 {
 
 fn test11(x: &usize) -> &_ {
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
-    &x
+    &x //~ ERROR cannot return reference to function parameter
 }
 
 unsafe fn test12(x: *const usize) -> *const *const _ {
@@ -229,3 +229,5 @@ fn evens_squared(n: usize) -> _ {
 
 const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
 //~^ ERROR the placeholder
+//~| ERROR cannot call non-const
+//~| ERROR cannot call non-const
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index bfcc76c1dae7d..18f6edad5c094 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -666,7 +666,31 @@ LL |     type F: std::ops::Fn(_);
 LL | impl Qux for Struct {
    | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
 
-error: aborting due to 72 previous errors
+error[E0515]: cannot return reference to function parameter `x`
+  --> $DIR/typeck_type_placeholder_item.rs:50:5
+   |
+LL |     &x
+   |     ^^ returns a reference to data owned by the current function
+
+error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:230:22
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |                      ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const fn `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:230:49: 230:52}>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:230:45
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |                                             ^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 75 previous errors
 
-Some errors have detailed explanations: E0046, E0121, E0282, E0403.
-For more information about an error, try `rustc --explain E0046`.
+Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403, E0515.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.rs b/tests/ui/ufcs/ufcs-explicit-self-bad.rs
index 3bb3d906d110b..29586dccfc950 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.rs
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.rs
@@ -7,7 +7,7 @@ struct Foo {
 impl Foo {
     fn foo(self: isize, x: isize) -> isize {
         //~^ ERROR invalid `self` parameter type
-        self.f + x
+        self.f + x //~ ERROR: doesn't have fields
     }
 }
 
@@ -53,8 +53,10 @@ fn main() {
         f: 1,
     });
     println!("{}", foo.foo(2));
+    //~^ ERROR: no method named `foo`
     let bar = Box::new(Bar {
         f: 1,
     });
     println!("{} {}", bar.foo(2), bar.bar(2));
+    //~^ ERROR: no method named `bar`
 }
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
index b0e71507a2e7d..7c2507754751f 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -118,7 +118,25 @@ note: ...does not necessarily outlive the anonymous lifetime defined here
 LL |     fn dummy3(self: &&Bar<T>) {}
    |                      ^^^^^^^
 
-error: aborting due to 8 previous errors
+error[E0610]: `isize` is a primitive type and therefore doesn't have fields
+  --> $DIR/ufcs-explicit-self-bad.rs:10:14
+   |
+LL |         self.f + x
+   |              ^
+
+error[E0599]: no method named `foo` found for struct `Box<Foo>` in the current scope
+  --> $DIR/ufcs-explicit-self-bad.rs:55:24
+   |
+LL |     println!("{}", foo.foo(2));
+   |                        ^^^ method not found in `Box<Foo>`
+
+error[E0599]: no method named `bar` found for struct `Box<Bar<isize>>` in the current scope
+  --> $DIR/ufcs-explicit-self-bad.rs:60:39
+   |
+LL |     println!("{} {}", bar.foo(2), bar.bar(2));
+   |                                       ^^^ method not found in `Box<Bar<isize>>`
+
+error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0053, E0307, E0308.
+Some errors have detailed explanations: E0053, E0307, E0308, E0599, E0610.
 For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs
index d2e486002272c..2278285bf8f15 100644
--- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs
+++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs
@@ -4,5 +4,5 @@ fn a<F: Fn<usize>>(f: F) {}
 //~^ ERROR type parameter to bare `Fn` trait must be a tuple
 
 fn main() {
-    a(|_: usize| {});
+    a(|_: usize| {}); //~ ERROR: mismatched types
 }
diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
index 66d393c67c543..0d4265ddf8bd9 100644
--- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
+++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
@@ -7,6 +7,21 @@ LL | fn a<F: Fn<usize>>(f: F) {}
 note: required by a bound in `Fn`
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/non-tupled-arg-mismatch.rs:7:5
+   |
+LL |     a(|_: usize| {});
+   |     ^^^^^^^^^^^^^^^^ types differ
+   |
+   = note: expected trait `Fn<usize>`
+              found trait `Fn(usize)`
+note: required by a bound in `a`
+  --> $DIR/non-tupled-arg-mismatch.rs:3:9
+   |
+LL | fn a<F: Fn<usize>>(f: F) {}
+   |         ^^^^^^^^^ required by this bound in `a`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0059`.
+Some errors have detailed explanations: E0059, E0308.
+For more information about an error, try `rustc --explain E0059`.
diff --git a/tests/ui/wf/wf-in-fn-ret.rs b/tests/ui/wf/wf-in-fn-ret.rs
index 4c9535184ff9a..3e9b9787cc577 100644
--- a/tests/ui/wf/wf-in-fn-ret.rs
+++ b/tests/ui/wf/wf-in-fn-ret.rs
@@ -3,12 +3,13 @@
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
 
-struct MustBeCopy<T:Copy> {
-    t: T
+struct MustBeCopy<T: Copy> {
+    t: T,
 }
 
 fn bar<T>() -> MustBeCopy<T> //~ ERROR E0277
+//~^ ERROR mismatched types
 {
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/wf/wf-in-fn-ret.stderr b/tests/ui/wf/wf-in-fn-ret.stderr
index 85cf78c598790..1ae49a348cc69 100644
--- a/tests/ui/wf/wf-in-fn-ret.stderr
+++ b/tests/ui/wf/wf-in-fn-ret.stderr
@@ -5,15 +5,27 @@ LL | fn bar<T>() -> MustBeCopy<T>
    |                ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
 note: required by a bound in `MustBeCopy`
-  --> $DIR/wf-in-fn-ret.rs:6:21
+  --> $DIR/wf-in-fn-ret.rs:6:22
    |
-LL | struct MustBeCopy<T:Copy> {
-   |                     ^^^^ required by this bound in `MustBeCopy`
+LL | struct MustBeCopy<T: Copy> {
+   |                      ^^^^ required by this bound in `MustBeCopy`
 help: consider restricting type parameter `T`
    |
 LL | fn bar<T: std::marker::Copy>() -> MustBeCopy<T>
    |         +++++++++++++++++++
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/wf-in-fn-ret.rs:10:16
+   |
+LL | fn bar<T>() -> MustBeCopy<T>
+   |    ---         ^^^^^^^^^^^^^ expected `MustBeCopy<T>`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note: expected struct `MustBeCopy<T>`
+           found unit type `()`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.