about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs26
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs121
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs83
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs207
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs5
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp13
-rw-r--r--compiler/rustc_metadata/Cargo.toml1
-rw-r--r--compiler/rustc_metadata/src/creader.rs4
-rw-r--r--compiler/rustc_metadata/src/locator.rs29
-rw-r--r--compiler/rustc_session/src/config.rs14
-rw-r--r--compiler/rustc_session/src/options.rs5
-rw-r--r--library/core/src/mem/mod.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs1
-rw-r--r--src/doc/rustc/src/instrument-coverage.md8
-rw-r--r--src/doc/style-guide/src/editions.md5
-rw-r--r--src/doc/style-guide/src/expressions.md12
-rw-r--r--src/doc/unstable-book/src/compiler-flags/profile.md27
-rw-r--r--src/etc/rust_analyzer_settings.json2
-rw-r--r--src/librustdoc/clean/types.rs7
-rw-r--r--src/librustdoc/html/format.rs6
-rw-r--r--src/librustdoc/html/render/print_item.rs2
-rw-r--r--src/librustdoc/html/render/type_layout.rs2
-rw-r--r--src/librustdoc/json/conversions.rs22
-rw-r--r--src/tools/rust-analyzer/Cargo.lock7
-rw-r--r--src/tools/rust-analyzer/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs17
-rw-r--r--src/tools/tidy/src/deps.rs3
-rw-r--r--tests/run-make/profile/rmake.rs21
-rw-r--r--tests/run-make/profile/test.rs1
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr8
-rw-r--r--tests/ui/lint/invalid-nan-comparison-suggestion.fixed14
-rw-r--r--tests/ui/lint/invalid-nan-comparison-suggestion.rs14
-rw-r--r--tests/ui/lint/invalid-nan-comparison-suggestion.stderr70
-rw-r--r--tests/ui/lint/invalid-nan-comparison.rs46
-rw-r--r--tests/ui/lint/invalid-nan-comparison.stderr180
-rw-r--r--tests/ui/never_type/defaulted-never-note.nofallback.stderr4
-rw-r--r--tests/ui/never_type/dependency-on-fallback-to-unit.stderr8
-rw-r--r--tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr8
-rw-r--r--tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr4
-rw-r--r--tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr4
-rw-r--r--tests/ui/never_type/fallback-closure-ret.nofallback.stderr4
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr32
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr32
55 files changed, 818 insertions, 345 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0f65cc696ab..9fa1daf6546 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4006,7 +4006,6 @@ dependencies = [
  "rustc_span",
  "rustc_target",
  "rustc_type_ir",
- "snap",
  "tempfile",
  "tracing",
 ]
@@ -4892,12 +4891,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 
 [[package]]
-name = "snap"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
-
-[[package]]
 name = "socket2"
 version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 2c5ec9dad59..64bb22e8cb2 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -232,11 +232,6 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
         return None;
     }
 
-    // probestack doesn't play nice either with gcov profiling.
-    if cx.sess().opts.unstable_opts.profile {
-        return None;
-    }
-
     let attr_value = match cx.sess().target.stack_probes {
         StackProbeType::None => return None,
         // Request LLVM to generate the probes inline. If the given LLVM version does not support
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index bfa9e8b82a0..cf7b16c9cc4 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -591,7 +591,6 @@ pub(crate) unsafe fn llvm_optimize(
             pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
             config.instrument_coverage,
             instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
-            config.instrument_gcov,
             pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
             config.debug_info_for_profiling,
             llvm_selfprofiler,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 9064cfaeb29..0d1fd0163eb 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -7,7 +7,6 @@ use std::{iter, ptr};
 use libc::{c_char, c_longlong, c_uint};
 use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo};
 use rustc_codegen_ssa::traits::*;
-use rustc_fs_util::path_to_c_string;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::bug;
@@ -979,33 +978,8 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
             debug_name_table_kind,
         );
 
-        if tcx.sess.opts.unstable_opts.profile {
-            let default_gcda_path = &output_filenames.with_extension("gcda");
-            let gcda_path =
-                tcx.sess.opts.unstable_opts.profile_emit.as_ref().unwrap_or(default_gcda_path);
-
-            let gcov_cu_info = [
-                path_to_mdstring(debug_context.llcontext, &output_filenames.with_extension("gcno")),
-                path_to_mdstring(debug_context.llcontext, gcda_path),
-                unit_metadata,
-            ];
-            let gcov_metadata = llvm::LLVMMDNodeInContext2(
-                debug_context.llcontext,
-                gcov_cu_info.as_ptr(),
-                gcov_cu_info.len(),
-            );
-            let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata);
-
-            llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val);
-        }
-
         return unit_metadata;
     };
-
-    fn path_to_mdstring<'ll>(llcx: &'ll llvm::Context, path: &Path) -> &'ll llvm::Metadata {
-        let path_str = path_to_c_string(path);
-        unsafe { llvm::LLVMMDStringInContext2(llcx, path_str.as_ptr(), path_str.as_bytes().len()) }
-    }
 }
 
 /// Creates a `DW_TAG_member` entry inside the DIE represented by the given `type_di_node`.
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 72e723aa849..b6c20cdcf0c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -55,7 +55,6 @@ const DW_TAG_arg_variable: c_uint = 0x101;
 
 /// A context object for maintaining all state needed by the debuginfo module.
 pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
-    llcontext: &'ll llvm::Context,
     llmod: &'ll llvm::Module,
     builder: &'ll mut DIBuilder<'ll>,
     created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,
@@ -78,9 +77,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
         debug!("CodegenUnitDebugContext::new");
         let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
         // DIBuilder inherits context from the module, so we'd better use the same one
-        let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
         CodegenUnitDebugContext {
-            llcontext,
             llmod,
             builder,
             created_files: Default::default(),
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 8fc586d2c8f..5fad7583e1a 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2269,7 +2269,6 @@ unsafe extern "C" {
         PGOUsePath: *const c_char,
         InstrumentCoverage: bool,
         InstrProfileOutput: *const c_char,
-        InstrumentGCOV: bool,
         PGOSampleUsePath: *const c_char,
         DebugInfoForProfiling: bool,
         llvm_selfprofiler: *mut c_void,
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 8445d16befb..d977cca247e 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -90,7 +90,6 @@ pub struct ModuleConfig {
     pub pgo_sample_use: Option<PathBuf>,
     pub debug_info_for_profiling: bool,
     pub instrument_coverage: bool,
-    pub instrument_gcov: bool,
 
     pub sanitizer: SanitizerSet,
     pub sanitizer_recover: SanitizerSet,
@@ -123,12 +122,7 @@ pub struct ModuleConfig {
 }
 
 impl ModuleConfig {
-    fn new(
-        kind: ModuleKind,
-        tcx: TyCtxt<'_>,
-        no_builtins: bool,
-        is_compiler_builtins: bool,
-    ) -> ModuleConfig {
+    fn new(kind: ModuleKind, tcx: TyCtxt<'_>, no_builtins: bool) -> ModuleConfig {
         // If it's a regular module, use `$regular`, otherwise use `$other`.
         // `$regular` and `$other` are evaluated lazily.
         macro_rules! if_regular {
@@ -189,13 +183,6 @@ impl ModuleConfig {
             pgo_sample_use: if_regular!(sess.opts.unstable_opts.profile_sample_use.clone(), None),
             debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling,
             instrument_coverage: if_regular!(sess.instrument_coverage(), false),
-            instrument_gcov: if_regular!(
-                // compiler_builtins overrides the codegen-units settings,
-                // which is incompatible with -Zprofile which requires that
-                // only a single codegen unit is used per crate.
-                sess.opts.unstable_opts.profile && !is_compiler_builtins,
-                false
-            ),
 
             sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()),
             sanitizer_dataflow_abilist: if_regular!(
@@ -473,16 +460,12 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
 
     let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
     let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins);
-    let is_compiler_builtins = attr::contains_name(crate_attrs, sym::compiler_builtins);
 
     let crate_info = CrateInfo::new(tcx, target_cpu);
 
-    let regular_config =
-        ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins);
-    let metadata_config =
-        ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins);
-    let allocator_config =
-        ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins);
+    let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins);
+    let metadata_config = ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins);
+    let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins);
 
     let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
     let (codegen_worker_send, codegen_worker_receive) = channel();
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index da779a16569..0b81f469371 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -43,7 +43,7 @@ fn associated_type_bounds<'tcx>(
     match filter {
         PredicateFilter::All
         | PredicateFilter::SelfOnly
-        | PredicateFilter::SelfThatDefines(_)
+        | PredicateFilter::SelfTraitThatDefines(_)
         | PredicateFilter::SelfAndAssociatedTypeBounds => {
             icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
         }
@@ -122,7 +122,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
                     PredicateFilter::SelfOnly => {
                         return None;
                     }
-                    PredicateFilter::SelfThatDefines(_)
+                    PredicateFilter::SelfTraitThatDefines(_)
                     | PredicateFilter::SelfConstIfConst
                     | PredicateFilter::SelfAndAssociatedTypeBounds
                     | PredicateFilter::ConstIfConst => {
@@ -329,7 +329,7 @@ fn opaque_type_bounds<'tcx>(
         match filter {
             PredicateFilter::All
             | PredicateFilter::SelfOnly
-            | PredicateFilter::SelfThatDefines(_)
+            | PredicateFilter::SelfTraitThatDefines(_)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
                 // Associated types are implicitly sized unless a `?Sized` bound is found
                 icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index efe84e0006f..7ce12d48160 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -557,7 +557,11 @@ pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     (trait_def_id, assoc_name): (DefId, Ident),
 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
-    implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name))
+    implied_predicates_with_filter(
+        tcx,
+        trait_def_id,
+        PredicateFilter::SelfTraitThatDefines(assoc_name),
+    )
 }
 
 pub(super) fn explicit_implied_predicates_of<'tcx>(
@@ -586,7 +590,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     let Some(trait_def_id) = trait_def_id.as_local() else {
         // if `assoc_name` is None, then the query should've been redirected to an
         // external provider
-        assert_matches!(filter, PredicateFilter::SelfThatDefines(_));
+        assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_));
         return tcx.explicit_super_predicates_of(trait_def_id);
     };
 
@@ -606,12 +610,8 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     let mut bounds = Bounds::default();
     icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
 
-    let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(
-        generics,
-        item.owner_id.def_id,
-        self_param_ty,
-        filter,
-    );
+    let where_bounds_that_match =
+        icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);
 
     // Combine the two lists to form the complete set of superbounds:
     let implied_bounds =
@@ -652,7 +652,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
 }
 
 // Make sure when elaborating supertraits, probing for associated types, etc.,
-// we really truly are elaborating clauses that have `Self` as their self type.
+// we really truly are elaborating clauses that have `ty` as their self type.
 // This is very important since downstream code relies on this being correct.
 pub(super) fn assert_only_contains_predicates_from<'tcx>(
     filter: PredicateFilter,
@@ -664,7 +664,7 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
     }
 
     match filter {
-        PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
+        PredicateFilter::SelfOnly => {
             for (clause, _) in bounds {
                 match clause.kind().skip_binder() {
                     ty::ClauseKind::Trait(trait_predicate) => {
@@ -704,6 +704,33 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
                 }
             }
         }
+        PredicateFilter::SelfTraitThatDefines(_) => {
+            for (clause, _) in bounds {
+                match clause.kind().skip_binder() {
+                    ty::ClauseKind::Trait(trait_predicate) => {
+                        assert_eq!(
+                            trait_predicate.self_ty(),
+                            ty,
+                            "expected `Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+
+                    ty::ClauseKind::Projection(_)
+                    | ty::ClauseKind::TypeOutlives(_)
+                    | ty::ClauseKind::RegionOutlives(_)
+                    | ty::ClauseKind::ConstArgHasType(_, _)
+                    | ty::ClauseKind::WellFormed(_)
+                    | ty::ClauseKind::ConstEvaluatable(_)
+                    | ty::ClauseKind::HostEffect(..) => {
+                        bug!(
+                            "unexpected non-`Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                }
+            }
+        }
         PredicateFilter::ConstIfConst => {
             for (clause, _) in bounds {
                 match clause.kind().skip_binder() {
@@ -767,21 +794,16 @@ pub(super) fn type_param_predicates<'tcx>(
         None => {}
     }
 
-    use rustc_hir::*;
-    use rustc_middle::ty::Ty;
-
     // In the HIR, bounds can derive from two places. Either
     // written inline like `<T: Foo>` or in a where-clause like
     // `where T: Foo`.
 
     let param_id = tcx.local_def_id_to_hir_id(def_id);
     let param_owner = tcx.hir().ty_param_owner(def_id);
-    let generics = tcx.generics_of(param_owner);
-    let index = generics.param_def_id_to_index[&def_id.to_def_id()];
-    let ty = Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id));
 
     // Don't look for bounds where the type parameter isn't in scope.
     let parent = if item_def_id == param_owner {
+        // FIXME: Shouldn't this be unreachable?
         None
     } else {
         tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local())
@@ -801,8 +823,9 @@ pub(super) fn type_param_predicates<'tcx>(
     let Some(hir_generics) = hir_node.generics() else {
         return result;
     };
+
     if let Node::Item(item) = hir_node
-        && let ItemKind::Trait(..) = item.kind
+        && let hir::ItemKind::Trait(..) = item.kind
         // Implied `Self: Trait` and supertrait bounds.
         && param_id == item_hir_id
     {
@@ -811,23 +834,34 @@ pub(super) fn type_param_predicates<'tcx>(
     }
 
     let icx = ItemCtxt::new(tcx, item_def_id);
-    let extra_predicates = extend.into_iter().chain(
-        icx.probe_ty_param_bounds_in_generics(
-            hir_generics,
-            def_id,
-            ty,
-            PredicateFilter::SelfThatDefines(assoc_name),
-        )
-        .into_iter()
-        .filter(|(predicate, _)| match predicate.kind().skip_binder() {
-            ty::ClauseKind::Trait(data) => data.self_ty().is_param(index),
-            _ => false,
-        }),
+    let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics(
+        hir_generics,
+        def_id,
+        PredicateFilter::SelfTraitThatDefines(assoc_name),
+    ));
+
+    let bounds =
+        &*tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates));
+
+    // Double check that the bounds *only* contain `SelfTy: Trait` preds.
+    let self_ty = match tcx.def_kind(def_id) {
+        DefKind::TyParam => Ty::new_param(
+            tcx,
+            tcx.generics_of(item_def_id)
+                .param_def_id_to_index(tcx, def_id.to_def_id())
+                .expect("expected generic param to be owned by item"),
+            tcx.item_name(def_id.to_def_id()),
+        ),
+        DefKind::Trait | DefKind::TraitAlias => tcx.types.self_param,
+        _ => unreachable!(),
+    };
+    assert_only_contains_predicates_from(
+        PredicateFilter::SelfTraitThatDefines(assoc_name),
+        bounds,
+        self_ty,
     );
 
-    ty::EarlyBinder::bind(
-        tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)),
-    )
+    ty::EarlyBinder::bind(bounds)
 }
 
 impl<'tcx> ItemCtxt<'tcx> {
@@ -841,7 +875,6 @@ impl<'tcx> ItemCtxt<'tcx> {
         &self,
         hir_generics: &'tcx hir::Generics<'tcx>,
         param_def_id: LocalDefId,
-        ty: Ty<'tcx>,
         filter: PredicateFilter,
     ) -> Vec<(ty::Clause<'tcx>, Span)> {
         let mut bounds = Bounds::default();
@@ -851,13 +884,21 @@ impl<'tcx> ItemCtxt<'tcx> {
                 continue;
             };
 
-            let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
-                ty
-            } else if matches!(filter, PredicateFilter::All) {
-                self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty)
-            } else {
-                continue;
-            };
+            match filter {
+                _ if predicate.is_param_bound(param_def_id.to_def_id()) => {
+                    // Ok
+                }
+                PredicateFilter::All => {
+                    // Ok
+                }
+                PredicateFilter::SelfOnly
+                | PredicateFilter::SelfTraitThatDefines(_)
+                | PredicateFilter::SelfConstIfConst
+                | PredicateFilter::SelfAndAssociatedTypeBounds => continue,
+                PredicateFilter::ConstIfConst => unreachable!(),
+            }
+
+            let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
 
             let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
             self.lowerer().lower_bounds(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 8cc475b536d..85ba88333f9 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -152,9 +152,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         'tcx: 'hir,
     {
         for hir_bound in hir_bounds {
-            // In order to avoid cycles, when we're lowering `SelfThatDefines`,
+            // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`,
             // we skip over any traits that don't define the given associated type.
-            if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter {
+            if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter {
                 if let Some(trait_ref) = hir_bound.trait_ref()
                     && let Some(trait_did) = trait_ref.trait_def_id()
                     && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
@@ -389,7 +389,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 match predicate_filter {
                     PredicateFilter::All
                     | PredicateFilter::SelfOnly
-                    | PredicateFilter::SelfThatDefines(_)
                     | PredicateFilter::SelfAndAssociatedTypeBounds => {
                         bounds.push_projection_bound(
                             tcx,
@@ -400,6 +399,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             constraint.span,
                         );
                     }
+                    // SelfTraitThatDefines is only interested in trait predicates.
+                    PredicateFilter::SelfTraitThatDefines(_) => {}
                     // `ConstIfConst` is only interested in `~const` bounds.
                     PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
                 }
@@ -426,7 +427,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         );
                     }
                     PredicateFilter::SelfOnly
-                    | PredicateFilter::SelfThatDefines(_)
+                    | PredicateFilter::SelfTraitThatDefines(_)
                     | PredicateFilter::SelfConstIfConst => {}
                 }
             }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 848813ffcb8..fb23ad1b248 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -76,7 +76,7 @@ pub enum PredicateFilter {
     /// Only traits that reference `Self: ..` and define an associated type
     /// with the given ident are implied by the trait. This mode exists to
     /// side-step query cycles when lowering associated types.
-    SelfThatDefines(Ident),
+    SelfTraitThatDefines(Ident),
 
     /// Only traits that reference `Self: ..` and their associated type bounds.
     /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
@@ -730,9 +730,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
 
         match predicate_filter {
+            // This is only concerned with trait predicates.
+            PredicateFilter::SelfTraitThatDefines(..) => {
+                bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
+            }
             PredicateFilter::All
             | PredicateFilter::SelfOnly
-            | PredicateFilter::SelfThatDefines(..)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
                 debug!(?poly_trait_ref);
                 bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index cceaabaff65..4f579b05d83 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -169,19 +169,34 @@ pub(crate) struct MissingParenthesesInRange {
 pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
-    Call,
+    Call {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
-    Method,
+    Method {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
-    Path,
+    Path {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
-    UnionField,
+    UnionField {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
-    Deref,
+    Deref {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
 }
 
 #[derive(LintDiagnostic)]
@@ -191,6 +206,64 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
     #[note]
     pub obligation_span: Span,
     pub obligation: ty::Predicate<'tcx>,
+    #[subdiagnostic]
+    pub sugg: SuggestAnnotations,
+}
+
+#[derive(Clone)]
+pub(crate) enum SuggestAnnotation {
+    Unit(Span),
+    Path(Span),
+    Local(Span),
+    Turbo(Span, usize, usize),
+}
+
+#[derive(Clone)]
+pub(crate) struct SuggestAnnotations {
+    pub suggestions: Vec<SuggestAnnotation>,
+}
+impl Subdiagnostic for SuggestAnnotations {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        _: &F,
+    ) {
+        if self.suggestions.is_empty() {
+            return;
+        }
+
+        let mut suggestions = vec![];
+        for suggestion in self.suggestions {
+            match suggestion {
+                SuggestAnnotation::Unit(span) => {
+                    suggestions.push((span, "()".to_string()));
+                }
+                SuggestAnnotation::Path(span) => {
+                    suggestions.push((span.shrink_to_lo(), "<() as ".to_string()));
+                    suggestions.push((span.shrink_to_hi(), ">".to_string()));
+                }
+                SuggestAnnotation::Local(span) => {
+                    suggestions.push((span, ": ()".to_string()));
+                }
+                SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push((
+                    span,
+                    format!(
+                        "::<{}>",
+                        (0..n_args)
+                            .map(|i| if i == idx { "()" } else { "_" })
+                            .collect::<Vec<_>>()
+                            .join(", "),
+                    ),
+                )),
+            }
+        }
+
+        diag.multipart_suggestion_verbose(
+            "use `()` annotations to avoid fallback changes",
+            suggestions,
+            Applicability::MachineApplicable,
+        );
+    }
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 68776c52555..8d8573c65c5 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -1,11 +1,15 @@
 use std::cell::OnceCell;
+use std::ops::ControlFlow;
 
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::iterate::DepthFirstSearch;
 use rustc_data_structures::graph::vec_graph::VecGraph;
 use rustc_data_structures::graph::{self};
 use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet};
 use rustc_hir as hir;
 use rustc_hir::HirId;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
 use rustc_session::lint;
@@ -14,7 +18,7 @@ use rustc_span::{DUMMY_SP, Span};
 use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
 use tracing::debug;
 
-use crate::{FnCtxt, TypeckRootCtxt, errors};
+use crate::{FnCtxt, errors};
 
 #[derive(Copy, Clone)]
 pub(crate) enum DivergingFallbackBehavior {
@@ -321,7 +325,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len());
         let unsafe_infer_vars = OnceCell::new();
 
-        self.lint_obligations_broken_by_never_type_fallback_change(behavior, &diverging_vids);
+        self.lint_obligations_broken_by_never_type_fallback_change(
+            behavior,
+            &diverging_vids,
+            &coercion_graph,
+        );
 
         for &diverging_vid in &diverging_vids {
             let diverging_ty = Ty::new_var(self.tcx, diverging_vid);
@@ -419,7 +427,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         root_vid: ty::TyVid,
     ) {
         let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| {
-            let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id);
+            let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_id);
             debug!(?unsafe_infer_vars);
             unsafe_infer_vars
         });
@@ -429,19 +437,31 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                 .filter_map(|x| unsafe_infer_vars.get(&x).copied())
                 .collect::<Vec<_>>();
 
+        let sugg = self.try_to_suggest_annotations(&[root_vid], coercion_graph);
+
         for (hir_id, span, reason) in affected_unsafe_infer_vars {
             self.tcx.emit_node_span_lint(
                 lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
                 hir_id,
                 span,
                 match reason {
-                    UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call,
-                    UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method,
-                    UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path,
+                    UnsafeUseReason::Call => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Call { sugg: sugg.clone() }
+                    }
+                    UnsafeUseReason::Method => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Method { sugg: sugg.clone() }
+                    }
+                    UnsafeUseReason::Path => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Path { sugg: sugg.clone() }
+                    }
                     UnsafeUseReason::UnionField => {
-                        errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField {
+                            sugg: sugg.clone(),
+                        }
+                    }
+                    UnsafeUseReason::Deref => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { sugg: sugg.clone() }
                     }
-                    UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref,
                 },
             );
         }
@@ -451,6 +471,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         &self,
         behavior: DivergingFallbackBehavior,
         diverging_vids: &[ty::TyVid],
+        coercions: &VecGraph<ty::TyVid, true>,
     ) {
         let DivergingFallbackBehavior::ToUnit = behavior else { return };
 
@@ -478,13 +499,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         };
 
         // If we have no errors with `fallback = ()`, but *do* have errors with `fallback = !`,
-        // then this code will be broken by the never type fallback change.qba
+        // then this code will be broken by the never type fallback change.
         let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit);
         if unit_errors.is_empty()
             && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never)
             && let [ref mut never_error, ..] = never_errors.as_mut_slice()
         {
             self.adjust_fulfillment_error_for_expr_obligation(never_error);
+            let sugg = self.try_to_suggest_annotations(diverging_vids, coercions);
             self.tcx.emit_node_span_lint(
                 lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
                 self.tcx.local_def_id_to_hir_id(self.body_id),
@@ -492,6 +514,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                 errors::DependencyOnUnitNeverTypeFallback {
                     obligation_span: never_error.obligation.cause.span,
                     obligation: never_error.obligation.predicate,
+                    sugg,
                 },
             )
         }
@@ -541,6 +564,153 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
     fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> {
         Some(self.root_var(self.shallow_resolve(ty).ty_vid()?))
     }
+
+    /// Given a set of diverging vids and coercions, walk the HIR to gather a
+    /// set of suggestions which can be applied to preserve fallback to unit.
+    fn try_to_suggest_annotations(
+        &self,
+        diverging_vids: &[ty::TyVid],
+        coercions: &VecGraph<ty::TyVid, true>,
+    ) -> errors::SuggestAnnotations {
+        let body =
+            self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner");
+        // For each diverging var, look through the HIR for a place to give it
+        // a type annotation. We do this per var because we only really need one
+        // suggestion to influence a var to be `()`.
+        let suggestions = diverging_vids
+            .iter()
+            .copied()
+            .filter_map(|vid| {
+                let reachable_vids =
+                    graph::depth_first_search_as_undirected(coercions, vid).collect();
+                AnnotateUnitFallbackVisitor { reachable_vids, fcx: self }
+                    .visit_expr(body.value)
+                    .break_value()
+            })
+            .collect();
+        errors::SuggestAnnotations { suggestions }
+    }
+}
+
+/// Try to walk the HIR to find a place to insert a useful suggestion
+/// to preserve fallback to `()` in 2024.
+struct AnnotateUnitFallbackVisitor<'a, 'tcx> {
+    reachable_vids: FxHashSet<ty::TyVid>,
+    fcx: &'a FnCtxt<'a, 'tcx>,
+}
+impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
+    // For a given path segment, if it's missing a turbofish, try to suggest adding
+    // one so we can constrain an argument to `()`. To keep the suggestion simple,
+    // we want to simply suggest `_` for all the other args. This (for now) only
+    // works when there are only type variables (and region variables, since we can
+    // elide them)...
+    fn suggest_for_segment(
+        &self,
+        arg_segment: &'tcx hir::PathSegment<'tcx>,
+        def_id: DefId,
+        id: HirId,
+    ) -> ControlFlow<errors::SuggestAnnotation> {
+        if arg_segment.args.is_none()
+            && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
+            && let generics = self.fcx.tcx.generics_of(def_id)
+            && let args = &all_args[generics.parent_count..]
+            // We can't turbofish consts :(
+            && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_)))
+        {
+            let n_tys = args
+                .iter()
+                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
+                .count();
+            for (idx, arg) in args.iter().enumerate() {
+                if let Some(ty) = arg.as_type()
+                    && let Some(vid) = self.fcx.root_vid(ty)
+                    && self.reachable_vids.contains(&vid)
+                {
+                    return ControlFlow::Break(errors::SuggestAnnotation::Turbo(
+                        arg_segment.ident.span.shrink_to_hi(),
+                        n_tys,
+                        idx,
+                    ));
+                }
+            }
+        }
+        ControlFlow::Continue(())
+    }
+}
+impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
+    type Result = ControlFlow<errors::SuggestAnnotation>;
+
+    fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result {
+        // Try to replace `_` with `()`.
+        if let hir::TyKind::Infer = hir_ty.kind
+            && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id)
+            && let Some(vid) = self.fcx.root_vid(ty)
+            && self.reachable_vids.contains(&vid)
+        {
+            return ControlFlow::Break(errors::SuggestAnnotation::Unit(hir_ty.span));
+        }
+        hir::intravisit::walk_ty(self, hir_ty)
+    }
+
+    fn visit_qpath(
+        &mut self,
+        qpath: &'tcx rustc_hir::QPath<'tcx>,
+        id: HirId,
+        _span: Span,
+    ) -> Self::Result {
+        let arg_segment = match qpath {
+            hir::QPath::Resolved(_, path) => {
+                path.segments.last().expect("paths should have a segment")
+            }
+            hir::QPath::TypeRelative(_, segment) => segment,
+            hir::QPath::LangItem(..) => {
+                return hir::intravisit::walk_qpath(self, qpath, id);
+            }
+        };
+        // Alternatively, try to turbofish `::<_, (), _>`.
+        if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() {
+            self.suggest_for_segment(arg_segment, def_id, id)?;
+        }
+        hir::intravisit::walk_qpath(self, qpath, id)
+    }
+
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
+        // Try to suggest adding an explicit qself `()` to a trait method path.
+        // i.e. changing `Default::default()` to `<() as Default>::default()`.
+        if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
+            && let Res::Def(DefKind::AssocFn, def_id) = path.res
+            && self.fcx.tcx.trait_of_item(def_id).is_some()
+            && let self_ty = self.fcx.typeck_results.borrow().node_args(expr.hir_id).type_at(0)
+            && let Some(vid) = self.fcx.root_vid(self_ty)
+            && self.reachable_vids.contains(&vid)
+            && let [.., trait_segment, _method_segment] = path.segments
+        {
+            let span = path.span.shrink_to_lo().to(trait_segment.ident.span);
+            return ControlFlow::Break(errors::SuggestAnnotation::Path(span));
+        }
+        // Or else, try suggesting turbofishing the method args.
+        if let hir::ExprKind::MethodCall(segment, ..) = expr.kind
+            && let Some(def_id) =
+                self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id)
+        {
+            self.suggest_for_segment(segment, def_id, expr.hir_id)?;
+        }
+        hir::intravisit::walk_expr(self, expr)
+    }
+
+    fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result {
+        // For a local, try suggest annotating the type if it's missing.
+        if let None = local.ty
+            && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id)
+            && let Some(vid) = self.fcx.root_vid(ty)
+            && self.reachable_vids.contains(&vid)
+        {
+            return ControlFlow::Break(errors::SuggestAnnotation::Local(
+                local.pat.span.shrink_to_hi(),
+            ));
+        }
+        hir::intravisit::walk_local(self, local)
+    }
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -569,27 +739,26 @@ pub(crate) enum UnsafeUseReason {
 ///
 /// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }`
 fn compute_unsafe_infer_vars<'a, 'tcx>(
-    root_ctxt: &'a TypeckRootCtxt<'tcx>,
+    fcx: &'a FnCtxt<'a, 'tcx>,
     body_id: LocalDefId,
 ) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> {
-    let body =
-        root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner");
+    let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner");
     let mut res = UnordMap::default();
 
     struct UnsafeInferVarsVisitor<'a, 'tcx> {
-        root_ctxt: &'a TypeckRootCtxt<'tcx>,
+        fcx: &'a FnCtxt<'a, 'tcx>,
         res: &'a mut UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)>,
     }
 
     impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_> {
         fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) {
-            let typeck_results = self.root_ctxt.typeck_results.borrow();
+            let typeck_results = self.fcx.typeck_results.borrow();
 
             match ex.kind {
                 hir::ExprKind::MethodCall(..) => {
                     if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id)
-                        && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity()
-                        && let sig = method_ty.fn_sig(self.root_ctxt.tcx)
+                        && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity()
+                        && let sig = method_ty.fn_sig(self.fcx.tcx)
                         && let hir::Safety::Unsafe = sig.safety()
                     {
                         let mut collector = InferVarCollector {
@@ -609,7 +778,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
                     let func_ty = typeck_results.expr_ty(func);
 
                     if func_ty.is_fn()
-                        && let sig = func_ty.fn_sig(self.root_ctxt.tcx)
+                        && let sig = func_ty.fn_sig(self.fcx.tcx)
                         && let hir::Safety::Unsafe = sig.safety()
                     {
                         let mut collector = InferVarCollector {
@@ -640,7 +809,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
                     // If this path refers to an unsafe function, collect inference variables which may affect it.
                     // `is_fn` excludes closures, but those can't be unsafe.
                     if ty.is_fn()
-                        && let sig = ty.fn_sig(self.root_ctxt.tcx)
+                        && let sig = ty.fn_sig(self.fcx.tcx)
                         && let hir::Safety::Unsafe = sig.safety()
                     {
                         let mut collector = InferVarCollector {
@@ -698,7 +867,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
         }
     }
 
-    UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value);
+    UnsafeInferVarsVisitor { fcx, res: &mut res }.visit_expr(&body.value);
 
     debug!(?res, "collected the following unsafe vars for {body_id:?}");
 
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index d3762e739db..35bba149d0a 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -832,8 +832,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(polonius, Polonius::Legacy);
     tracked!(precise_enum_drop_elaboration, false);
     tracked!(print_fuel, Some("abc".to_string()));
-    tracked!(profile, true);
-    tracked!(profile_emit, Some(PathBuf::from("abc")));
     tracked!(profile_sample_use, Some(PathBuf::from("abc")));
     tracked!(profiler_runtime, "abc".to_string());
     tracked!(regparm, Some(3));
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 88878a018e7..48dd8e38a03 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -204,7 +204,10 @@ fn lint_nan<'tcx>(
                     return false;
                 };
 
-                matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::f32_nan | sym::f64_nan))
+                matches!(
+                    cx.tcx.get_diagnostic_name(def_id),
+                    Some(sym::f16_nan | sym::f32_nan | sym::f64_nan | sym::f128_nan)
+                )
             }
             _ => false,
         }
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 3e906f89c15..3b7dc6de825 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -42,7 +42,6 @@
 #if LLVM_VERSION_GE(19, 0)
 #include "llvm/Support/PGOOptions.h"
 #endif
-#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
@@ -714,9 +713,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
     bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
     bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions,
     const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage,
-    const char *InstrProfileOutput, bool InstrumentGCOV,
-    const char *PGOSampleUsePath, bool DebugInfoForProfiling,
-    void *LlvmSelfProfiler,
+    const char *InstrProfileOutput, const char *PGOSampleUsePath,
+    bool DebugInfoForProfiling, void *LlvmSelfProfiler,
     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
     LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
     const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins,
@@ -847,13 +845,6 @@ extern "C" LLVMRustResult LLVMRustOptimize(
         });
   }
 
-  if (InstrumentGCOV) {
-    PipelineStartEPCallbacks.push_back(
-        [](ModulePassManager &MPM, OptimizationLevel Level) {
-          MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
-        });
-  }
-
   if (InstrumentCoverage) {
     PipelineStartEPCallbacks.push_back(
         [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index 3b0151b1f94..cece700b4dd 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -27,7 +27,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_type_ir = { path = "../rustc_type_ir" }
-snap = "1"
 tempfile = "3.2"
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 16623915c40..d2be6ae8d69 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -778,9 +778,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
 
     fn inject_profiler_runtime(&mut self, krate: &ast::Crate) {
         if self.sess.opts.unstable_opts.no_profiler_runtime
-            || !(self.sess.instrument_coverage()
-                || self.sess.opts.unstable_opts.profile
-                || self.sess.opts.cg.profile_generate.enabled())
+            || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled())
         {
             return;
         }
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index a4a69ae9514..f924ed48b6f 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -213,7 +213,7 @@
 //! metadata::locator or metadata::creader for all the juicy details!
 
 use std::borrow::Cow;
-use std::io::{Read, Result as IoResult, Write};
+use std::io::{Result as IoResult, Write};
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::{cmp, fmt};
@@ -232,7 +232,6 @@ use rustc_session::utils::CanonicalizedPath;
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::{Target, TargetTriple};
-use snap::read::FrameDecoder;
 use tracing::{debug, info};
 
 use crate::creader::{Library, MetadataLoader};
@@ -792,7 +791,6 @@ fn get_metadata_section<'p>(
         CrateFlavor::Dylib => {
             let buf =
                 loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?;
-            // The header is uncompressed
             let header_len = METADATA_HEADER.len();
             // header + u64 length of data
             let data_start = header_len + 8;
@@ -806,7 +804,7 @@ fn get_metadata_section<'p>(
                 )));
             }
 
-            // Length of the compressed stream - this allows linkers to pad the section if they want
+            // Length of the metadata - this allows linkers to pad the section if they want
             let Ok(len_bytes) =
                 <[u8; 8]>::try_from(&buf[header_len..cmp::min(data_start, buf.len())])
             else {
@@ -814,29 +812,10 @@ fn get_metadata_section<'p>(
                     "invalid metadata length found".to_string(),
                 ));
             };
-            let compressed_len = u64::from_le_bytes(len_bytes) as usize;
+            let metadata_len = u64::from_le_bytes(len_bytes) as usize;
 
             // Header is okay -> inflate the actual metadata
-            let compressed_bytes = buf.slice(|buf| &buf[data_start..(data_start + compressed_len)]);
-            if &compressed_bytes[..cmp::min(METADATA_HEADER.len(), compressed_bytes.len())]
-                == METADATA_HEADER
-            {
-                // The metadata was not actually compressed.
-                compressed_bytes
-            } else {
-                debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
-                // Assume the decompressed data will be at least the size of the compressed data, so we
-                // don't have to grow the buffer as much.
-                let mut inflated = Vec::with_capacity(compressed_bytes.len());
-                FrameDecoder::new(&*compressed_bytes).read_to_end(&mut inflated).map_err(|_| {
-                    MetadataError::LoadFailure(format!(
-                        "failed to decompress metadata: {}",
-                        filename.display()
-                    ))
-                })?;
-
-                slice_owned(inflated, Deref::deref)
-            }
+            buf.slice(|buf| &buf[data_start..(data_start + metadata_len)])
         }
         CrateFlavor::Rmeta => {
             // mmap the file, because only a small fraction of it is read.
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d733e32f209..5ee3b4015eb 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2453,7 +2453,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
     let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
 
     let mut cg = CodegenOptions::build(early_dcx, matches);
-    let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
+    let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
         early_dcx,
         &output_types,
         matches,
@@ -2476,18 +2476,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
 
     let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
 
-    if unstable_opts.profile && incremental.is_some() {
-        early_dcx.early_fatal("can't instrument with gcov profiling when compiling incrementally");
-    }
-    if unstable_opts.profile {
-        match codegen_units {
-            Some(1) => {}
-            None => codegen_units = Some(1),
-            Some(_) => early_dcx
-                .early_fatal("can't instrument with gcov profiling with multiple codegen units"),
-        }
-    }
-
     if cg.profile_generate.enabled() && cg.profile_use.is_some() {
         early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
     }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 54a4621db24..2b158627751 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1985,13 +1985,8 @@ options! {
     proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread,
         parse_proc_macro_execution_strategy, [UNTRACKED],
         "how to run proc-macro code (default: same-thread)"),
-    profile: bool = (false, parse_bool, [TRACKED],
-        "insert profiling code (default: no)"),
     profile_closures: bool = (false, parse_no_flag, [UNTRACKED],
         "profile size of closures"),
-    profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
-        "file path to emit profiling data at runtime when using 'profile' \
-        (default based on relative source path)"),
     profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"),
     profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED],
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 74b198c4fdd..4cf52042a57 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1254,11 +1254,9 @@ impl<T> SizedTypeProperties for T {}
 ///
 /// Nested field accesses may be used, but not array indexes.
 ///
-/// Enum variants may be traversed as if they were fields. Variants themselves do
-/// not have an offset.
-///
-/// However, on stable only a single field name is supported, which blocks the use of
-/// enum support.
+/// If the nightly-only feature `offset_of_enum` is enabled,
+/// variants may be traversed as if they were fields.
+/// Variants themselves do not have an offset.
 ///
 /// Visibility is respected - all types and fields must be visible to the call site:
 ///
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 99ddf58104c..4ab4e60773f 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1056,6 +1056,14 @@ pub fn rustc_cargo(
         cargo.rustflag("-l").rustflag("Enzyme-19");
     }
 
+    // Building with protected visibility reduces the number of dynamic relocations needed, giving
+    // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object
+    // with direct references to protected symbols, so for now we only use protected symbols if
+    // linking with LLD is enabled.
+    if builder.build.config.lld_mode.is_used() {
+        cargo.rustflag("-Zdefault-visibility=protected");
+    }
+
     // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary
     // and may just be a time sink.
     if compiler.stage != 0 {
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index 51964977933..704fa46ab1e 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -571,6 +571,7 @@ Select which editor you would like to set up [default: None]: ";
                 "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a",
                 "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000",
                 "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d",
+                "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
             ],
             EditorKind::Emacs => vec![
                 "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md
index ed091d8fc57..41da47e9206 100644
--- a/src/doc/rustc/src/instrument-coverage.md
+++ b/src/doc/rustc/src/instrument-coverage.md
@@ -2,12 +2,8 @@
 
 ## Introduction
 
-The Rust compiler includes two code coverage implementations:
-
--   A GCC-compatible, gcov-based coverage implementation, enabled with `-Z profile`, which derives coverage data based on DebugInfo.
--   A source-based code coverage implementation, enabled with `-C instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data.
-
-This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-C instrument-coverage` compiler flag.
+This document describes how to enable and use LLVM instrumentation-based coverage,
+via the `-C instrument-coverage` compiler flag.
 
 ## How it works
 
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
index 74e873e35ff..d9dba641495 100644
--- a/src/doc/style-guide/src/editions.md
+++ b/src/doc/style-guide/src/editions.md
@@ -40,8 +40,9 @@ include:
   of a delimited expression, delimited expressions are generally combinable,
   regardless of the number of members. Previously only applied with exactly
   one member (except for closures with explicit blocks).
-- When line-breaking a binary operator, if the first operand spans multiple
-  lines, use the base indentation of the last line.
+- When line-breaking an assignment operator, if the left-hand side spans
+  multiple lines, use the base indentation of the last line of the left-hand
+  side to indent the right-hand side.
 - Miscellaneous `rustfmt` bugfixes.
 - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order).
 - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase".
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 3bb0ee6d5ff..4f63a632030 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -328,9 +328,9 @@ foo_bar
 Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather
 than at other binary operators.
 
-If line-breaking at a binary operator (including assignment operators) where the
-first operand spans multiple lines, use the base indentation of the *last*
-line of the first operand, and indent relative to that:
+If line-breaking an assignment operator where the left-hand side spans multiple
+lines, use the base indentation of the *last* line of the left-hand side, and
+indent the right-hand side relative to that:
 
 ```rust
 impl SomeType {
@@ -344,12 +344,6 @@ impl SomeType {
         self.array[array_index as usize]
             .as_mut()
             .expect("thing must exist")
-            .extra_info
-                + long_long_long_long_long_long_long_long_long_long_long_long_long_long_long;
-
-        self.array[array_index as usize]
-            .as_mut()
-            .expect("thing must exist")
             .extra_info = Some(ExtraInfo {
                 parent,
                 count: count as u16,
diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md
deleted file mode 100644
index 71303bfaff2..00000000000
--- a/src/doc/unstable-book/src/compiler-flags/profile.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# `profile`
-
-The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
-
-------------------------
-
-This feature allows the generation of code coverage reports.
-
-Set the `-Zprofile` compiler flag in order to enable gcov profiling.
-
-For example:
-```Bash
-cargo new testgcov --bin
-cd testgcov
-export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
-export CARGO_INCREMENTAL=0
-cargo build
-cargo run
-```
-
-Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created.
-You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/mozilla/grcov).
-
-Please note that `RUSTFLAGS` by default applies to everything that cargo builds and runs during a build!
-When the `--target` flag is explicitly passed to cargo, the `RUSTFLAGS` no longer apply to build scripts and procedural macros.
-For more fine-grained control consider passing a `RUSTC_WRAPPER` program to cargo that only adds the profiling flags to
-rustc for the specific crates you want to profile.
diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json
index a20105f0ef3..d1b186fd316 100644
--- a/src/etc/rust_analyzer_settings.json
+++ b/src/etc/rust_analyzer_settings.json
@@ -1,6 +1,5 @@
 {
     "git.detectSubmodulesLimit": 20,
-    "rust-analyzer.check.invocationLocation": "root",
     "rust-analyzer.check.invocationStrategy": "once",
     "rust-analyzer.check.overrideCommand": [
         "python3",
@@ -24,7 +23,6 @@
     "rust-analyzer.procMacro.server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv",
     "rust-analyzer.procMacro.enable": true,
     "rust-analyzer.cargo.buildScripts.enable": true,
-    "rust-analyzer.cargo.buildScripts.invocationLocation": "root",
     "rust-analyzer.cargo.buildScripts.invocationStrategy": "once",
     "rust-analyzer.cargo.buildScripts.overrideCommand": [
         "python3",
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index c62144be3da..d49b4320db6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -5,6 +5,7 @@ use std::sync::{Arc, OnceLock as OnceCell};
 use std::{fmt, iter};
 
 use arrayvec::ArrayVec;
+use rustc_abi::{ExternAbi, VariantIdx};
 use rustc_ast::MetaItemInner;
 use rustc_ast_pretty::pprust;
 use rustc_attr::{ConstStability, Deprecation, Stability, StableSince};
@@ -26,8 +27,6 @@ use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use rustc_span::{DUMMY_SP, FileName, Loc};
-use rustc_target::abi::VariantIdx;
-use rustc_target::spec::abi::Abi;
 use thin_vec::ThinVec;
 use tracing::{debug, trace};
 use {rustc_ast as ast, rustc_hir as hir};
@@ -656,7 +655,7 @@ impl Item {
                 let def_id = self.def_id().unwrap();
                 let abi = tcx.fn_sig(def_id).skip_binder().abi();
                 hir::FnHeader {
-                    safety: if abi == Abi::RustIntrinsic {
+                    safety: if abi == ExternAbi::RustIntrinsic {
                         intrinsic_operation_unsafety(tcx, def_id.expect_local())
                     } else {
                         safety
@@ -2342,7 +2341,7 @@ pub(crate) struct BareFunctionDecl {
     pub(crate) safety: hir::Safety,
     pub(crate) generic_params: Vec<GenericParamDef>,
     pub(crate) decl: FnDecl,
-    pub(crate) abi: Abi,
+    pub(crate) abi: ExternAbi,
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 47c21d89177..e9d5ba2ea57 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -13,6 +13,7 @@ use std::fmt::{self, Display, Write};
 use std::iter::{self, once};
 
 use itertools::Itertools;
+use rustc_abi::ExternAbi;
 use rustc_attr::{ConstStability, StabilityLevel, StableSince};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +24,6 @@ use rustc_metadata::creader::{CStore, LoadedMacro};
 use rustc_middle::ty::{self, TyCtxt, TypingMode};
 use rustc_span::symbol::kw;
 use rustc_span::{Symbol, sym};
-use rustc_target::spec::abi::Abi;
 use tracing::{debug, trace};
 
 use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length};
@@ -1787,11 +1787,11 @@ impl clean::AssocItemConstraint {
     }
 }
 
-pub(crate) fn print_abi_with_space(abi: Abi) -> impl Display {
+pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
     display_fn(move |f| {
         let quot = if f.alternate() { "\"" } else { "&quot;" };
         match abi {
-            Abi::Rust => Ok(()),
+            ExternAbi::Rust => Ok(()),
             abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()),
         }
     })
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 5e9cbef99a9..c6a2d87cbd0 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -5,6 +5,7 @@ use std::rc::Rc;
 
 use itertools::Itertools;
 use rinja::Template;
+use rustc_abi::VariantIdx;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_hir as hir;
@@ -14,7 +15,6 @@ use rustc_index::IndexVec;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{Symbol, kw, sym};
-use rustc_target::abi::VariantIdx;
 use tracing::{debug, info};
 
 use super::type_layout::document_type_layout;
diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs
index 79209cee94f..d85ba3a2b14 100644
--- a/src/librustdoc/html/render/type_layout.rs
+++ b/src/librustdoc/html/render/type_layout.rs
@@ -1,13 +1,13 @@
 use std::fmt;
 
 use rinja::Template;
+use rustc_abi::{Primitive, TagEncoding, Variants};
 use rustc_data_structures::captures::Captures;
 use rustc_hir::def_id::DefId;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::LayoutError;
 use rustc_middle::ty::{self};
 use rustc_span::symbol::Symbol;
-use rustc_target::abi::{Primitive, TagEncoding, Variants};
 
 use crate::html::format::display_fn;
 use crate::html::render::Context;
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7270f170780..1c8303d4c20 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -4,6 +4,7 @@
 
 #![allow(rustc::default_hash_types)]
 
+use rustc_abi::ExternAbi;
 use rustc_ast::ast;
 use rustc_attr::DeprecatedSince;
 use rustc_hir::def::{CtorKind, DefKind};
@@ -11,7 +12,6 @@ use rustc_hir::def_id::DefId;
 use rustc_metadata::rendered_const;
 use rustc_middle::{bug, ty};
 use rustc_span::{Pos, Symbol, sym};
-use rustc_target::spec::abi::Abi as RustcAbi;
 use rustdoc_json_types::*;
 
 use super::FullItemId;
@@ -421,17 +421,17 @@ pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> FunctionHeader {
     }
 }
 
-fn convert_abi(a: RustcAbi) -> Abi {
+fn convert_abi(a: ExternAbi) -> Abi {
     match a {
-        RustcAbi::Rust => Abi::Rust,
-        RustcAbi::C { unwind } => Abi::C { unwind },
-        RustcAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
-        RustcAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
-        RustcAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
-        RustcAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
-        RustcAbi::Win64 { unwind } => Abi::Win64 { unwind },
-        RustcAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
-        RustcAbi::System { unwind } => Abi::System { unwind },
+        ExternAbi::Rust => Abi::Rust,
+        ExternAbi::C { unwind } => Abi::C { unwind },
+        ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
+        ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
+        ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
+        ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
+        ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
+        ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
+        ExternAbi::System { unwind } => Abi::System { unwind },
         _ => Abi::Other(a.to_string()),
     }
 }
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 695c37f6d7b..424357e8473 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1364,7 +1364,6 @@ dependencies = [
  "proc-macro-api",
  "proc-macro-test",
  "ra-ap-rustc_lexer",
- "snap",
  "span",
  "stdx",
  "syntax-bridge",
@@ -1889,12 +1888,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "snap"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
-
-[[package]]
 name = "span"
 version = "0.0.0"
 dependencies = [
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 3aa93b7b7b4..1099d2cb918 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -145,7 +145,6 @@ smallvec = { version = "1.10.0", features = [
   "const_generics",
 ] }
 smol_str = "0.3.2"
-snap = "1.1.0"
 text-size = "1.1.1"
 tracing = "0.1.40"
 tracing-tree = "0.3.0"
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index e8d9677c928..4fabcc90067 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -16,7 +16,6 @@ doctest = false
 object.workspace = true
 libloading.workspace = true
 memmap2.workspace = true
-snap.workspace = true
 
 stdx.workspace = true
 tt.workspace = true
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
index 1f7ef7914ba..7f0e95c50de 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
@@ -8,7 +8,6 @@ use std::{
 use memmap2::Mmap;
 use object::read::{File as BinaryFile, Object, ObjectSection};
 use paths::AbsPath;
-use snap::read::FrameDecoder as SnapDecoder;
 
 #[derive(Debug)]
 #[allow(dead_code)]
@@ -123,9 +122,8 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
     let version = u32::from_be_bytes([dot_rustc[4], dot_rustc[5], dot_rustc[6], dot_rustc[7]]);
     // Last supported version is:
     // https://github.com/rust-lang/rust/commit/b94cfefc860715fb2adf72a6955423d384c69318
-    let (snappy_portion, bytes_before_version) = match version {
-        5 | 6 => (&dot_rustc[8..], 13),
-        7 | 8 => {
+    let (mut metadata_portion, bytes_before_version) = match version {
+        8 => {
             let len_bytes = &dot_rustc[8..12];
             let data_len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize;
             (&dot_rustc[12..data_len + 12], 13)
@@ -143,13 +141,6 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
         }
     };
 
-    let mut uncompressed: Box<dyn Read> = if &snappy_portion[0..4] == b"rust" {
-        // Not compressed.
-        Box::new(snappy_portion)
-    } else {
-        Box::new(SnapDecoder::new(snappy_portion))
-    };
-
     // We're going to skip over the bytes before the version string, so basically:
     // 8 bytes for [b'r',b'u',b's',b't',0,0,0,5]
     // 4 or 8 bytes for [crate root bytes]
@@ -157,11 +148,11 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
     // so 13 or 17 bytes in total, and we should check the last of those bytes
     // to know the length
     let mut bytes = [0u8; 17];
-    uncompressed.read_exact(&mut bytes[..bytes_before_version])?;
+    metadata_portion.read_exact(&mut bytes[..bytes_before_version])?;
     let length = bytes[bytes_before_version - 1];
 
     let mut version_string_utf8 = vec![0u8; length as usize];
-    uncompressed.read_exact(&mut version_string_utf8)?;
+    metadata_portion.read_exact(&mut version_string_utf8)?;
     let version_string = String::from_utf8(version_string_utf8);
     version_string.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
 }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 630838d46a2..f3bd72fe647 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -101,7 +101,6 @@ const EXCEPTIONS: ExceptionList = &[
     ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"),     // rustc (license is the same as LLVM uses)
     ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0                       // cargo/... (because of serde)
     ("self_cell", "Apache-2.0"),                             // rustc (fluent translations)
-    ("snap", "BSD-3-Clause"),                                // rustc
     ("wasi-preview1-component-adapter-provider", "Apache-2.0 WITH LLVM-exception"), // rustc
     // tidy-alphabetical-end
 ];
@@ -163,7 +162,6 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[
     ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"),
     ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0
     ("scip", "Apache-2.0"),
-    ("snap", "BSD-3-Clause"),
     // tidy-alphabetical-end
 ];
 
@@ -391,7 +389,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "sharded-slab",
     "shlex",
     "smallvec",
-    "snap",
     "stable_deref_trait",
     "stacker",
     "static_assertions",
diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs
deleted file mode 100644
index 58a1b53c040..00000000000
--- a/tests/run-make/profile/rmake.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// This test revolves around the rustc flag -Z profile, which should
-// generate a .gcno file (initial profiling information) as well
-// as a .gcda file (branch counters). The path where these are emitted
-// should also be configurable with -Z profile-emit. This test checks
-// that the files are produced, and then that the latter flag is respected.
-// See https://github.com/rust-lang/rust/pull/42433
-
-//@ ignore-cross-compile
-//@ needs-profiler-runtime
-
-use run_make_support::{path, run, rustc};
-
-fn main() {
-    rustc().arg("-g").arg("-Zprofile").input("test.rs").run();
-    run("test");
-    assert!(path("test.gcno").exists(), "no .gcno file");
-    assert!(path("test.gcda").exists(), "no .gcda file");
-    rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run();
-    run("test");
-    assert!(path("abc/abc.gcda").exists(), "gcda file not emitted to defined path");
-}
diff --git a/tests/run-make/profile/test.rs b/tests/run-make/profile/test.rs
deleted file mode 100644
index f328e4d9d04..00000000000
--- a/tests/run-make/profile/test.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn main() {}
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index 134fd098b7e..79eee2a3def 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let x: () = match true {
+   |          ++++
 
 warning: this function depends on never type fallback being `()`
   --> $DIR/never-type-fallback-breaking.rs:27:1
@@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     deserialize::<()>()?;
+   |                ++++++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed
index 46b2d4e9c3f..2d88c274080 100644
--- a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed
+++ b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed
@@ -1,7 +1,15 @@
 //@ check-pass
 //@ run-rustfix
 
+#![feature(f16, f128)]
+
 fn main() {
+    let x = 5f16;
+    let _ = x.is_nan();
+    //~^ WARN incorrect NaN comparison
+    let _ = !x.is_nan();
+    //~^ WARN incorrect NaN comparison
+
     let x = 5f32;
     let _ = x.is_nan();
     //~^ WARN incorrect NaN comparison
@@ -14,6 +22,12 @@ fn main() {
     let _ = !x.is_nan();
     //~^ WARN incorrect NaN comparison
 
+    let x = 5f128;
+    let _ = x.is_nan();
+    //~^ WARN incorrect NaN comparison
+    let _ = !x.is_nan();
+    //~^ WARN incorrect NaN comparison
+
     let b = &2.3f32;
     if !b.is_nan() {}
     //~^ WARN incorrect NaN comparison
diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.rs b/tests/ui/lint/invalid-nan-comparison-suggestion.rs
index 558b433d794..91753447869 100644
--- a/tests/ui/lint/invalid-nan-comparison-suggestion.rs
+++ b/tests/ui/lint/invalid-nan-comparison-suggestion.rs
@@ -1,7 +1,15 @@
 //@ check-pass
 //@ run-rustfix
 
+#![feature(f16, f128)]
+
 fn main() {
+    let x = 5f16;
+    let _ = x == f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    let _ = x != f16::NAN;
+    //~^ WARN incorrect NaN comparison
+
     let x = 5f32;
     let _ = x == f32::NAN;
     //~^ WARN incorrect NaN comparison
@@ -14,6 +22,12 @@ fn main() {
     let _ = x != f64::NAN;
     //~^ WARN incorrect NaN comparison
 
+    let x = 5f128;
+    let _ = x == f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    let _ = x != f128::NAN;
+    //~^ WARN incorrect NaN comparison
+
     let b = &2.3f32;
     if b != &f32::NAN {}
     //~^ WARN incorrect NaN comparison
diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr
index c310341de07..9d07d3f9240 100644
--- a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr
+++ b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr
@@ -1,18 +1,42 @@
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:6:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:8:13
    |
-LL |     let _ = x == f32::NAN;
+LL |     let _ = x == f16::NAN;
    |             ^^^^^^^^^^^^^
    |
    = note: `#[warn(invalid_nan_comparisons)]` on by default
 help: use `f32::is_nan()` or `f64::is_nan()` instead
    |
+LL -     let _ = x == f16::NAN;
+LL +     let _ = x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:10:13
+   |
+LL |     let _ = x != f16::NAN;
+   |             ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     let _ = x != f16::NAN;
+LL +     let _ = !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:14:13
+   |
+LL |     let _ = x == f32::NAN;
+   |             ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
 LL -     let _ = x == f32::NAN;
 LL +     let _ = x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:8:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:16:13
    |
 LL |     let _ = x != f32::NAN;
    |             ^^^^^^^^^^^^^
@@ -24,7 +48,7 @@ LL +     let _ = !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:12:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:20:13
    |
 LL |     let _ = x == f64::NAN;
    |             ^^^^^^^^^^^^^
@@ -36,7 +60,7 @@ LL +     let _ = x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:14:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:22:13
    |
 LL |     let _ = x != f64::NAN;
    |             ^^^^^^^^^^^^^
@@ -48,7 +72,31 @@ LL +     let _ = !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:18:8
+  --> $DIR/invalid-nan-comparison-suggestion.rs:26:13
+   |
+LL |     let _ = x == f128::NAN;
+   |             ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     let _ = x == f128::NAN;
+LL +     let _ = x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:28:13
+   |
+LL |     let _ = x != f128::NAN;
+   |             ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     let _ = x != f128::NAN;
+LL +     let _ = !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:32:8
    |
 LL |     if b != &f32::NAN {}
    |        ^^^^^^^^^^^^^^
@@ -60,7 +108,7 @@ LL +     if !b.is_nan() {}
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:22:8
+  --> $DIR/invalid-nan-comparison-suggestion.rs:36:8
    |
 LL |     if b != { &f32::NAN } {}
    |        ^^^^^^^^^^^^^^^^^^
@@ -72,7 +120,7 @@ LL +     if !b.is_nan() {}
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:26:9
+  --> $DIR/invalid-nan-comparison-suggestion.rs:40:9
    |
 LL | /         b != {
 LL | |
@@ -87,7 +135,7 @@ LL +         !b.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:35:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:49:13
    |
 LL |     let _ = nan!() == number!();
    |             ^^^^^^^^^^^^^^^^^^^
@@ -99,7 +147,7 @@ LL +     let _ = number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:37:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:51:13
    |
 LL |     let _ = number!() != nan!();
    |             ^^^^^^^^^^^^^^^^^^^
@@ -110,5 +158,5 @@ LL -     let _ = number!() != nan!();
 LL +     let _ = !number!().is_nan();
    |
 
-warning: 9 warnings emitted
+warning: 13 warnings emitted
 
diff --git a/tests/ui/lint/invalid-nan-comparison.rs b/tests/ui/lint/invalid-nan-comparison.rs
index 202a5e27e8e..1a2c8a7c5a0 100644
--- a/tests/ui/lint/invalid-nan-comparison.rs
+++ b/tests/ui/lint/invalid-nan-comparison.rs
@@ -1,13 +1,38 @@
 //@ check-pass
 
+#![feature(f16, f128)]
+
 fn main() {
+    f16();
     f32();
     f64();
+    f128();
 }
 
 const TEST: bool = 5f32 == f32::NAN;
 //~^ WARN incorrect NaN comparison
 
+fn f16() {
+    macro_rules! number { () => { 5f16 }; }
+    let x = number!();
+    x == f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x != f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x < f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x > f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x <= f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x >= f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    number!() == f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    f16::NAN != number!();
+    //~^ WARN incorrect NaN comparison
+}
+
 fn f32() {
     macro_rules! number { () => { 5f32 }; }
     let x = number!();
@@ -49,3 +74,24 @@ fn f64() {
     f64::NAN != number!();
     //~^ WARN incorrect NaN comparison
 }
+
+fn f128() {
+    macro_rules! number { () => { 5f128 }; }
+    let x = number!();
+    x == f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x != f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x < f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x > f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x <= f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x >= f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    number!() == f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    f128::NAN != number!();
+    //~^ WARN incorrect NaN comparison
+}
diff --git a/tests/ui/lint/invalid-nan-comparison.stderr b/tests/ui/lint/invalid-nan-comparison.stderr
index 054c06d38b3..486d2a9636c 100644
--- a/tests/ui/lint/invalid-nan-comparison.stderr
+++ b/tests/ui/lint/invalid-nan-comparison.stderr
@@ -1,5 +1,5 @@
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:8:20
+  --> $DIR/invalid-nan-comparison.rs:12:20
    |
 LL | const TEST: bool = 5f32 == f32::NAN;
    |                    ^^^^^^^^^^^^^^^^
@@ -12,7 +12,79 @@ LL + const TEST: bool = 5f32.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:14:5
+  --> $DIR/invalid-nan-comparison.rs:18:5
+   |
+LL |     x == f16::NAN;
+   |     ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x == f16::NAN;
+LL +     x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:20:5
+   |
+LL |     x != f16::NAN;
+   |     ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x != f16::NAN;
+LL +     !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:22:5
+   |
+LL |     x < f16::NAN;
+   |     ^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:24:5
+   |
+LL |     x > f16::NAN;
+   |     ^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:26:5
+   |
+LL |     x <= f16::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:28:5
+   |
+LL |     x >= f16::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:30:5
+   |
+LL |     number!() == f16::NAN;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     number!() == f16::NAN;
+LL +     number!().is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:32:5
+   |
+LL |     f16::NAN != number!();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     f16::NAN != number!();
+LL +     !number!().is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:39:5
    |
 LL |     x == f32::NAN;
    |     ^^^^^^^^^^^^^
@@ -24,7 +96,7 @@ LL +     x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:16:5
+  --> $DIR/invalid-nan-comparison.rs:41:5
    |
 LL |     x != f32::NAN;
    |     ^^^^^^^^^^^^^
@@ -36,31 +108,31 @@ LL +     !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:18:5
+  --> $DIR/invalid-nan-comparison.rs:43:5
    |
 LL |     x < f32::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:20:5
+  --> $DIR/invalid-nan-comparison.rs:45:5
    |
 LL |     x > f32::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:22:5
+  --> $DIR/invalid-nan-comparison.rs:47:5
    |
 LL |     x <= f32::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:24:5
+  --> $DIR/invalid-nan-comparison.rs:49:5
    |
 LL |     x >= f32::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:26:5
+  --> $DIR/invalid-nan-comparison.rs:51:5
    |
 LL |     number!() == f32::NAN;
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +144,7 @@ LL +     number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:28:5
+  --> $DIR/invalid-nan-comparison.rs:53:5
    |
 LL |     f32::NAN != number!();
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +156,7 @@ LL +     !number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:35:5
+  --> $DIR/invalid-nan-comparison.rs:60:5
    |
 LL |     x == f64::NAN;
    |     ^^^^^^^^^^^^^
@@ -96,7 +168,7 @@ LL +     x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:37:5
+  --> $DIR/invalid-nan-comparison.rs:62:5
    |
 LL |     x != f64::NAN;
    |     ^^^^^^^^^^^^^
@@ -108,31 +180,31 @@ LL +     !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:39:5
+  --> $DIR/invalid-nan-comparison.rs:64:5
    |
 LL |     x < f64::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:41:5
+  --> $DIR/invalid-nan-comparison.rs:66:5
    |
 LL |     x > f64::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:43:5
+  --> $DIR/invalid-nan-comparison.rs:68:5
    |
 LL |     x <= f64::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:45:5
+  --> $DIR/invalid-nan-comparison.rs:70:5
    |
 LL |     x >= f64::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:47:5
+  --> $DIR/invalid-nan-comparison.rs:72:5
    |
 LL |     number!() == f64::NAN;
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +216,7 @@ LL +     number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:49:5
+  --> $DIR/invalid-nan-comparison.rs:74:5
    |
 LL |     f64::NAN != number!();
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -155,5 +227,77 @@ LL -     f64::NAN != number!();
 LL +     !number!().is_nan();
    |
 
-warning: 17 warnings emitted
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:81:5
+   |
+LL |     x == f128::NAN;
+   |     ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x == f128::NAN;
+LL +     x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:83:5
+   |
+LL |     x != f128::NAN;
+   |     ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x != f128::NAN;
+LL +     !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:85:5
+   |
+LL |     x < f128::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:87:5
+   |
+LL |     x > f128::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:89:5
+   |
+LL |     x <= f128::NAN;
+   |     ^^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:91:5
+   |
+LL |     x >= f128::NAN;
+   |     ^^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:93:5
+   |
+LL |     number!() == f128::NAN;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     number!() == f128::NAN;
+LL +     number!().is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:95:5
+   |
+LL |     f128::NAN != number!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     f128::NAN != number!();
+LL +     !number!().is_nan();
+   |
+
+warning: 33 warnings emitted
 
diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
index d88615186dd..6bc4501b6a3 100644
--- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr
+++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will f
 LL |     foo(_x);
    |         ^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let _x: () = return;
+   |           ++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
index ec49137ba79..79f47bb5fbc 100644
--- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
+++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail
 LL |         false => <_>::default(),
    |                   ^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         false => <()>::default(),
+   |                   ~~
 
 warning: this function depends on never type fallback being `()`
   --> $DIR/dependency-on-fallback-to-unit.rs:19:1
@@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     deserialize::<()>()?;
+   |                ++++++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
index 2a3c5edc218..d40d1da76f9 100644
--- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail
 LL |         x = UnitDefault::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let x: ();
+   |          ++++
 
 warning: this function depends on never type fallback being `()`
   --> $DIR/diverging-fallback-control-flow.rs:42:1
@@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail
    |
 LL |         x = UnitDefault::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let x: ();
+   |          ++++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
index 11245cc7aab..d11c21d9573 100644
--- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Test` will fail
 LL |     unconstrained_arg(return);
    |                       ^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     unconstrained_arg::<()>(return);
+   |                      ++++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
index b485c94df4d..30a5e60a758 100644
--- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail
 LL |     let _ = if true { unconstrained_return() } else { panic!() };
    |                       ^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let _: () = if true { unconstrained_return() } else { panic!() };
+   |          ++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
index 3fb5536dee7..fb0166dd9e0 100644
--- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
+++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Bar` will fail
 LL |     foo(|| panic!());
    |     ^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     foo::<(), _>(|| panic!());
+   |        +++++++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
index a75039b8237..6a48a7b9b47 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
@@ -8,6 +8,10 @@ LL |         unsafe { mem::zeroed() }
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { mem::zeroed::<()>() }
+   |                             ++++++
 
 warning: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13
@@ -18,6 +22,10 @@ LL |             core::mem::transmute(Zst)
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             core::mem::transmute::<_, ()>(Zst)
+   |                                 +++++++++
 
 warning: never type fallback affects this union access
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18
@@ -38,6 +46,10 @@ LL |         unsafe { *ptr::from_ref(&()).cast() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { *ptr::from_ref(&()).cast::<()>() }
+   |                                          ++++++
 
 warning: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18
@@ -48,6 +60,10 @@ LL |         unsafe { internally_create(x) }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { internally_create::<()>(x) }
+   |                                   ++++++
 
 warning: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18
@@ -58,6 +74,10 @@ LL |         unsafe { zeroed() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 warning: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22
@@ -68,6 +88,10 @@ LL |         let zeroed = mem::zeroed;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 warning: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17
@@ -78,6 +102,10 @@ LL |         let f = internally_create;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let f = internally_create::<()>;
+   |                                  ++++++
 
 warning: never type fallback affects this call to an `unsafe` method
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13
@@ -102,6 +130,10 @@ LL |         msg_send!();
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             match send_message::<() /* ?0 */>() {
+   |                                  ~~
 
 warning: 10 warnings emitted
 
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
index 4138e9f8c86..844cd62c267 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
@@ -8,6 +8,10 @@ LL |         unsafe { mem::zeroed() }
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { mem::zeroed::<()>() }
+   |                             ++++++
 
 error: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13
@@ -18,6 +22,10 @@ LL |             core::mem::transmute(Zst)
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             core::mem::transmute::<_, ()>(Zst)
+   |                                 +++++++++
 
 error: never type fallback affects this union access
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18
@@ -38,6 +46,10 @@ LL |         unsafe { *ptr::from_ref(&()).cast() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { *ptr::from_ref(&()).cast::<()>() }
+   |                                          ++++++
 
 error: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18
@@ -48,6 +60,10 @@ LL |         unsafe { internally_create(x) }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { internally_create::<()>(x) }
+   |                                   ++++++
 
 error: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18
@@ -58,6 +74,10 @@ LL |         unsafe { zeroed() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 error: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22
@@ -68,6 +88,10 @@ LL |         let zeroed = mem::zeroed;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 error: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17
@@ -78,6 +102,10 @@ LL |         let f = internally_create;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let f = internally_create::<()>;
+   |                                  ++++++
 
 error: never type fallback affects this call to an `unsafe` method
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13
@@ -102,6 +130,10 @@ LL |         msg_send!();
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             match send_message::<() /* ?0 */>() {
+   |                                  ~~
 
 warning: the type `!` does not permit zero-initialization
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18