about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-11-18 05:11:23 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-11-18 05:11:23 +0000
commitf71a0427145afabcde4d1a9b746bc0f91d6003a0 (patch)
tree1da03fa3c2eb29aa72590b2d6163585d44a22101
parent0a4d828e897cfe400db9f849e760f29c1d9296cf (diff)
parentc6974344a5707c054ed808ea9c724dd93ec3c680 (diff)
downloadrust-f71a0427145afabcde4d1a9b746bc0f91d6003a0.tar.gz
rust-f71a0427145afabcde4d1a9b746bc0f91d6003a0.zip
Merge from rustc
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs114
-rw-r--r--compiler/rustc_ast/src/visit.rs84
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml1
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl6
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs23
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs70
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs13
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs160
-rw-r--r--compiler/rustc_borrowck/src/lib.rs93
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs9
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs41
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs20
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs9
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs3
-rw-r--r--compiler/rustc_expand/src/expand.rs4
-rw-r--r--compiler/rustc_expand/src/placeholders.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs51
-rw-r--r--compiler/rustc_lint/src/early.rs23
-rw-r--r--compiler/rustc_lint/src/unused.rs9
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs4
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs36
-rw-r--r--compiler/rustc_middle/src/lint.rs11
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs15
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs35
-rw-r--r--compiler/rustc_middle/src/query/erase.rs4
-rw-r--r--compiler/rustc_middle/src/query/keys.rs9
-rw-r--r--compiler/rustc_middle/src/query/mod.rs13
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs10
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs11
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs56
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs16
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/results.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/visitor.rs143
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/points.rs21
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs18
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs12
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs134
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs1
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs4
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs15
-rw-r--r--compiler/rustc_parse/src/errors.rs3
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs11
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs109
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/target_features.rs37
-rw-r--r--library/alloc/src/string.rs2
-rw-r--r--library/core/src/intrinsics/mod.rs73
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/num/int_macros.rs2
-rw-r--r--library/core/src/num/uint_macros.rs2
-rw-r--r--library/core/src/ptr/const_ptr.rs8
-rw-r--r--library/core/src/ptr/mod.rs16
-rw-r--r--library/core/src/ptr/mut_ptr.rs6
-rw-r--r--library/core/src/slice/raw.rs4
-rw-r--r--library/core/src/sync/atomic.rs6
-rw-r--r--library/core/src/ub_checks.rs16
-rw-r--r--src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile2
-rw-r--r--src/librustdoc/html/static/js/search.js20
m---------src/tools/cargo0
-rw-r--r--src/tools/miri/tests/pass/shims/time-with-isolation.stdout2
-rw-r--r--src/tools/run-make-support/src/external_deps/c_build.rs2
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs (renamed from src/tools/run-make-support/src/external_deps/cc.rs)98
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs97
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/gcc.rs66
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/mod.rs7
-rw-r--r--src/tools/run-make-support/src/external_deps/mod.rs2
-rw-r--r--src/tools/run-make-support/src/lib.rs4
-rw-r--r--src/tools/rustfmt/src/items.rs11
-rw-r--r--src/tools/rustfmt/src/visitor.rs17
-rw-r--r--src/tools/tidy/src/target_specific_tests.rs34
-rw-r--r--tests/codegen/checked_math.rs2
-rw-r--r--tests/codegen/intrinsics/cold_path.rs13
-rw-r--r--tests/codegen/intrinsics/likely.rs37
-rw-r--r--tests/codegen/intrinsics/likely_assert.rs17
-rw-r--r--tests/codegen/intrinsics/unlikely.rs35
-rw-r--r--tests/crashes/123077-2.rs12
-rw-r--r--tests/crashes/129150.rs7
-rw-r--r--tests/crashes/130687.rs4
-rw-r--r--tests/crashes/131535.rs4
-rw-r--r--tests/crashes/131637.rs7
-rw-r--r--tests/crashes/132530.rs9
-rw-r--r--tests/debuginfo/numeric-types.rs64
-rw-r--r--tests/debuginfo/range-types.rs20
-rw-r--r--tests/debuginfo/unit-type.rs11
-rw-r--r--tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir23
-rw-r--r--tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir23
-rw-r--r--tests/run-make/mte-ffi/rmake.rs17
-rw-r--r--tests/rustdoc-js-std/parser-errors.js8
-rw-r--r--tests/rustdoc-js-std/path-end-empty.js6
-rw-r--r--tests/ui-fulldeps/stable-mir/check_intrinsics.rs6
-rw-r--r--tests/ui/consts/const-ptr-is-null.rs1
-rw-r--r--tests/ui/consts/const-ptr-is-null.stderr2
-rw-r--r--tests/ui/consts/is_val_statically_known.rs2
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs12
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr15
-rw-r--r--tests/ui/consts/ptr_is_null.rs1
-rw-r--r--tests/ui/delegation/unsupported.rs8
-rw-r--r--tests/ui/delegation/unsupported.stderr61
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.fixed6
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr6
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.rs6
-rw-r--r--tests/ui/impl-trait/precise-capturing/auxiliary/no-use-macro.rs20
-rw-r--r--tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs29
-rw-r--r--tests/ui/impl-trait/precise-capturing/external-macro.rs26
-rw-r--r--tests/ui/intrinsics/reify-intrinsic.rs6
-rw-r--r--tests/ui/intrinsics/reify-intrinsic.stderr6
-rw-r--r--tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs31
-rw-r--r--tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr82
-rw-r--r--tests/ui/issues/issue-39848.stderr6
-rw-r--r--tests/ui/let-else/let-else-if.stderr2
-rw-r--r--tests/ui/lint/issue-104392.stderr2
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed8
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.rs8
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr69
-rw-r--r--tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.fixed32
-rw-r--r--tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.rs32
-rw-r--r--tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.stderr43
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.fixed2
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.rs2
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.stderr2
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.fixed2
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.rs2
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.stderr18
-rw-r--r--tests/ui/missing/missing-block-hint.stderr2
-rw-r--r--tests/ui/never_type/defaulted-never-note.nofallback.stderr2
-rw-r--r--tests/ui/never_type/defaulted-never-note.rs2
-rw-r--r--tests/ui/never_type/dependency-on-fallback-to-unit.rs4
-rw-r--r--tests/ui/never_type/dependency-on-fallback-to-unit.stderr4
-rw-r--r--tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr4
-rw-r--r--tests/ui/never_type/diverging-fallback-control-flow.rs4
-rw-r--r--tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr2
-rw-r--r--tests/ui/never_type/diverging-fallback-no-leak.rs2
-rw-r--r--tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr2
-rw-r--r--tests/ui/never_type/diverging-fallback-unconstrained-return.rs2
-rw-r--r--tests/ui/never_type/fallback-closure-ret.nofallback.stderr2
-rw-r--r--tests/ui/never_type/fallback-closure-ret.rs2
-rw-r--r--tests/ui/never_type/impl_trait_fallback.rs2
-rw-r--r--tests/ui/never_type/impl_trait_fallback.stderr2
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr20
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr20
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs20
-rw-r--r--tests/ui/parser/bad-if-statements.stderr4
-rw-r--r--tests/ui/parser/block-no-opening-brace.stderr6
-rw-r--r--tests/ui/parser/closure-return-syntax.stderr2
-rw-r--r--tests/ui/parser/else-no-if.stderr18
-rw-r--r--tests/ui/parser/label-after-block-like.stderr14
-rw-r--r--tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.fixed39
-rw-r--r--tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.rs39
-rw-r--r--tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.stderr57
-rw-r--r--tests/ui/parser/recover/missing-dot-on-if-condition-expression.rs57
-rw-r--r--tests/ui/parser/recover/missing-dot-on-if-condition-expression.stderr101
-rw-r--r--tests/ui/parser/unnecessary-let.fixed13
-rw-r--r--tests/ui/parser/unnecessary-let.rs4
-rw-r--r--tests/ui/parser/unnecessary-let.stderr24
-rw-r--r--tests/ui/pattern/usefulness/conflicting_bindings.rs2
-rw-r--r--tests/ui/pattern/usefulness/conflicting_bindings.stderr18
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs11
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr18
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs25
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-6.rs6
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-6.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr14
-rw-r--r--tests/ui/unsafe/unsafe-block-without-braces.stderr2
-rw-r--r--triagebot.toml2
182 files changed, 2433 insertions, 1090 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b98c4fd0642..e5025a1ba4f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3270,6 +3270,7 @@ name = "rustc_ast_lowering"
 version = "0.0.0"
 dependencies = [
  "rustc_ast",
+ "rustc_ast_pretty",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fluent_macro",
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 44bb44cb728..a09aa9ee665 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -23,7 +23,7 @@ use crate::ast::*;
 use crate::ptr::P;
 use crate::token::{self, Token};
 use crate::tokenstream::*;
-use crate::visit::{AssocCtxt, BoundKind};
+use crate::visit::{AssocCtxt, BoundKind, FnCtxt};
 
 pub trait ExpectOne<A: Array> {
     fn expect_one(self, err: &'static str) -> A::Item;
@@ -37,7 +37,16 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
 }
 
 pub trait WalkItemKind {
-    fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor);
+    type Ctxt;
+    fn walk(
+        &mut self,
+        span: Span,
+        id: NodeId,
+        ident: &mut Ident,
+        visibility: &mut Visibility,
+        ctxt: Self::Ctxt,
+        visitor: &mut impl MutVisitor,
+    );
 }
 
 pub trait MutVisitor: Sized {
@@ -114,9 +123,9 @@ pub trait MutVisitor: Sized {
     fn flat_map_assoc_item(
         &mut self,
         i: P<AssocItem>,
-        _ctxt: AssocCtxt,
+        ctxt: AssocCtxt,
     ) -> SmallVec<[P<AssocItem>; 1]> {
-        walk_flat_map_item(self, i)
+        walk_flat_map_assoc_item(self, i, ctxt)
     }
 
     fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
@@ -880,7 +889,7 @@ fn walk_coroutine_kind<T: MutVisitor>(vis: &mut T, coroutine_kind: &mut Coroutin
 
 fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
     match kind {
-        FnKind::Fn(FnSig { header, decl, span }, generics, body) => {
+        FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span }, _visibility, generics, body) => {
             // Identifier and visibility are visited as a part of the item.
             vis.visit_fn_header(header);
             vis.visit_generics(generics);
@@ -890,8 +899,9 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
             }
             vis.visit_span(span);
         }
-        FnKind::Closure(binder, decl, body) => {
+        FnKind::Closure(binder, coroutine_kind, decl, body) => {
             vis.visit_closure_binder(binder);
+            coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind));
             vis.visit_fn_decl(decl);
             vis.visit_expr(body);
         }
@@ -1079,17 +1089,29 @@ pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) {
     vis.visit_span(span);
 }
 
-pub fn walk_item_kind(
-    kind: &mut impl WalkItemKind,
+pub fn walk_item_kind<K: WalkItemKind>(
+    kind: &mut K,
     span: Span,
     id: NodeId,
+    ident: &mut Ident,
+    visibility: &mut Visibility,
+    ctxt: K::Ctxt,
     vis: &mut impl MutVisitor,
 ) {
-    kind.walk(span, id, vis)
+    kind.walk(span, id, ident, visibility, ctxt, vis)
 }
 
 impl WalkItemKind for ItemKind {
-    fn walk(&mut self, span: Span, id: NodeId, vis: &mut impl MutVisitor) {
+    type Ctxt = ();
+    fn walk(
+        &mut self,
+        span: Span,
+        id: NodeId,
+        ident: &mut Ident,
+        visibility: &mut Visibility,
+        _ctxt: Self::Ctxt,
+        vis: &mut impl MutVisitor,
+    ) {
         match self {
             ItemKind::ExternCrate(_orig_name) => {}
             ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
@@ -1102,7 +1124,11 @@ impl WalkItemKind for ItemKind {
             }
             ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
                 visit_defaultness(vis, defaultness);
-                vis.visit_fn(FnKind::Fn(sig, generics, body), span, id);
+                vis.visit_fn(
+                    FnKind::Fn(FnCtxt::Free, ident, sig, visibility, generics, body),
+                    span,
+                    id,
+                );
             }
             ItemKind::Mod(safety, mod_kind) => {
                 visit_safety(vis, safety);
@@ -1201,14 +1227,27 @@ impl WalkItemKind for ItemKind {
 }
 
 impl WalkItemKind for AssocItemKind {
-    fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) {
+    type Ctxt = AssocCtxt;
+    fn walk(
+        &mut self,
+        span: Span,
+        id: NodeId,
+        ident: &mut Ident,
+        visibility: &mut Visibility,
+        ctxt: Self::Ctxt,
+        visitor: &mut impl MutVisitor,
+    ) {
         match self {
             AssocItemKind::Const(item) => {
                 visit_const_item(item, visitor);
             }
             AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
                 visit_defaultness(visitor, defaultness);
-                visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id);
+                visitor.visit_fn(
+                    FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, visibility, generics, body),
+                    span,
+                    id,
+                );
             }
             AssocItemKind::Type(box TyAlias {
                 defaultness,
@@ -1288,24 +1327,40 @@ pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
     vis.visit_span(inject_use_span);
 }
 
-/// Mutates one item, returning the item again.
-pub fn walk_flat_map_item<K: WalkItemKind>(
+pub fn walk_flat_map_item<K: WalkItemKind<Ctxt = ()>>(
+    visitor: &mut impl MutVisitor,
+    item: P<Item<K>>,
+) -> SmallVec<[P<Item<K>>; 1]> {
+    walk_flat_map_assoc_item(visitor, item, ())
+}
+
+pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
     visitor: &mut impl MutVisitor,
     mut item: P<Item<K>>,
+    ctxt: K::Ctxt,
 ) -> SmallVec<[P<Item<K>>; 1]> {
     let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
     visitor.visit_id(id);
     visit_attrs(visitor, attrs);
     visitor.visit_vis(vis);
     visitor.visit_ident(ident);
-    kind.walk(*span, *id, visitor);
+    kind.walk(*span, *id, ident, vis, ctxt, visitor);
     visit_lazy_tts(visitor, tokens);
     visitor.visit_span(span);
     smallvec![item]
 }
 
 impl WalkItemKind for ForeignItemKind {
-    fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) {
+    type Ctxt = ();
+    fn walk(
+        &mut self,
+        span: Span,
+        id: NodeId,
+        ident: &mut Ident,
+        visibility: &mut Visibility,
+        _ctxt: Self::Ctxt,
+        visitor: &mut impl MutVisitor,
+    ) {
         match self {
             ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
                 visitor.visit_ty(ty);
@@ -1313,7 +1368,11 @@ impl WalkItemKind for ForeignItemKind {
             }
             ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
                 visit_defaultness(visitor, defaultness);
-                visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id);
+                visitor.visit_fn(
+                    FnKind::Fn(FnCtxt::Foreign, ident, sig, visibility, generics, body),
+                    span,
+                    id,
+                );
             }
             ForeignItemKind::TyAlias(box TyAlias {
                 defaultness,
@@ -1522,9 +1581,8 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
             fn_arg_span,
         }) => {
             visit_constness(vis, constness);
-            coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind));
             vis.visit_capture_by(capture_clause);
-            vis.visit_fn(FnKind::Closure(binder, fn_decl, body), *span, *id);
+            vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id);
             vis.visit_span(fn_decl_span);
             vis.visit_span(fn_arg_span);
         }
@@ -1785,8 +1843,20 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo
 #[derive(Debug)]
 pub enum FnKind<'a> {
     /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
-    Fn(&'a mut FnSig, &'a mut Generics, &'a mut Option<P<Block>>),
+    Fn(
+        FnCtxt,
+        &'a mut Ident,
+        &'a mut FnSig,
+        &'a mut Visibility,
+        &'a mut Generics,
+        &'a mut Option<P<Block>>,
+    ),
 
     /// E.g., `|x, y| body`.
-    Closure(&'a mut ClosureBinder, &'a mut P<FnDecl>, &'a mut P<Expr>),
+    Closure(
+        &'a mut ClosureBinder,
+        &'a mut Option<CoroutineKind>,
+        &'a mut P<FnDecl>,
+        &'a mut P<Expr>,
+    ),
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 58497d70a24..3500c215376 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -66,7 +66,7 @@ impl BoundKind {
 #[derive(Copy, Clone, Debug)]
 pub enum FnKind<'a> {
     /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
-    Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>),
+    Fn(FnCtxt, &'a Ident, &'a FnSig, &'a Visibility, &'a Generics, &'a Option<P<Block>>),
 
     /// E.g., `|x, y| body`.
     Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr),
@@ -112,11 +112,15 @@ pub enum LifetimeCtxt {
     GenericArg,
 }
 
-pub trait WalkItemKind: Sized {
+pub trait WalkItemKind {
+    type Ctxt;
     fn walk<'a, V: Visitor<'a>>(
         &'a self,
-        item: &'a Item<Self>,
-        ctxt: AssocCtxt,
+        span: Span,
+        id: NodeId,
+        ident: &'a Ident,
+        visibility: &'a Visibility,
+        ctxt: Self::Ctxt,
         visitor: &mut V,
     ) -> V::Result;
 }
@@ -268,8 +272,8 @@ pub trait Visitor<'ast>: Sized {
     fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result {
         walk_fn_ret_ty(self, ret_ty)
     }
-    fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result {
-        Self::Result::output()
+    fn visit_fn_header(&mut self, header: &'ast FnHeader) -> Self::Result {
+        walk_fn_header(self, header)
     }
     fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result {
         walk_expr_field(self, f)
@@ -292,6 +296,9 @@ pub trait Visitor<'ast>: Sized {
     fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result {
         Self::Result::output()
     }
+    fn visit_coroutine_kind(&mut self, _coroutine_kind: &'ast CoroutineKind) -> Self::Result {
+        Self::Result::output()
+    }
 }
 
 pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
@@ -337,16 +344,19 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR
 }
 
 impl WalkItemKind for ItemKind {
+    type Ctxt = ();
     fn walk<'a, V: Visitor<'a>>(
         &'a self,
-        item: &'a Item<Self>,
-        _ctxt: AssocCtxt,
+        span: Span,
+        id: NodeId,
+        ident: &'a Ident,
+        vis: &'a Visibility,
+        _ctxt: Self::Ctxt,
         visitor: &mut V,
     ) -> V::Result {
-        let Item { id, span, vis, ident, .. } = item;
         match self {
             ItemKind::ExternCrate(_rename) => {}
-            ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, *id, false)),
+            ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
             ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
@@ -357,8 +367,8 @@ impl WalkItemKind for ItemKind {
                 visit_opt!(visitor, visit_expr, expr);
             }
             ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
-                let kind = FnKind::Fn(FnCtxt::Free, *ident, sig, vis, generics, body.as_deref());
-                try_visit!(visitor.visit_fn(kind, *span, *id));
+                let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body);
+                try_visit!(visitor.visit_fn(kind, span, id));
             }
             ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
                 ModKind::Loaded(items, _inline, _inner_span) => {
@@ -415,7 +425,7 @@ impl WalkItemKind for ItemKind {
                 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
             }
             ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
-            ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, *id)),
+            ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, id)),
             ItemKind::Delegation(box Delegation {
                 id,
                 qself,
@@ -431,7 +441,7 @@ impl WalkItemKind for ItemKind {
             }
             ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
                 try_visit!(walk_qself(visitor, qself));
-                try_visit!(visitor.visit_path(prefix, *id));
+                try_visit!(visitor.visit_path(prefix, id));
                 if let Some(suffixes) = suffixes {
                     for (ident, rename) in suffixes {
                         visitor.visit_ident(ident);
@@ -449,9 +459,9 @@ impl WalkItemKind for ItemKind {
 
 pub fn walk_item<'a, V: Visitor<'a>>(
     visitor: &mut V,
-    item: &'a Item<impl WalkItemKind>,
+    item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
 ) -> V::Result {
-    walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/)
+    walk_assoc_item(visitor, item, ())
 }
 
 pub fn walk_enum_def<'a, V: Visitor<'a>>(
@@ -681,20 +691,23 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
 }
 
 impl WalkItemKind for ForeignItemKind {
+    type Ctxt = ();
     fn walk<'a, V: Visitor<'a>>(
         &'a self,
-        item: &'a Item<Self>,
-        _ctxt: AssocCtxt,
+        span: Span,
+        id: NodeId,
+        ident: &'a Ident,
+        vis: &'a Visibility,
+        _ctxt: Self::Ctxt,
         visitor: &mut V,
     ) -> V::Result {
-        let &Item { id, span, ident, ref vis, .. } = item;
         match self {
             ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
             }
             ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
-                let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
+                let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body);
                 try_visit!(visitor.visit_fn(kind, span, id));
             }
             ForeignItemKind::TyAlias(box TyAlias {
@@ -813,6 +826,12 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy)
     V::Result::output()
 }
 
+pub fn walk_fn_header<'a, V: Visitor<'a>>(visitor: &mut V, fn_header: &'a FnHeader) -> V::Result {
+    let FnHeader { safety: _, coroutine_kind, constness: _, ext: _ } = fn_header;
+    visit_opt!(visitor, visit_coroutine_kind, coroutine_kind.as_ref());
+    V::Result::output()
+}
+
 pub fn walk_fn_decl<'a, V: Visitor<'a>>(
     visitor: &mut V,
     FnDecl { inputs, output }: &'a FnDecl,
@@ -830,8 +849,9 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
             try_visit!(walk_fn_decl(visitor, decl));
             visit_opt!(visitor, visit_block, body);
         }
-        FnKind::Closure(binder, _coroutine_kind, decl, body) => {
+        FnKind::Closure(binder, coroutine_kind, decl, body) => {
             try_visit!(visitor.visit_closure_binder(binder));
+            visit_opt!(visitor, visit_coroutine_kind, coroutine_kind.as_ref());
             try_visit!(walk_fn_decl(visitor, decl));
             try_visit!(visitor.visit_expr(body));
         }
@@ -840,13 +860,16 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
 }
 
 impl WalkItemKind for AssocItemKind {
+    type Ctxt = AssocCtxt;
     fn walk<'a, V: Visitor<'a>>(
         &'a self,
-        item: &'a Item<Self>,
-        ctxt: AssocCtxt,
+        span: Span,
+        id: NodeId,
+        ident: &'a Ident,
+        vis: &'a Visibility,
+        ctxt: Self::Ctxt,
         visitor: &mut V,
     ) -> V::Result {
-        let &Item { id, span, ident, ref vis, .. } = item;
         match self {
             AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
                 try_visit!(visitor.visit_generics(generics));
@@ -854,8 +877,7 @@ impl WalkItemKind for AssocItemKind {
                 visit_opt!(visitor, visit_expr, expr);
             }
             AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
-                let kind =
-                    FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
+                let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body);
                 try_visit!(visitor.visit_fn(kind, span, id));
             }
             AssocItemKind::Type(box TyAlias {
@@ -903,16 +925,16 @@ impl WalkItemKind for AssocItemKind {
     }
 }
 
-pub fn walk_assoc_item<'a, V: Visitor<'a>>(
+pub fn walk_assoc_item<'a, V: Visitor<'a>, K: WalkItemKind>(
     visitor: &mut V,
-    item: &'a Item<impl WalkItemKind>,
-    ctxt: AssocCtxt,
+    item: &'a Item<K>,
+    ctxt: K::Ctxt,
 ) -> V::Result {
-    let Item { id: _, span: _, ident, vis, attrs, kind, tokens: _ } = item;
+    let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item;
     walk_list!(visitor, visit_attribute, attrs);
     try_visit!(visitor.visit_vis(vis));
     try_visit!(visitor.visit_ident(ident));
-    try_visit!(kind.walk(item, ctxt, visitor));
+    try_visit!(kind.walk(*span, *id, ident, vis, ctxt, visitor));
     V::Result::output()
 }
 
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index c47c12b4fd1..8cc4521e0a7 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -9,6 +9,7 @@ doctest = false
 [dependencies]
 # tidy-alphabetical-start
 rustc_ast = { path = "../rustc_ast" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index a5ee6713be8..f704320c71d 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -103,6 +103,12 @@ ast_lowering_invalid_asm_template_modifier_reg_class =
 ast_lowering_invalid_asm_template_modifier_sym =
     asm template modifiers are not allowed for `sym` arguments
 
+ast_lowering_invalid_legacy_const_generic_arg =
+    invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+
+ast_lowering_invalid_legacy_const_generic_arg_suggestion =
+    try using a const generic argument instead
+
 ast_lowering_invalid_register =
     invalid register `{$reg}`: {$error}
 
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 6b39c2d3955..e6a3f939f2d 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -451,3 +451,26 @@ pub(crate) struct YieldInClosure {
     #[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
     pub suggestion: Option<Span>,
 }
+
+#[derive(Diagnostic)]
+#[diag(ast_lowering_invalid_legacy_const_generic_arg)]
+pub(crate) struct InvalidLegacyConstGenericArg {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub suggestion: UseConstGenericArg,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    ast_lowering_invalid_legacy_const_generic_arg_suggestion,
+    applicability = "maybe-incorrect"
+)]
+pub(crate) struct UseConstGenericArg {
+    #[suggestion_part(code = "::<{const_args}>")]
+    pub end_of_fn: Span,
+    pub const_args: String,
+    pub other_args: String,
+    #[suggestion_part(code = "{other_args}")]
+    pub call_args: Span,
+}
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index b7cf2d252dc..3af29838b72 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1,18 +1,22 @@
 use std::assert_matches::assert_matches;
+use std::ops::ControlFlow;
 
 use rustc_ast::ptr::P as AstP;
 use rustc_ast::*;
+use rustc_ast_pretty::pprust::expr_to_string;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::HirId;
 use rustc_hir::def::{DefKind, Res};
 use rustc_middle::span_bug;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::errors::report_lit_error;
 use rustc_span::source_map::{Spanned, respan};
 use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use rustc_span::{DUMMY_SP, DesugaringKind, Span};
 use thin_vec::{ThinVec, thin_vec};
+use visit::{Visitor, walk_expr};
 
 use super::errors::{
     AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
@@ -23,9 +27,32 @@ use super::errors::{
 use super::{
     GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
 };
-use crate::errors::YieldInClosure;
+use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
 use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated};
 
+struct WillCreateDefIdsVisitor {}
+
+impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor {
+    type Result = ControlFlow<Span>;
+
+    fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
+        ControlFlow::Break(c.value.span)
+    }
+
+    fn visit_item(&mut self, item: &'v Item) -> Self::Result {
+        ControlFlow::Break(item.span)
+    }
+
+    fn visit_expr(&mut self, ex: &'v Expr) -> Self::Result {
+        match ex.kind {
+            ExprKind::Gen(..) | ExprKind::ConstBlock(..) | ExprKind::Closure(..) => {
+                ControlFlow::Break(ex.span)
+            }
+            _ => walk_expr(self, ex),
+        }
+    }
+}
+
 impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
         self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x)))
@@ -396,10 +423,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
             unreachable!();
         };
 
+        let mut error = None;
+        let mut invalid_expr_error = |tcx: TyCtxt<'_>, span| {
+            // Avoid emitting the error multiple times.
+            if error.is_none() {
+                let mut const_args = vec![];
+                let mut other_args = vec![];
+                for (idx, arg) in args.iter().enumerate() {
+                    if legacy_args_idx.contains(&idx) {
+                        const_args.push(format!("{{ {} }}", expr_to_string(arg)));
+                    } else {
+                        other_args.push(expr_to_string(arg));
+                    }
+                }
+                let suggestion = UseConstGenericArg {
+                    end_of_fn: f.span.shrink_to_hi(),
+                    const_args: const_args.join(", "),
+                    other_args: other_args.join(", "),
+                    call_args: args[0].span.to(args.last().unwrap().span),
+                };
+                error = Some(tcx.dcx().emit_err(InvalidLegacyConstGenericArg { span, suggestion }));
+            }
+            error.unwrap()
+        };
+
         // Split the arguments into const generics and normal arguments
         let mut real_args = vec![];
         let mut generic_args = ThinVec::new();
-        for (idx, arg) in args.into_iter().enumerate() {
+        for (idx, arg) in args.iter().cloned().enumerate() {
             if legacy_args_idx.contains(&idx) {
                 let parent_def_id = self.current_def_id_parent;
                 let node_id = self.next_node_id();
@@ -410,7 +461,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
                 }
 
-                let anon_const = AnonConst { id: node_id, value: arg };
+                let mut visitor = WillCreateDefIdsVisitor {};
+                let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
+                    AstP(Expr {
+                        id: self.next_node_id(),
+                        kind: ExprKind::Err(invalid_expr_error(self.tcx, span)),
+                        span: f.span,
+                        attrs: [].into(),
+                        tokens: None,
+                    })
+                } else {
+                    arg
+                };
+
+                let anon_const = AnonConst { id: node_id, value: const_value };
                 generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
             } else {
                 real_args.push(arg);
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5a0e9e8aec0..d53280751fc 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -738,7 +738,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         allow_internal_unstable: Option<Lrc<[Symbol]>>,
     ) -> Span {
         self.tcx.with_stable_hashing_context(|hcx| {
-            span.mark_with_reason(allow_internal_unstable, reason, self.tcx.sess.edition(), hcx)
+            span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
         })
     }
 
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index dee48586f34..07a6f4e5ee7 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -946,8 +946,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
                 self.visit_vis(&item.vis);
                 self.visit_ident(&item.ident);
-                let kind =
-                    FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
+                let kind = FnKind::Fn(FnCtxt::Free, &item.ident, sig, &item.vis, generics, body);
                 self.visit_fn(kind, item.span, item.id);
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
@@ -1476,14 +1475,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             {
                 self.visit_vis(&item.vis);
                 self.visit_ident(&item.ident);
-                let kind = FnKind::Fn(
-                    FnCtxt::Assoc(ctxt),
-                    item.ident,
-                    sig,
-                    &item.vis,
-                    generics,
-                    body.as_deref(),
-                );
+                let kind =
+                    FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, sig, &item.vis, generics, body);
                 walk_list!(self, visit_attribute, &item.attrs);
                 self.visit_fn(kind, item.span, item.id);
             }
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index d832decc170..7adc7a8863e 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -1,93 +1,171 @@
+use std::fmt;
+
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::graph;
 use rustc_index::bit_set::BitSet;
-use rustc_middle::mir::{self, BasicBlock, Body, Location, Place, TerminatorEdges};
+use rustc_middle::mir::{
+    self, BasicBlock, Body, CallReturnPlaces, Location, Place, TerminatorEdges,
+};
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::fmt::DebugWithContext;
 use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
-use rustc_mir_dataflow::{Analysis, Forward, GenKill, Results, ResultsVisitable};
+use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice, SwitchIntEdgeEffects};
 use tracing::debug;
 
 use crate::{BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict};
 
-/// The results of the dataflow analyses used by the borrow checker.
-pub(crate) struct BorrowckResults<'a, 'tcx> {
-    pub(crate) borrows: Results<'tcx, Borrows<'a, 'tcx>>,
-    pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
-    pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'tcx>>,
-}
-
-/// The transient state of the dataflow analyses used by the borrow checker.
-#[derive(Debug)]
-pub(crate) struct BorrowckDomain<'a, 'tcx> {
-    pub(crate) borrows: <Borrows<'a, 'tcx> as Analysis<'tcx>>::Domain,
-    pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
-    pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
+// This analysis is different to most others. Its results aren't computed with
+// `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are
+// computed individually with `iterate_to_fixpoint`.
+pub(crate) struct Borrowck<'a, 'tcx> {
+    pub(crate) borrows: Borrows<'a, 'tcx>,
+    pub(crate) uninits: MaybeUninitializedPlaces<'a, 'tcx>,
+    pub(crate) ever_inits: EverInitializedPlaces<'a, 'tcx>,
 }
 
-impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
-    type Direction = Forward;
+impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
     type Domain = BorrowckDomain<'a, 'tcx>;
 
+    const NAME: &'static str = "borrowck";
+
     fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
         BorrowckDomain {
-            borrows: self.borrows.analysis.bottom_value(body),
-            uninits: self.uninits.analysis.bottom_value(body),
-            ever_inits: self.ever_inits.analysis.bottom_value(body),
+            borrows: self.borrows.bottom_value(body),
+            uninits: self.uninits.bottom_value(body),
+            ever_inits: self.ever_inits.bottom_value(body),
         }
     }
 
-    fn reset_to_block_entry(&self, state: &mut Self::Domain, block: BasicBlock) {
-        state.borrows.clone_from(self.borrows.entry_set_for_block(block));
-        state.uninits.clone_from(self.uninits.entry_set_for_block(block));
-        state.ever_inits.clone_from(self.ever_inits.entry_set_for_block(block));
+    fn initialize_start_block(&self, _body: &mir::Body<'tcx>, _state: &mut Self::Domain) {
+        // This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
+        unreachable!();
     }
 
-    fn reconstruct_before_statement_effect(
+    fn apply_before_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
-        self.borrows.analysis.apply_before_statement_effect(&mut state.borrows, stmt, loc);
-        self.uninits.analysis.apply_before_statement_effect(&mut state.uninits, stmt, loc);
-        self.ever_inits.analysis.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
+        self.borrows.apply_before_statement_effect(&mut state.borrows, stmt, loc);
+        self.uninits.apply_before_statement_effect(&mut state.uninits, stmt, loc);
+        self.ever_inits.apply_before_statement_effect(&mut state.ever_inits, stmt, loc);
     }
 
-    fn reconstruct_statement_effect(
+    fn apply_statement_effect(
         &mut self,
         state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
-        self.borrows.analysis.apply_statement_effect(&mut state.borrows, stmt, loc);
-        self.uninits.analysis.apply_statement_effect(&mut state.uninits, stmt, loc);
-        self.ever_inits.analysis.apply_statement_effect(&mut state.ever_inits, stmt, loc);
+        self.borrows.apply_statement_effect(&mut state.borrows, stmt, loc);
+        self.uninits.apply_statement_effect(&mut state.uninits, stmt, loc);
+        self.ever_inits.apply_statement_effect(&mut state.ever_inits, stmt, loc);
     }
 
-    fn reconstruct_before_terminator_effect(
+    fn apply_before_terminator_effect(
         &mut self,
         state: &mut Self::Domain,
         term: &mir::Terminator<'tcx>,
         loc: Location,
     ) {
-        self.borrows.analysis.apply_before_terminator_effect(&mut state.borrows, term, loc);
-        self.uninits.analysis.apply_before_terminator_effect(&mut state.uninits, term, loc);
-        self.ever_inits.analysis.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
+        self.borrows.apply_before_terminator_effect(&mut state.borrows, term, loc);
+        self.uninits.apply_before_terminator_effect(&mut state.uninits, term, loc);
+        self.ever_inits.apply_before_terminator_effect(&mut state.ever_inits, term, loc);
     }
 
-    fn reconstruct_terminator_effect(
+    fn apply_terminator_effect<'mir>(
         &mut self,
         state: &mut Self::Domain,
-        term: &mir::Terminator<'tcx>,
+        term: &'mir mir::Terminator<'tcx>,
         loc: Location,
+    ) -> TerminatorEdges<'mir, 'tcx> {
+        self.borrows.apply_terminator_effect(&mut state.borrows, term, loc);
+        self.uninits.apply_terminator_effect(&mut state.uninits, term, loc);
+        self.ever_inits.apply_terminator_effect(&mut state.ever_inits, term, loc);
+
+        // This return value doesn't matter. It's only used by `iterate_to_fixpoint`, which this
+        // analysis doesn't use.
+        TerminatorEdges::None
+    }
+
+    fn apply_call_return_effect(
+        &mut self,
+        _state: &mut Self::Domain,
+        _block: BasicBlock,
+        _return_places: CallReturnPlaces<'_, 'tcx>,
+    ) {
+        // This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
+        unreachable!();
+    }
+
+    fn apply_switch_int_edge_effects(
+        &mut self,
+        _block: BasicBlock,
+        _discr: &mir::Operand<'tcx>,
+        _apply_edge_effects: &mut impl SwitchIntEdgeEffects<Self::Domain>,
     ) {
-        self.borrows.analysis.apply_terminator_effect(&mut state.borrows, term, loc);
-        self.uninits.analysis.apply_terminator_effect(&mut state.uninits, term, loc);
-        self.ever_inits.analysis.apply_terminator_effect(&mut state.ever_inits, term, loc);
+        // This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
+        unreachable!();
     }
 }
 
+impl JoinSemiLattice for BorrowckDomain<'_, '_> {
+    fn join(&mut self, _other: &Self) -> bool {
+        // This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
+        unreachable!();
+    }
+}
+
+impl<'tcx, C> DebugWithContext<C> for BorrowckDomain<'_, 'tcx>
+where
+    C: rustc_mir_dataflow::move_paths::HasMoveData<'tcx>,
+{
+    fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("borrows: ")?;
+        self.borrows.fmt_with(ctxt, f)?;
+        f.write_str(" uninits: ")?;
+        self.uninits.fmt_with(ctxt, f)?;
+        f.write_str(" ever_inits: ")?;
+        self.ever_inits.fmt_with(ctxt, f)?;
+        Ok(())
+    }
+
+    fn fmt_diff_with(&self, old: &Self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if self == old {
+            return Ok(());
+        }
+
+        if self.borrows != old.borrows {
+            f.write_str("borrows: ")?;
+            self.borrows.fmt_diff_with(&old.borrows, ctxt, f)?;
+            f.write_str("\n")?;
+        }
+
+        if self.uninits != old.uninits {
+            f.write_str("uninits: ")?;
+            self.uninits.fmt_diff_with(&old.uninits, ctxt, f)?;
+            f.write_str("\n")?;
+        }
+
+        if self.ever_inits != old.ever_inits {
+            f.write_str("ever_inits: ")?;
+            self.ever_inits.fmt_diff_with(&old.ever_inits, ctxt, f)?;
+            f.write_str("\n")?;
+        }
+
+        Ok(())
+    }
+}
+
+/// The transient state of the dataflow analyses used by the borrow checker.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub(crate) struct BorrowckDomain<'a, 'tcx> {
+    pub(crate) borrows: <Borrows<'a, 'tcx> as Analysis<'tcx>>::Domain,
+    pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
+    pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain,
+}
+
 rustc_index::newtype_index! {
     #[orderable]
     #[debug_format = "bw{}"]
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 657e6e0907c..7eaf265d410 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -36,13 +36,13 @@ use rustc_middle::mir::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
 use rustc_middle::{bug, span_bug};
-use rustc_mir_dataflow::Analysis;
 use rustc_mir_dataflow::impls::{
     EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
 };
 use rustc_mir_dataflow::move_paths::{
     InitIndex, InitLocation, LookupResult, MoveData, MoveOutIndex, MovePathIndex,
 };
+use rustc_mir_dataflow::{Analysis, EntrySets, Results, ResultsVisitor, visit_results};
 use rustc_session::lint::builtin::UNUSED_MUT;
 use rustc_span::{Span, Symbol};
 use smallvec::SmallVec;
@@ -50,7 +50,7 @@ use tracing::{debug, instrument};
 
 use crate::borrow_set::{BorrowData, BorrowSet};
 use crate::consumers::{BodyWithBorrowckFacts, ConsumerOptions};
-use crate::dataflow::{BorrowIndex, BorrowckDomain, BorrowckResults, Borrows};
+use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows};
 use crate::diagnostics::{AccessKind, IllegalMoveOriginKind, MoveError, RegionName};
 use crate::location::LocationTable;
 use crate::nll::PoloniusOutput;
@@ -221,6 +221,10 @@ fn do_mir_borrowck<'tcx>(
         consumer_options,
     );
 
+    // `flow_inits` is large, so we drop it as soon as possible. This reduces
+    // peak memory usage significantly on some benchmarks.
+    drop(flow_inits);
+
     // Dump MIR results into a file, if that is enabled. This let us
     // write unit-tests, as well as helping with debugging.
     nll::dump_nll_mir(&infcx, body, &regioncx, &opt_closure_req, &borrow_set);
@@ -229,27 +233,6 @@ fn do_mir_borrowck<'tcx>(
     // information.
     nll::dump_annotation(&infcx, body, &regioncx, &opt_closure_req, &opaque_type_values, diags);
 
-    // The various `flow_*` structures can be large. We drop `flow_inits` here
-    // so it doesn't overlap with the others below. This reduces peak memory
-    // usage significantly on some benchmarks.
-    drop(flow_inits);
-
-    let flow_borrows = Borrows::new(tcx, body, &regioncx, &borrow_set).iterate_to_fixpoint(
-        tcx,
-        body,
-        Some("borrowck"),
-    );
-    let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data).iterate_to_fixpoint(
-        tcx,
-        body,
-        Some("borrowck"),
-    );
-    let flow_ever_inits = EverInitializedPlaces::new(body, &move_data).iterate_to_fixpoint(
-        tcx,
-        body,
-        Some("borrowck"),
-    );
-
     let movable_coroutine =
         // The first argument is the coroutine type passed by value
         if let Some(local) = body.local_decls.raw.get(1)
@@ -334,16 +317,11 @@ fn do_mir_borrowck<'tcx>(
     // Compute and report region errors, if any.
     mbcx.report_region_errors(nll_errors);
 
-    let mut results = BorrowckResults {
-        ever_inits: flow_ever_inits,
-        uninits: flow_uninits,
-        borrows: flow_borrows,
-    };
-
-    rustc_mir_dataflow::visit_results(
+    let mut flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
+    visit_results(
         body,
         traversal::reverse_postorder(body).map(|(bb, _)| bb),
-        &mut results,
+        &mut flow_results,
         &mut mbcx,
     );
 
@@ -426,6 +404,47 @@ fn do_mir_borrowck<'tcx>(
     (result, body_with_facts)
 }
 
+fn get_flow_results<'a, 'tcx>(
+    tcx: TyCtxt<'tcx>,
+    body: &'a Body<'tcx>,
+    move_data: &'a MoveData<'tcx>,
+    borrow_set: &'a BorrowSet<'tcx>,
+    regioncx: &RegionInferenceContext<'tcx>,
+) -> Results<'tcx, Borrowck<'a, 'tcx>> {
+    // We compute these three analyses individually, but them combine them into
+    // a single results so that `mbcx` can visit them all together.
+    let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
+        tcx,
+        body,
+        Some("borrowck"),
+    );
+    let uninits = MaybeUninitializedPlaces::new(tcx, body, move_data).iterate_to_fixpoint(
+        tcx,
+        body,
+        Some("borrowck"),
+    );
+    let ever_inits = EverInitializedPlaces::new(body, move_data).iterate_to_fixpoint(
+        tcx,
+        body,
+        Some("borrowck"),
+    );
+
+    let analysis = Borrowck {
+        borrows: borrows.analysis,
+        uninits: uninits.analysis,
+        ever_inits: ever_inits.analysis,
+    };
+
+    assert_eq!(borrows.entry_sets.len(), uninits.entry_sets.len());
+    assert_eq!(borrows.entry_sets.len(), ever_inits.entry_sets.len());
+    let entry_sets: EntrySets<'_, Borrowck<'_, '_>> =
+        itertools::izip!(borrows.entry_sets, uninits.entry_sets, ever_inits.entry_sets)
+            .map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
+            .collect();
+
+    Results { analysis, entry_sets }
+}
+
 pub(crate) struct BorrowckInferCtxt<'tcx> {
     pub(crate) infcx: InferCtxt<'tcx>,
     pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
@@ -588,14 +607,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
 // 2. loans made in overlapping scopes do not conflict
 // 3. assignments do not affect things loaned out as immutable
 // 4. moves do not affect things loaned out in any way
-impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
-    for MirBorrowckCtxt<'a, '_, 'tcx>
-{
-    type Domain = BorrowckDomain<'a, 'tcx>;
-
+impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
     fn visit_statement_before_primary_effect(
         &mut self,
-        _results: &mut R,
+        _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
         state: &BorrowckDomain<'a, 'tcx>,
         stmt: &'a Statement<'tcx>,
         location: Location,
@@ -667,7 +682,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
 
     fn visit_terminator_before_primary_effect(
         &mut self,
-        _results: &mut R,
+        _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
         state: &BorrowckDomain<'a, 'tcx>,
         term: &'a Terminator<'tcx>,
         loc: Location,
@@ -780,7 +795,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
 
     fn visit_terminator_after_primary_effect(
         &mut self,
-        _results: &mut R,
+        _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
         state: &BorrowckDomain<'a, 'tcx>,
         term: &'a Terminator<'tcx>,
         loc: Location,
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index f419c1e776b..e7ee6b43e27 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -204,10 +204,10 @@ impl MutVisitor for CfgEval<'_> {
     fn flat_map_assoc_item(
         &mut self,
         item: P<ast::AssocItem>,
-        _ctxt: AssocCtxt,
+        ctxt: AssocCtxt,
     ) -> SmallVec<[P<ast::AssocItem>; 1]> {
         let item = configure!(self, item);
-        mut_visit::walk_flat_map_item(self, item)
+        mut_visit::walk_flat_map_assoc_item(self, item, ctxt)
     }
 
     fn flat_map_foreign_item(
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 95348453308..ba5d34359aa 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -144,7 +144,15 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
             item.kind
         {
             let prev_tests = mem::take(&mut self.tests);
-            walk_item_kind(&mut item.kind, item.span, item.id, self);
+            walk_item_kind(
+                &mut item.kind,
+                item.span,
+                item.id,
+                &mut item.ident,
+                &mut item.vis,
+                (),
+                self,
+            );
             self.add_test_cases(item.id, span, prev_tests);
         } else {
             // But in those cases, we emit a lint to warn the user of these missing tests.
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 1e2e41b3122..b92885cc1a7 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -453,11 +453,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
             fx.bcx.ins().trap(TrapCode::user(2).unwrap());
             return Ok(());
         }
-        sym::likely | sym::unlikely => {
-            intrinsic_args!(fx, args => (a); intrinsic);
-
-            ret.write_cvalue(fx, a);
-        }
         sym::breakpoint => {
             intrinsic_args!(fx, args => (); intrinsic);
 
@@ -1267,6 +1262,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
             );
         }
 
+        sym::cold_path => {
+            // This is a no-op. The intrinsic is just a hint to the optimizer.
+        }
+
         // Unimplemented intrinsics must have a fallback body. The fallback body is obtained
         // by converting the `InstanceKind::Intrinsic` to an `InstanceKind::Item`.
         _ => {
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index b0298a35cb0..225f294e1e4 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -139,8 +139,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
                     &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                 )
             }
-            sym::likely => self.expect(args[0].immediate(), true),
-            sym::unlikely => self.expect(args[0].immediate(), false),
             sym::is_val_statically_known => {
                 let a = args[0].immediate();
                 let builtin = self.context.get_builtin_function("__builtin_constant_p");
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index e9c687d75e3..b56f464975d 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -192,7 +192,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     Some(instance),
                 )
             }
-            sym::likely => self.expect(args[0].immediate(), true),
             sym::is_val_statically_known => {
                 let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx);
                 let kind = self.type_kind(intrinsic_type);
@@ -213,7 +212,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     self.const_bool(false)
                 }
             }
-            sym::unlikely => self.expect(args[0].immediate(), false),
             sym::select_unpredictable => {
                 let cond = args[0].immediate();
                 assert_eq!(args[1].layout, args[2].layout);
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 027d80350e4..097d37bb70c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -377,20 +377,32 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             // If there are two targets (one conditional, one fallback), emit `br` instead of
             // `switch`.
             let (test_value, target) = target_iter.next().unwrap();
-            let lltrue = helper.llbb_with_cleanup(self, target);
-            let llfalse = helper.llbb_with_cleanup(self, targets.otherwise());
+            let otherwise = targets.otherwise();
+            let lltarget = helper.llbb_with_cleanup(self, target);
+            let llotherwise = helper.llbb_with_cleanup(self, otherwise);
+            let target_cold = self.cold_blocks[target];
+            let otherwise_cold = self.cold_blocks[otherwise];
+            // If `target_cold == otherwise_cold`, the branches have the same weight
+            // so there is no expectation. If they differ, the `target` branch is expected
+            // when the `otherwise` branch is cold.
+            let expect = if target_cold == otherwise_cold { None } else { Some(otherwise_cold) };
             if switch_ty == bx.tcx().types.bool {
                 // Don't generate trivial icmps when switching on bool.
                 match test_value {
-                    0 => bx.cond_br(discr_value, llfalse, lltrue),
-                    1 => bx.cond_br(discr_value, lltrue, llfalse),
+                    0 => {
+                        let expect = expect.map(|e| !e);
+                        bx.cond_br_with_expect(discr_value, llotherwise, lltarget, expect);
+                    }
+                    1 => {
+                        bx.cond_br_with_expect(discr_value, lltarget, llotherwise, expect);
+                    }
                     _ => bug!(),
                 }
             } else {
                 let switch_llty = bx.immediate_backend_type(bx.layout_of(switch_ty));
                 let llval = bx.const_uint_big(switch_llty, test_value);
                 let cmp = bx.icmp(IntPredicate::IntEQ, discr_value, llval);
-                bx.cond_br(cmp, lltrue, llfalse);
+                bx.cond_br_with_expect(cmp, lltarget, llotherwise, expect);
             }
         } else if self.cx.sess().opts.optimize == OptLevel::No
             && target_iter.len() == 2
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index c9e38bb80c2..2a1b9e28c1e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -498,6 +498,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
+            sym::cold_path => {
+                // This is a no-op. The intrinsic is just a hint to the optimizer.
+                return Ok(());
+            }
+
             _ => {
                 // Need to use backend-specific things in the implementation.
                 return bx.codegen_intrinsic_call(instance, fn_abi, args, llresult, span);
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 20fd08923ec..f19e3b72141 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -91,6 +91,10 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
     /// Cached terminate upon unwinding block and its reason
     terminate_block: Option<(Bx::BasicBlock, UnwindTerminateReason)>,
 
+    /// A bool flag for each basic block indicating whether it is a cold block.
+    /// A cold block is a block that is unlikely to be executed at runtime.
+    cold_blocks: IndexVec<mir::BasicBlock, bool>,
+
     /// The location where each MIR arg/var/tmp/ret is stored. This is
     /// usually an `PlaceRef` representing an alloca, but not always:
     /// sometimes we can skip the alloca and just store the value
@@ -207,6 +211,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         cleanup_kinds,
         landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
         funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
+        cold_blocks: find_cold_blocks(cx.tcx(), mir),
         locals: locals::Locals::empty(),
         debug_context,
         per_local_var_debug_info: None,
@@ -477,3 +482,39 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
     args
 }
+
+fn find_cold_blocks<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mir: &mir::Body<'tcx>,
+) -> IndexVec<mir::BasicBlock, bool> {
+    let local_decls = &mir.local_decls;
+
+    let mut cold_blocks: IndexVec<mir::BasicBlock, bool> =
+        IndexVec::from_elem(false, &mir.basic_blocks);
+
+    // Traverse all basic blocks from end of the function to the start.
+    for (bb, bb_data) in traversal::postorder(mir) {
+        let terminator = bb_data.terminator();
+
+        // If a BB ends with a call to a cold function, mark it as cold.
+        if let mir::TerminatorKind::Call { ref func, .. } = terminator.kind
+            && let ty::FnDef(def_id, ..) = *func.ty(local_decls, tcx).kind()
+            && let attrs = tcx.codegen_fn_attrs(def_id)
+            && attrs.flags.contains(CodegenFnAttrFlags::COLD)
+        {
+            cold_blocks[bb] = true;
+            continue;
+        }
+
+        // If all successors of a BB are cold and there's at least one of them, mark this BB as cold
+        let mut succ = terminator.successors();
+        if let Some(first) = succ.next()
+            && cold_blocks[first]
+            && succ.all(|s| cold_blocks[s])
+        {
+            cold_blocks[bb] = true;
+        }
+    }
+
+    cold_blocks
+}
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 74cd522a30f..b0138ac8bfe 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -84,6 +84,26 @@ pub trait BuilderMethods<'a, 'tcx>:
         then_llbb: Self::BasicBlock,
         else_llbb: Self::BasicBlock,
     );
+
+    // Conditional with expectation.
+    //
+    // This function is opt-in for back ends.
+    //
+    // The default implementation calls `self.expect()` before emiting the branch
+    // by calling `self.cond_br()`
+    fn cond_br_with_expect(
+        &mut self,
+        mut cond: Self::Value,
+        then_llbb: Self::BasicBlock,
+        else_llbb: Self::BasicBlock,
+        expect: Option<bool>,
+    ) {
+        if let Some(expect) = expect {
+            cond = self.expect(cond, expect);
+        }
+        self.cond_br(cond, then_llbb, else_llbb)
+    }
+
     fn switch(
         &mut self,
         v: Self::Value,
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 6686413bf02..1271d9d2d0d 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -152,13 +152,20 @@ where
             let span = span.substitute_dummy(our_span);
             let err = mk(span, frames);
             let mut err = tcx.dcx().create_err(err);
+            let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_));
 
             let msg = error.diagnostic_message();
             error.add_args(&mut err);
 
             // Use *our* span to label the interp error
             err.span_label(our_span, msg);
-            ErrorHandled::Reported(err.emit().into(), span)
+            let g = err.emit();
+            let reported = if can_be_spurious {
+                ReportedErrorInfo::spurious(g)
+            } else {
+                ReportedErrorInfo::from(g)
+            };
+            ErrorHandled::Reported(reported, span)
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 62115aef4a7..f12320cb851 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -263,6 +263,12 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
     }
 
     /// See documentation on the `ptr_guaranteed_cmp` intrinsic.
+    /// Returns `2` if the result is unknown.
+    /// Returns `1` if the pointers are guaranteed equal.
+    /// Returns `0` if the pointers are guaranteed inequal.
+    ///
+    /// Note that this intrinsic is exposed on stable for comparison with null. In other words, any
+    /// change to this function that affects comparison with null is insta-stable!
     fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
         interp_ok(match (a, b) {
             // Comparisons between integers are always known.
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index ff6d5b28b3b..eb574bd5f77 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -596,6 +596,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                                 // const-eval will return "tainted" errors if e.g. the layout cannot
                                 // be computed as the type references non-existing names.
                                 // See <https://github.com/rust-lang/rust/issues/124348>.
+                            } else if reported.can_be_spurious() {
+                                // These errors can just sometimes happen, even when the expression
+                                // is nominally "infallible", e.g. when running out of memory.
                             } else {
                                 // Looks like the const is not captured by `required_consts`, that's bad.
                                 span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index c7a56a80e81..d89d73824aa 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -417,6 +417,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 // These just return their argument
                 self.copy_op(&args[0], dest)?;
             }
+            sym::cold_path => {
+                // This is a no-op. The intrinsic is just a hint to the optimizer.
+            }
             sym::raw_eq => {
                 let result = self.raw_eq_intrinsic(&args[0], &args[1])?;
                 self.write_scalar(result, dest)?;
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 04ac7891023..91786462b40 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1303,7 +1303,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
         fragment.make_trait_items()
     }
     fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
-        walk_flat_map_item(visitor, self.wrapped)
+        walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Trait)
     }
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1344,7 +1344,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
         fragment.make_impl_items()
     }
     fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
-        walk_flat_map_item(visitor, self.wrapped)
+        walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl)
     }
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 610c69e9d21..90206b19bd5 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -286,7 +286,7 @@ impl MutVisitor for PlaceholderExpander {
                     AssocCtxt::Impl => it.make_impl_items(),
                 }
             }
-            _ => walk_flat_map_item(self, item),
+            _ => walk_flat_map_assoc_item(self, item, ctxt),
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index cb954b0adcb..3e33120901f 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -109,9 +109,8 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
         | sym::three_way_compare
         | sym::discriminant_value
         | sym::type_id
-        | sym::likely
-        | sym::unlikely
         | sym::select_unpredictable
+        | sym::cold_path
         | sym::ptr_guaranteed_cmp
         | sym::minnumf16
         | sym::minnumf32
@@ -489,9 +488,8 @@ pub fn check_intrinsic_type(
             sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
 
             sym::assume => (0, 0, vec![tcx.types.bool], tcx.types.unit),
-            sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
-            sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
             sym::select_unpredictable => (1, 0, vec![tcx.types.bool, param(0), param(0)], param(0)),
+            sym::cold_path => (0, 0, vec![], tcx.types.unit),
 
             sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
             sym::write_via_move => {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index cc55f57c46c..b4b3ef31f97 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -177,6 +177,7 @@ enum Scope<'a> {
     LateBoundary {
         s: ScopeRef<'a>,
         what: &'static str,
+        deny_late_regions: bool,
     },
 
     Root {
@@ -234,9 +235,11 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
                 .field("s", &"..")
                 .finish(),
             Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
-            Scope::LateBoundary { s: _, what } => {
-                f.debug_struct("LateBoundary").field("what", what).finish()
-            }
+            Scope::LateBoundary { s: _, what, deny_late_regions } => f
+                .debug_struct("LateBoundary")
+                .field("what", what)
+                .field("deny_late_regions", deny_late_regions)
+                .finish(),
             Scope::Root { opt_parent_item } => {
                 f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
             }
@@ -573,17 +576,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             // give, we will reverse the IndexMap after early captures.
             let mut late_depth = 0;
             let mut scope = self.scope;
-            let mut crossed_late_boundary = None;
             let mut opaque_capture_scopes = vec![(opaque.def_id, &captures)];
             loop {
                 match *scope {
                     Scope::Binder { ref bound_vars, scope_type, s, .. } => {
                         for (&original_lifetime, &def) in bound_vars.iter().rev() {
-                            if let ResolvedArg::LateBound(..) = def
-                                && crossed_late_boundary.is_some()
-                            {
-                                continue;
-                            }
                             if let DefKind::LifetimeParam = self.tcx.def_kind(original_lifetime) {
                                 let def = def.shifted(late_depth);
                                 let ident = lifetime_ident(original_lifetime);
@@ -624,12 +621,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
                     Scope::ObjectLifetimeDefault { s, .. }
                     | Scope::Supertrait { s, .. }
-                    | Scope::TraitRefBoundary { s, .. } => {
-                        scope = s;
-                    }
-
-                    Scope::LateBoundary { s, what, .. } => {
-                        crossed_late_boundary = Some(what);
+                    | Scope::TraitRefBoundary { s, .. }
+                    | Scope::LateBoundary { s, .. } => {
                         scope = s;
                     }
                 }
@@ -640,7 +633,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         let scope = Scope::Opaque { captures: &captures, def_id: opaque.def_id, s: self.scope };
         self.with(scope, |this| {
             let scope = Scope::TraitRefBoundary { s: this.scope };
-            this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
+            this.with(scope, |this| {
+                let scope = Scope::LateBoundary {
+                    s: this.scope,
+                    what: "nested `impl Trait`",
+                    // We can capture late-bound regions; we just don't duplicate
+                    // lifetime or const params, so we can't allow those.
+                    deny_late_regions: false,
+                };
+                this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
+            })
         });
 
         let captures = captures.into_inner().into_iter().collect();
@@ -997,9 +999,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
     }
 
     fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
-        self.with(Scope::LateBoundary { s: self.scope, what: "constant" }, |this| {
-            intravisit::walk_anon_const(this, c);
-        });
+        self.with(
+            Scope::LateBoundary { s: self.scope, what: "constant", deny_late_regions: true },
+            |this| {
+                intravisit::walk_anon_const(this, c);
+            },
+        );
     }
 
     fn visit_generic_param(&mut self, p: &'tcx GenericParam<'tcx>) {
@@ -1291,8 +1296,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     scope = s;
                 }
 
-                Scope::LateBoundary { s, what } => {
-                    crossed_late_boundary = Some(what);
+                Scope::LateBoundary { s, what, deny_late_regions } => {
+                    if deny_late_regions {
+                        crossed_late_boundary = Some(what);
+                    }
                     scope = s;
                 }
             }
@@ -1508,7 +1515,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     scope = s;
                 }
 
-                Scope::LateBoundary { s, what } => {
+                Scope::LateBoundary { s, what, deny_late_regions: _ } => {
                     crossed_late_boundary = Some(what);
                     scope = s;
                 }
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index acccff77a10..ef9b3dbd13b 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -68,6 +68,10 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
 }
 
 impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
+    fn visit_coroutine_kind(&mut self, coroutine_kind: &'a ast::CoroutineKind) -> Self::Result {
+        self.check_id(coroutine_kind.closure_id());
+    }
+
     fn visit_param(&mut self, param: &'a ast::Param) {
         self.with_lint_attrs(param.id, &param.attrs, |cx| {
             lint_callback!(cx, check_param, param);
@@ -111,17 +115,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         self.with_lint_attrs(e.id, &e.attrs, |cx| {
             lint_callback!(cx, check_expr, e);
             ast_visit::walk_expr(cx, e);
-            // Explicitly check for lints associated with 'closure_id', since
-            // it does not have a corresponding AST node
-            match e.kind {
-                ast::ExprKind::Closure(box ast::Closure {
-                    coroutine_kind: Some(coroutine_kind),
-                    ..
-                }) => {
-                    cx.check_id(coroutine_kind.closure_id());
-                }
-                _ => {}
-            }
             lint_callback!(cx, check_expr_post, e);
         })
     }
@@ -156,14 +149,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         lint_callback!(self, check_fn, fk, span, id);
         self.check_id(id);
         ast_visit::walk_fn(self, fk);
-
-        // Explicitly check for lints associated with 'closure_id', since
-        // it does not have a corresponding AST node
-        if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
-            if let Some(coroutine_kind) = sig.header.coroutine_kind {
-                self.check_id(coroutine_kind.closure_id());
-            }
-        }
     }
 
     fn visit_variant_data(&mut self, s: &'a ast::VariantData) {
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index b50a95e7d2b..6c13127b04e 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -584,6 +584,7 @@ enum UnusedDelimsCtx {
     MatchScrutineeExpr,
     ReturnValue,
     BlockRetValue,
+    BreakValue,
     LetScrutineeExpr,
     ArrayLenExpr,
     AnonConst,
@@ -605,6 +606,7 @@ impl From<UnusedDelimsCtx> for &'static str {
             UnusedDelimsCtx::MatchScrutineeExpr => "`match` scrutinee expression",
             UnusedDelimsCtx::ReturnValue => "`return` value",
             UnusedDelimsCtx::BlockRetValue => "block return value",
+            UnusedDelimsCtx::BreakValue => "`break` value",
             UnusedDelimsCtx::LetScrutineeExpr => "`let` scrutinee expression",
             UnusedDelimsCtx::ArrayLenExpr | UnusedDelimsCtx::AnonConst => "const expression",
             UnusedDelimsCtx::MatchArmExpr => "match arm expression",
@@ -913,6 +915,10 @@ trait UnusedDelimLint {
                 (value, UnusedDelimsCtx::ReturnValue, false, Some(left), None, true)
             }
 
+            Break(_, Some(ref value)) => {
+                (value, UnusedDelimsCtx::BreakValue, false, None, None, true)
+            }
+
             Index(_, ref value, _) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
 
             Assign(_, ref value, _) | AssignOp(.., ref value) => {
@@ -1063,6 +1069,9 @@ impl UnusedDelimLint for UnusedParens {
                                 _,
                                 _,
                             ) if node.is_lazy()))
+                    && !((ctx == UnusedDelimsCtx::ReturnValue
+                        || ctx == UnusedDelimsCtx::BreakValue)
+                        && matches!(inner.kind, ast::ExprKind::Assign(_, _, _)))
                 {
                     self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
                 }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 51146cfd2e9..efdb4b077e9 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4185,7 +4185,7 @@ declare_lint! {
     Warn,
     "never type fallback affecting unsafe function calls",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
+        reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024),
         reference: "issue #123748 <https://github.com/rust-lang/rust/issues/123748>",
     };
     @edition Edition2024 => Deny;
@@ -4239,7 +4239,7 @@ declare_lint! {
     Warn,
     "never type fallback affecting unsafe function calls",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024),
         reference: "issue #123748 <https://github.com/rust-lang/rust/issues/123748>",
     };
     report_in_external_macro
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 0caf6ef3a6d..eac4afee050 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -381,6 +381,8 @@ pub enum FutureIncompatibilityReason {
     /// hard errors (and the lint removed). Preferably when there is some
     /// confidence that the number of impacted projects is very small (few
     /// should have a broken dependency in their dependency tree).
+    ///
+    /// [`EditionAndFutureReleaseError`]: FutureIncompatibilityReason::EditionAndFutureReleaseError
     FutureReleaseErrorReportInDeps,
     /// Code that changes meaning in some way in a
     /// future release.
@@ -419,6 +421,28 @@ pub enum FutureIncompatibilityReason {
     /// slightly changes the text of the diagnostic, but is otherwise the
     /// same.
     EditionSemanticsChange(Edition),
+    /// This will be an error in the provided edition *and* in a future
+    /// release.
+    ///
+    /// This variant a combination of [`FutureReleaseErrorDontReportInDeps`]
+    /// and [`EditionError`]. This is useful in rare cases when we
+    /// want to have "preview" of a breaking change in an edition, but do a
+    /// breaking change later on all editions anyway.
+    ///
+    /// [`EditionError`]: FutureIncompatibilityReason::EditionError
+    /// [`FutureReleaseErrorDontReportInDeps`]: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps
+    EditionAndFutureReleaseError(Edition),
+    /// This will change meaning in the provided edition *and* in a future
+    /// release.
+    ///
+    /// This variant a combination of [`FutureReleaseSemanticsChange`]
+    /// and [`EditionSemanticsChange`]. This is useful in rare cases when we
+    /// want to have "preview" of a breaking change in an edition, but do a
+    /// breaking change later on all editions anyway.
+    ///
+    /// [`EditionSemanticsChange`]: FutureIncompatibilityReason::EditionSemanticsChange
+    /// [`FutureReleaseSemanticsChange`]: FutureIncompatibilityReason::FutureReleaseSemanticsChange
+    EditionAndFutureReleaseSemanticsChange(Edition),
     /// A custom reason.
     ///
     /// Choose this variant if the built-in text of the diagnostic of the
@@ -431,9 +455,15 @@ pub enum FutureIncompatibilityReason {
 impl FutureIncompatibilityReason {
     pub fn edition(self) -> Option<Edition> {
         match self {
-            Self::EditionError(e) => Some(e),
-            Self::EditionSemanticsChange(e) => Some(e),
-            _ => None,
+            Self::EditionError(e)
+            | Self::EditionSemanticsChange(e)
+            | Self::EditionAndFutureReleaseError(e)
+            | Self::EditionAndFutureReleaseSemanticsChange(e) => Some(e),
+
+            FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps
+            | FutureIncompatibilityReason::FutureReleaseErrorReportInDeps
+            | FutureIncompatibilityReason::FutureReleaseSemanticsChange
+            | FutureIncompatibilityReason::Custom(_) => None,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index b5862565e8e..92ba6ceee93 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -382,6 +382,17 @@ pub fn lint_level(
                 FutureIncompatibilityReason::EditionSemanticsChange(edition) => {
                     format!("this changes meaning in Rust {edition}")
                 }
+                FutureIncompatibilityReason::EditionAndFutureReleaseError(edition) => {
+                    format!(
+                        "this was previously accepted by the compiler but is being phased out; \
+                         it will become a hard error in Rust {edition} and in a future release in all editions!"
+                    )
+                }
+                FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(edition) => {
+                    format!(
+                        "this changes meaning in Rust {edition} and in a future release in all editions!"
+                    )
+                }
                 FutureIncompatibilityReason::Custom(reason) => reason.to_owned(),
             };
 
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 8ec7e1851a5..08afa33c6b4 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -59,22 +59,33 @@ impl ErrorHandled {
 pub struct ReportedErrorInfo {
     error: ErrorGuaranteed,
     is_tainted_by_errors: bool,
+    /// Whether this is the kind of error that can sometimes occur, and sometimes not.
+    /// Used for resource exhaustion errors.
+    can_be_spurious: bool,
 }
 
 impl ReportedErrorInfo {
     #[inline]
     pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
-        ReportedErrorInfo { is_tainted_by_errors: true, error }
+        ReportedErrorInfo { is_tainted_by_errors: true, can_be_spurious: false, error }
     }
+    #[inline]
+    pub fn spurious(error: ErrorGuaranteed) -> ReportedErrorInfo {
+        ReportedErrorInfo { can_be_spurious: true, is_tainted_by_errors: false, error }
+    }
+
     pub fn is_tainted_by_errors(&self) -> bool {
         self.is_tainted_by_errors
     }
+    pub fn can_be_spurious(&self) -> bool {
+        self.can_be_spurious
+    }
 }
 
 impl From<ErrorGuaranteed> for ReportedErrorInfo {
     #[inline]
     fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
-        ReportedErrorInfo { is_tainted_by_errors: false, error }
+        ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error }
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index d8d99deeb2c..244d22d082f 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -46,7 +46,7 @@ pub enum InstantiationMode {
     LocalCopy,
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable, TyEncodable, TyDecodable)]
 pub enum MonoItem<'tcx> {
     Fn(Instance<'tcx>),
     Static(DefId),
@@ -66,20 +66,7 @@ impl<'tcx> MonoItem<'tcx> {
     // change NON_INCR_MIN_CGU_SIZE as well.
     pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
         match *self {
-            MonoItem::Fn(instance) => {
-                match instance.def {
-                    // "Normal" functions size estimate: the number of
-                    // statements, plus one for the terminator.
-                    InstanceKind::Item(..)
-                    | InstanceKind::DropGlue(..)
-                    | InstanceKind::AsyncDropGlueCtorShim(..) => {
-                        let mir = tcx.instance_mir(instance.def);
-                        mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
-                    }
-                    // Other compiler-generated shims size estimate: 1
-                    _ => 1,
-                }
-            }
+            MonoItem::Fn(instance) => tcx.size_estimate(instance),
             // Conservatively estimate the size of a static declaration or
             // assembly item to be 1.
             MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
@@ -556,3 +543,21 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
         Symbol::intern(&cgu_name)
     }
 }
+
+/// See module-level docs of `rustc_monomorphize::collector` on some context for "mentioned" items.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum CollectionMode {
+    /// Collect items that are used, i.e., actually needed for codegen.
+    ///
+    /// Which items are used can depend on optimization levels, as MIR optimizations can remove
+    /// uses.
+    UsedItems,
+    /// Collect items that are mentioned. The goal of this mode is that it is independent of
+    /// optimizations: the set of "mentioned" items is computed before optimizations are run.
+    ///
+    /// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
+    /// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
+    /// might decide to run them before computing mentioned items.) The key property of this set is
+    /// that it is optimization-independent.
+    MentionedItems,
+}
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 1d4c36e28bd..013847f0b2d 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -216,6 +216,10 @@ impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) {
     type Result = [u8; size_of::<(&'static (), &'static [()])>()];
 }
 
+impl<T0, T1> EraseType for (&'_ [T0], &'_ [T1]) {
+    type Result = [u8; size_of::<(&'static [()], &'static [()])>()];
+}
+
 impl<T0> EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) {
     type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()];
 }
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index fe28ef0f70c..c5def5fc65b 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -7,6 +7,7 @@ use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{DUMMY_SP, Span};
 
 use crate::infer::canonical::CanonicalQueryInput;
+use crate::mir::mono::CollectionMode;
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::{TyAndLayout, ValidityRequirement};
 use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
@@ -590,3 +591,11 @@ impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) {
         }
     }
 }
+
+impl<'tcx> Key for (ty::Instance<'tcx>, CollectionMode) {
+    type Cache<V> = DefaultCache<Self, V>;
+
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+        self.0.default_span(tcx)
+    }
+}
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 4e3668822ec..4068d06f6df 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -40,6 +40,7 @@ use rustc_session::cstore::{
 };
 use rustc_session::lint::LintExpectationId;
 use rustc_span::def_id::LOCAL_CRATE;
+use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
 use rustc_span::{DUMMY_SP, Span};
 use rustc_target::spec::PanicStrategy;
@@ -59,7 +60,7 @@ use crate::mir::interpret::{
     EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
     EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput,
 };
-use crate::mir::mono::CodegenUnit;
+use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem};
 use crate::query::erase::{Erase, erase, restore};
 use crate::query::plumbing::{
     CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at,
@@ -2339,6 +2340,16 @@ rustc_queries! {
         arena_cache
         desc { "functions to skip for move-size check" }
     }
+
+    query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
+        desc { "collecting items used by `{}`", key.0 }
+        cache_on_disk_if { true }
+    }
+
+    query size_estimate(key: ty::Instance<'tcx>) -> usize {
+        desc { "estimating codegen size of `{}`", key }
+        cache_on_disk_if { true }
+    }
 }
 
 rustc_query_append! { define_callbacks! }
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 8b77a4a81ca..3849cb72668 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -12,6 +12,7 @@ use rustc_index::{Idx, IndexVec};
 use rustc_macros::{Decodable, Encodable};
 use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
+use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::mir::{self, interpret};
 use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -22,7 +23,7 @@ use rustc_session::Session;
 use rustc_span::hygiene::{
     ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
 };
-use rustc_span::source_map::SourceMap;
+use rustc_span::source_map::{SourceMap, Spanned};
 use rustc_span::{
     BytePos, CachingSourceMapView, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span,
     SpanDecoder, SpanEncoder, StableSourceFileId, Symbol,
@@ -773,6 +774,13 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsm
     }
 }
 
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Spanned<MonoItem<'tcx>>] {
+    #[inline]
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+        RefDecodable::decode(d)
+    }
+}
+
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
     for &'tcx crate::traits::specialization_graph::Graph
 {
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index b5358f0ca35..47a84d4b258 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -13,9 +13,11 @@ use std::marker::DiscriminantKind;
 use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::LocalDefId;
+use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::ty::TyCtxt;
 use rustc_serialize::{Decodable, Encodable};
 use rustc_span::Span;
+use rustc_span::source_map::Spanned;
 pub use rustc_type_ir::{TyDecoder, TyEncoder};
 
 use crate::arena::ArenaAllocatable;
@@ -397,6 +399,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
     }
 }
 
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [Spanned<MonoItem<'tcx>>] {
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder
+            .interner()
+            .arena
+            .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
+    }
+}
+
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
     for ty::List<ty::BoundVariableKind>
 {
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 3e01f0512c4..9a5cf9d4e84 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -4,8 +4,8 @@ use rustc_middle::mir::{
     self, BasicBlock, CallReturnPlaces, Location, SwitchTargets, TerminatorEdges,
 };
 
-use super::visitor::{ResultsVisitable, ResultsVisitor};
-use super::{Analysis, Effect, EffectIndex, SwitchIntTarget};
+use super::visitor::ResultsVisitor;
+use super::{Analysis, Effect, EffectIndex, Results, SwitchIntTarget};
 
 pub trait Direction {
     const IS_FORWARD: bool;
@@ -33,14 +33,14 @@ pub trait Direction {
     where
         A: Analysis<'tcx>;
 
-    fn visit_results_in_block<'mir, 'tcx, D, R>(
-        state: &mut D,
+    fn visit_results_in_block<'mir, 'tcx, A>(
+        state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-        results: &mut R,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = D>,
+        results: &mut Results<'tcx, A>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
     ) where
-        R: ResultsVisitable<'tcx, Domain = D>;
+        A: Analysis<'tcx>;
 
     fn join_state_into_successors_of<'tcx, A>(
         analysis: &mut A,
@@ -53,7 +53,7 @@ pub trait Direction {
         A: Analysis<'tcx>;
 }
 
-/// Dataflow that runs from the exit of a block (the terminator), to its entry (the first statement).
+/// Dataflow that runs from the exit of a block (terminator), to its entry (the first statement).
 pub struct Backward;
 
 impl Direction for Backward {
@@ -157,32 +157,32 @@ impl Direction for Backward {
         analysis.apply_statement_effect(state, statement, location);
     }
 
-    fn visit_results_in_block<'mir, 'tcx, D, R>(
-        state: &mut D,
+    fn visit_results_in_block<'mir, 'tcx, A>(
+        state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-        results: &mut R,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = D>,
+        results: &mut Results<'tcx, A>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
     ) where
-        R: ResultsVisitable<'tcx, Domain = D>,
+        A: Analysis<'tcx>,
     {
-        results.reset_to_block_entry(state, block);
+        state.clone_from(results.entry_set_for_block(block));
 
         vis.visit_block_end(state);
 
         // Terminator
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
-        results.reconstruct_before_terminator_effect(state, term, loc);
+        results.analysis.apply_before_terminator_effect(state, term, loc);
         vis.visit_terminator_before_primary_effect(results, state, term, loc);
-        results.reconstruct_terminator_effect(state, term, loc);
+        results.analysis.apply_terminator_effect(state, term, loc);
         vis.visit_terminator_after_primary_effect(results, state, term, loc);
 
         for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() {
             let loc = Location { block, statement_index };
-            results.reconstruct_before_statement_effect(state, stmt, loc);
+            results.analysis.apply_before_statement_effect(state, stmt, loc);
             vis.visit_statement_before_primary_effect(results, state, stmt, loc);
-            results.reconstruct_statement_effect(state, stmt, loc);
+            results.analysis.apply_statement_effect(state, stmt, loc);
             vis.visit_statement_after_primary_effect(results, state, stmt, loc);
         }
 
@@ -389,32 +389,32 @@ impl Direction for Forward {
         }
     }
 
-    fn visit_results_in_block<'mir, 'tcx, F, R>(
-        state: &mut F,
+    fn visit_results_in_block<'mir, 'tcx, A>(
+        state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-        results: &mut R,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = F>,
+        results: &mut Results<'tcx, A>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
     ) where
-        R: ResultsVisitable<'tcx, Domain = F>,
+        A: Analysis<'tcx>,
     {
-        results.reset_to_block_entry(state, block);
+        state.clone_from(results.entry_set_for_block(block));
 
         vis.visit_block_start(state);
 
         for (statement_index, stmt) in block_data.statements.iter().enumerate() {
             let loc = Location { block, statement_index };
-            results.reconstruct_before_statement_effect(state, stmt, loc);
+            results.analysis.apply_before_statement_effect(state, stmt, loc);
             vis.visit_statement_before_primary_effect(results, state, stmt, loc);
-            results.reconstruct_statement_effect(state, stmt, loc);
+            results.analysis.apply_statement_effect(state, stmt, loc);
             vis.visit_statement_after_primary_effect(results, state, stmt, loc);
         }
 
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
-        results.reconstruct_before_terminator_effect(state, term, loc);
+        results.analysis.apply_before_terminator_effect(state, term, loc);
         vis.visit_terminator_before_primary_effect(results, state, term, loc);
-        results.reconstruct_terminator_effect(state, term, loc);
+        results.analysis.apply_terminator_effect(state, term, loc);
         vis.visit_terminator_after_primary_effect(results, state, term, loc);
 
         vis.visit_block_end(state);
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index bac75b972f9..98a4f58cb5d 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -544,20 +544,18 @@ impl<D> StateDiffCollector<D> {
     }
 }
 
-impl<'tcx, A> ResultsVisitor<'_, 'tcx, Results<'tcx, A>> for StateDiffCollector<A::Domain>
+impl<'tcx, A> ResultsVisitor<'_, 'tcx, A> for StateDiffCollector<A::Domain>
 where
     A: Analysis<'tcx>,
     A::Domain: DebugWithContext<A>,
 {
-    type Domain = A::Domain;
-
-    fn visit_block_start(&mut self, state: &Self::Domain) {
+    fn visit_block_start(&mut self, state: &A::Domain) {
         if A::Direction::IS_FORWARD {
             self.prev_state.clone_from(state);
         }
     }
 
-    fn visit_block_end(&mut self, state: &Self::Domain) {
+    fn visit_block_end(&mut self, state: &A::Domain) {
         if A::Direction::IS_BACKWARD {
             self.prev_state.clone_from(state);
         }
@@ -566,7 +564,7 @@ where
     fn visit_statement_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::Domain,
+        state: &A::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -579,7 +577,7 @@ where
     fn visit_statement_after_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::Domain,
+        state: &A::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -590,7 +588,7 @@ where
     fn visit_terminator_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::Domain,
+        state: &A::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
@@ -603,7 +601,7 @@ where
     fn visit_terminator_after_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::Domain,
+        state: &A::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 8f81da8bb04..244dfe26ad3 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -55,8 +55,8 @@ mod visitor;
 pub use self::cursor::ResultsCursor;
 pub use self::direction::{Backward, Direction, Forward};
 pub use self::lattice::{JoinSemiLattice, MaybeReachable};
-pub use self::results::Results;
-pub use self::visitor::{ResultsVisitable, ResultsVisitor, visit_results};
+pub use self::results::{EntrySets, Results};
+pub use self::visitor::{ResultsVisitor, visit_results};
 
 /// Analysis domains are all bitsets of various kinds. This trait holds
 /// operations needed by all of them.
diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs
index 366fcbf33ba..ff6cafbfbae 100644
--- a/compiler/rustc_mir_dataflow/src/framework/results.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/results.rs
@@ -18,7 +18,7 @@ use crate::errors::{
     DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
 };
 
-type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
+pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
 
 /// A dataflow analysis that has converged to fixpoint.
 #[derive(Clone)]
@@ -27,7 +27,7 @@ where
     A: Analysis<'tcx>,
 {
     pub analysis: A,
-    pub(super) entry_sets: EntrySets<'tcx, A>,
+    pub entry_sets: EntrySets<'tcx, A>,
 }
 
 impl<'tcx, A> Results<'tcx, A>
@@ -51,7 +51,7 @@ where
         &mut self,
         body: &'mir mir::Body<'tcx>,
         blocks: impl IntoIterator<Item = BasicBlock>,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, Self, Domain = A::Domain>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
     ) {
         visit_results(body, blocks, self, vis)
     }
@@ -59,7 +59,7 @@ where
     pub fn visit_reachable_with<'mir>(
         &mut self,
         body: &'mir mir::Body<'tcx>,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, Self, Domain = A::Domain>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
     ) {
         let blocks = traversal::reachable(body);
         visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index 3d6b008a684..5c7539eed4d 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -4,15 +4,15 @@ use super::{Analysis, Direction, Results};
 
 /// Calls the corresponding method in `ResultsVisitor` for every location in a `mir::Body` with the
 /// dataflow state at that location.
-pub fn visit_results<'mir, 'tcx, D, R>(
+pub fn visit_results<'mir, 'tcx, A>(
     body: &'mir mir::Body<'tcx>,
     blocks: impl IntoIterator<Item = BasicBlock>,
-    results: &mut R,
-    vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = D>,
+    results: &mut Results<'tcx, A>,
+    vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
 ) where
-    R: ResultsVisitable<'tcx, Domain = D>,
+    A: Analysis<'tcx>,
 {
-    let mut state = results.bottom_value(body);
+    let mut state = results.analysis.bottom_value(body);
 
     #[cfg(debug_assertions)]
     let reachable_blocks = mir::traversal::reachable_as_bitset(body);
@@ -22,23 +22,23 @@ pub fn visit_results<'mir, 'tcx, D, R>(
         assert!(reachable_blocks.contains(block));
 
         let block_data = &body[block];
-        R::Direction::visit_results_in_block(&mut state, block, block_data, results, vis);
+        A::Direction::visit_results_in_block(&mut state, block, block_data, results, vis);
     }
 }
 
-/// A visitor over the results of an `Analysis`. The type parameter `R` is the results type being
-/// visited.
-pub trait ResultsVisitor<'mir, 'tcx, R> {
-    type Domain;
-
-    fn visit_block_start(&mut self, _state: &Self::Domain) {}
+/// A visitor over the results of an `Analysis`.
+pub trait ResultsVisitor<'mir, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    fn visit_block_start(&mut self, _state: &A::Domain) {}
 
     /// Called with the `before_statement_effect` of the given statement applied to `state` but not
     /// its `statement_effect`.
     fn visit_statement_before_primary_effect(
         &mut self,
-        _results: &mut R,
-        _state: &Self::Domain,
+        _results: &mut Results<'tcx, A>,
+        _state: &A::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -48,19 +48,19 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
     /// statement applied to `state`.
     fn visit_statement_after_primary_effect(
         &mut self,
-        _results: &mut R,
-        _state: &Self::Domain,
+        _results: &mut Results<'tcx, A>,
+        _state: &A::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         _location: Location,
     ) {
     }
 
-    /// Called with the `before_terminator_effect` of the given terminator applied to `state` but not
-    /// its `terminator_effect`.
+    /// Called with the `before_terminator_effect` of the given terminator applied to `state` but
+    /// not its `terminator_effect`.
     fn visit_terminator_before_primary_effect(
         &mut self,
-        _results: &mut R,
-        _state: &Self::Domain,
+        _results: &mut Results<'tcx, A>,
+        _state: &A::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         _location: Location,
     ) {
@@ -72,109 +72,12 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
     /// The `call_return_effect` (if one exists) will *not* be applied to `state`.
     fn visit_terminator_after_primary_effect(
         &mut self,
-        _results: &mut R,
-        _state: &Self::Domain,
+        _results: &mut Results<'tcx, A>,
+        _state: &A::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         _location: Location,
     ) {
     }
 
-    fn visit_block_end(&mut self, _state: &Self::Domain) {}
-}
-
-/// Things that can be visited by a `ResultsVisitor`.
-///
-/// This trait exists so that we can visit the results of one or more dataflow analyses
-/// simultaneously.
-pub trait ResultsVisitable<'tcx> {
-    type Direction: Direction;
-    type Domain;
-
-    /// Creates an empty `Domain` to hold the transient state for these dataflow results.
-    ///
-    /// The value of the newly created `Domain` will be overwritten by `reset_to_block_entry`
-    /// before it can be observed by a `ResultsVisitor`.
-    fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain;
-
-    fn reset_to_block_entry(&self, state: &mut Self::Domain, block: BasicBlock);
-
-    fn reconstruct_before_statement_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        statement: &mir::Statement<'tcx>,
-        location: Location,
-    );
-
-    fn reconstruct_statement_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        statement: &mir::Statement<'tcx>,
-        location: Location,
-    );
-
-    fn reconstruct_before_terminator_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        terminator: &mir::Terminator<'tcx>,
-        location: Location,
-    );
-
-    fn reconstruct_terminator_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        terminator: &mir::Terminator<'tcx>,
-        location: Location,
-    );
-}
-
-impl<'tcx, A> ResultsVisitable<'tcx> for Results<'tcx, A>
-where
-    A: Analysis<'tcx>,
-{
-    type Domain = A::Domain;
-    type Direction = A::Direction;
-
-    fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
-        self.analysis.bottom_value(body)
-    }
-
-    fn reset_to_block_entry(&self, state: &mut Self::Domain, block: BasicBlock) {
-        state.clone_from(self.entry_set_for_block(block));
-    }
-
-    fn reconstruct_before_statement_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        stmt: &mir::Statement<'tcx>,
-        loc: Location,
-    ) {
-        self.analysis.apply_before_statement_effect(state, stmt, loc);
-    }
-
-    fn reconstruct_statement_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        stmt: &mir::Statement<'tcx>,
-        loc: Location,
-    ) {
-        self.analysis.apply_statement_effect(state, stmt, loc);
-    }
-
-    fn reconstruct_before_terminator_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        term: &mir::Terminator<'tcx>,
-        loc: Location,
-    ) {
-        self.analysis.apply_before_terminator_effect(state, term, loc);
-    }
-
-    fn reconstruct_terminator_effect(
-        &mut self,
-        state: &mut Self::Domain,
-        term: &mir::Terminator<'tcx>,
-        loc: Location,
-    ) {
-        self.analysis.apply_terminator_effect(state, term, loc);
-    }
+    fn visit_block_end(&mut self, _state: &A::Domain) {}
 }
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index b404e3bfb72..ab1453f1ed0 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -18,8 +18,8 @@ pub use self::drop_flag_effects::{
     move_path_children_matching, on_all_children_bits, on_lookup_result_bits,
 };
 pub use self::framework::{
-    Analysis, Backward, Direction, Forward, GenKill, JoinSemiLattice, MaybeReachable, Results,
-    ResultsCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects, fmt, graphviz, lattice,
+    Analysis, Backward, Direction, EntrySets, Forward, GenKill, JoinSemiLattice, MaybeReachable,
+    Results, ResultsCursor, ResultsVisitor, SwitchIntEdgeEffects, fmt, graphviz, lattice,
     visit_results,
 };
 use self::move_paths::MoveData;
diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs
index 73abb669a11..10f1e009855 100644
--- a/compiler/rustc_mir_dataflow/src/points.rs
+++ b/compiler/rustc_mir_dataflow/src/points.rs
@@ -3,7 +3,7 @@ use rustc_index::interval::SparseIntervalMatrix;
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::{self, BasicBlock, Body, Location};
 
-use crate::framework::{ResultsVisitable, ResultsVisitor, visit_results};
+use crate::framework::{Analysis, Results, ResultsVisitor, visit_results};
 
 /// Maps between a `Location` and a `PointIndex` (and vice versa).
 pub struct DenseLocationMap {
@@ -95,14 +95,14 @@ rustc_index::newtype_index! {
 }
 
 /// Add points depending on the result of the given dataflow analysis.
-pub fn save_as_intervals<'tcx, N, R>(
+pub fn save_as_intervals<'tcx, N, A>(
     elements: &DenseLocationMap,
     body: &mir::Body<'tcx>,
-    mut results: R,
+    mut results: Results<'tcx, A>,
 ) -> SparseIntervalMatrix<N, PointIndex>
 where
     N: Idx,
-    R: ResultsVisitable<'tcx, Domain = BitSet<N>>,
+    A: Analysis<'tcx, Domain = BitSet<N>>,
 {
     let values = SparseIntervalMatrix::new(elements.num_points());
     let mut visitor = Visitor { elements, values };
@@ -120,16 +120,15 @@ struct Visitor<'a, N: Idx> {
     values: SparseIntervalMatrix<N, PointIndex>,
 }
 
-impl<'mir, 'tcx, R, N> ResultsVisitor<'mir, 'tcx, R> for Visitor<'_, N>
+impl<'mir, 'tcx, A, N> ResultsVisitor<'mir, 'tcx, A> for Visitor<'_, N>
 where
+    A: Analysis<'tcx, Domain = BitSet<N>>,
     N: Idx,
 {
-    type Domain = BitSet<N>;
-
     fn visit_statement_after_primary_effect(
         &mut self,
-        _results: &mut R,
-        state: &Self::Domain,
+        _results: &mut Results<'tcx, A>,
+        state: &A::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         location: Location,
     ) {
@@ -142,8 +141,8 @@ where
 
     fn visit_terminator_after_primary_effect(
         &mut self,
-        _results: &mut R,
-        state: &Self::Domain,
+        _results: &mut Results<'tcx, A>,
+        state: &A::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
     ) {
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 063f220501f..c2666caa1e8 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -68,11 +68,11 @@ use rustc_middle::ty::{
     self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, TypingMode,
 };
 use rustc_middle::{bug, span_bug};
-use rustc_mir_dataflow::Analysis;
 use rustc_mir_dataflow::impls::{
     MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
 };
 use rustc_mir_dataflow::storage::always_storage_live_locals;
+use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor};
 use rustc_span::Span;
 use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::symbol::sym;
@@ -817,9 +817,9 @@ impl ops::Deref for CoroutineSavedLocals {
 /// computation; see `CoroutineLayout` for more.
 fn compute_storage_conflicts<'mir, 'tcx>(
     body: &'mir Body<'tcx>,
-    saved_locals: &CoroutineSavedLocals,
+    saved_locals: &'mir CoroutineSavedLocals,
     always_live_locals: BitSet<Local>,
-    mut requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
+    mut requires_storage: Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
 ) -> BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal> {
     assert_eq!(body.local_decls.len(), saved_locals.domain_size());
 
@@ -877,15 +877,13 @@ struct StorageConflictVisitor<'a, 'tcx> {
     eligible_storage_live: BitSet<Local>,
 }
 
-impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
+impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, MaybeRequiresStorage<'a, 'tcx>>
     for StorageConflictVisitor<'a, 'tcx>
 {
-    type Domain = BitSet<Local>;
-
     fn visit_statement_before_primary_effect(
         &mut self,
-        _results: &mut R,
-        state: &Self::Domain,
+        _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
+        state: &BitSet<Local>,
         _statement: &'a Statement<'tcx>,
         loc: Location,
     ) {
@@ -894,8 +892,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
 
     fn visit_terminator_before_primary_effect(
         &mut self,
-        _results: &mut R,
-        state: &Self::Domain,
+        _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
+        state: &BitSet<Local>,
         _terminator: &'a Terminator<'tcx>,
         loc: Location,
     ) {
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 7d073f1fa57..ab6460c490b 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -941,16 +941,12 @@ fn try_write_constant<'tcx>(
     interp_ok(())
 }
 
-impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, Results<'tcx, ConstAnalysis<'_, 'tcx>>>
-    for Collector<'_, 'tcx>
-{
-    type Domain = State<FlatSet<Scalar>>;
-
+impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> {
     #[instrument(level = "trace", skip(self, results, statement))]
     fn visit_statement_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
-        state: &Self::Domain,
+        state: &State<FlatSet<Scalar>>,
         statement: &'mir Statement<'tcx>,
         location: Location,
     ) {
@@ -972,7 +968,7 @@ impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, Results<'tcx, ConstAnalysis<'_, 'tcx
     fn visit_statement_after_primary_effect(
         &mut self,
         results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
-        state: &Self::Domain,
+        state: &State<FlatSet<Scalar>>,
         statement: &'mir Statement<'tcx>,
         location: Location,
     ) {
@@ -997,7 +993,7 @@ impl<'mir, 'tcx> ResultsVisitor<'mir, 'tcx, Results<'tcx, ConstAnalysis<'_, 'tcx
     fn visit_terminator_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
-        state: &Self::Domain,
+        state: &State<FlatSet<Scalar>>,
         terminator: &'mir Terminator<'tcx>,
         location: Location,
     ) {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 429e31b2c88..322deb539cd 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -207,6 +207,7 @@
 
 use std::path::PathBuf;
 
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::{LRef, MTLock, par_for_each_in};
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_hir as hir;
@@ -215,7 +216,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar};
-use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
+use rustc_middle::mir::mono::{CollectionMode, InstantiationMode, MonoItem};
 use rustc_middle::mir::visit::Visitor as MirVisitor;
 use rustc_middle::mir::{self, Location, MentionedItem, traversal};
 use rustc_middle::query::TyCtxtAt;
@@ -243,16 +244,6 @@ pub(crate) enum MonoItemCollectionStrategy {
     Lazy,
 }
 
-pub(crate) struct UsageMap<'tcx> {
-    // Maps every mono item to the mono items used by it.
-    used_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
-
-    // Maps every mono item to the mono items that use it.
-    user_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
-}
-
-type MonoItems<'tcx> = Vec<Spanned<MonoItem<'tcx>>>;
-
 /// The state that is shared across the concurrent threads that are doing collection.
 struct SharedState<'tcx> {
     /// Items that have been or are currently being recursively collected.
@@ -264,22 +255,12 @@ struct SharedState<'tcx> {
     usage_map: MTLock<UsageMap<'tcx>>,
 }
 
-/// See module-level docs on some contect for "mentioned" items.
-#[derive(Copy, Clone, Debug, PartialEq)]
-enum CollectionMode {
-    /// Collect items that are used, i.e., actually needed for codegen.
-    ///
-    /// Which items are used can depend on optimization levels, as MIR optimizations can remove
-    /// uses.
-    UsedItems,
-    /// Collect items that are mentioned. The goal of this mode is that it is independent of
-    /// optimizations: the set of "mentioned" items is computed before optimizations are run.
-    ///
-    /// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
-    /// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
-    /// might decide to run them before computing mentioned items.) The key property of this set is
-    /// that it is optimization-independent.
-    MentionedItems,
+pub(crate) struct UsageMap<'tcx> {
+    // Maps every mono item to the mono items used by it.
+    used_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
+
+    // Maps every mono item to the mono items that use it.
+    user_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
 }
 
 impl<'tcx> UsageMap<'tcx> {
@@ -287,19 +268,15 @@ impl<'tcx> UsageMap<'tcx> {
         UsageMap { used_map: Default::default(), user_map: Default::default() }
     }
 
-    fn record_used<'a>(
-        &mut self,
-        user_item: MonoItem<'tcx>,
-        used_items: &'a [Spanned<MonoItem<'tcx>>],
-    ) where
+    fn record_used<'a>(&mut self, user_item: MonoItem<'tcx>, used_items: &'a MonoItems<'tcx>)
+    where
         'tcx: 'a,
     {
-        let used_items: Vec<_> = used_items.iter().map(|item| item.node).collect();
-        for &used_item in used_items.iter() {
+        for used_item in used_items.items() {
             self.user_map.entry(used_item).or_default().push(user_item);
         }
 
-        assert!(self.used_map.insert(user_item, used_items).is_none());
+        assert!(self.used_map.insert(user_item, used_items.items().collect()).is_none());
     }
 
     pub(crate) fn get_user_items(&self, item: MonoItem<'tcx>) -> &[MonoItem<'tcx>] {
@@ -325,6 +302,52 @@ impl<'tcx> UsageMap<'tcx> {
     }
 }
 
+struct MonoItems<'tcx> {
+    // We want a set of MonoItem + Span where trying to re-insert a MonoItem with a different Span
+    // is ignored. Map does that, but it looks odd.
+    items: FxIndexMap<MonoItem<'tcx>, Span>,
+}
+
+impl<'tcx> MonoItems<'tcx> {
+    fn new() -> Self {
+        Self { items: FxIndexMap::default() }
+    }
+
+    fn is_empty(&self) -> bool {
+        self.items.is_empty()
+    }
+
+    fn push(&mut self, item: Spanned<MonoItem<'tcx>>) {
+        // Insert only if the entry does not exist. A normal insert would stomp the first span that
+        // got inserted.
+        self.items.entry(item.node).or_insert(item.span);
+    }
+
+    fn items(&self) -> impl Iterator<Item = MonoItem<'tcx>> + '_ {
+        self.items.keys().cloned()
+    }
+}
+
+impl<'tcx> IntoIterator for MonoItems<'tcx> {
+    type Item = Spanned<MonoItem<'tcx>>;
+    type IntoIter = impl Iterator<Item = Spanned<MonoItem<'tcx>>>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.items.into_iter().map(|(item, span)| respan(span, item))
+    }
+}
+
+impl<'tcx> Extend<Spanned<MonoItem<'tcx>>> for MonoItems<'tcx> {
+    fn extend<I>(&mut self, iter: I)
+    where
+        I: IntoIterator<Item = Spanned<MonoItem<'tcx>>>,
+    {
+        for item in iter {
+            self.push(item)
+        }
+    }
+}
+
 /// Collect all monomorphized items reachable from `starting_point`, and emit a note diagnostic if a
 /// post-monomorphization error is encountered during a collection step.
 ///
@@ -443,13 +466,9 @@ fn collect_items_rec<'tcx>(
             ));
 
             rustc_data_structures::stack::ensure_sufficient_stack(|| {
-                collect_items_of_instance(
-                    tcx,
-                    instance,
-                    &mut used_items,
-                    &mut mentioned_items,
-                    mode,
-                )
+                let (used, mentioned) = tcx.items_of_instance((instance, mode));
+                used_items.extend(used.into_iter().copied());
+                mentioned_items.extend(mentioned.into_iter().copied());
             });
         }
         MonoItem::GlobalAsm(item_id) => {
@@ -1171,14 +1190,12 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
 /// Scans the MIR in order to find function calls, closures, and drop-glue.
 ///
 /// Anything that's found is added to `output`. Furthermore the "mentioned items" of the MIR are returned.
-#[instrument(skip(tcx, used_items, mentioned_items), level = "debug")]
+#[instrument(skip(tcx), level = "debug")]
 fn collect_items_of_instance<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: Instance<'tcx>,
-    used_items: &mut MonoItems<'tcx>,
-    mentioned_items: &mut MonoItems<'tcx>,
     mode: CollectionMode,
-) {
+) -> (MonoItems<'tcx>, MonoItems<'tcx>) {
     // This item is getting monomorphized, do mono-time checks.
     tcx.ensure().check_mono_item(instance);
 
@@ -1193,11 +1210,13 @@ fn collect_items_of_instance<'tcx>(
     // mentioned item. So instead we collect all pre-monomorphized `MentionedItem` that were already
     // added to `used_items` in a hash set, which can efficiently query in the
     // `body.mentioned_items` loop below without even having to monomorphize the item.
+    let mut used_items = MonoItems::new();
+    let mut mentioned_items = MonoItems::new();
     let mut used_mentioned_items = Default::default();
     let mut collector = MirUsedCollector {
         tcx,
         body,
-        used_items,
+        used_items: &mut used_items,
         used_mentioned_items: &mut used_mentioned_items,
         instance,
     };
@@ -1212,7 +1231,7 @@ fn collect_items_of_instance<'tcx>(
     // them errors.
     for const_op in body.required_consts() {
         if let Some(val) = collector.eval_constant(const_op) {
-            collect_const_value(tcx, val, mentioned_items);
+            collect_const_value(tcx, val, &mut mentioned_items);
         }
     }
 
@@ -1221,9 +1240,23 @@ fn collect_items_of_instance<'tcx>(
     for item in body.mentioned_items() {
         if !collector.used_mentioned_items.contains(&item.node) {
             let item_mono = collector.monomorphize(item.node);
-            visit_mentioned_item(tcx, &item_mono, item.span, mentioned_items);
+            visit_mentioned_item(tcx, &item_mono, item.span, &mut mentioned_items);
         }
     }
+
+    (used_items, mentioned_items)
+}
+
+fn items_of_instance<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    (instance, mode): (Instance<'tcx>, CollectionMode),
+) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
+    let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode);
+
+    let used_items = tcx.arena.alloc_from_iter(used_items);
+    let mentioned_items = tcx.arena.alloc_from_iter(mentioned_items);
+
+    (used_items, mentioned_items)
 }
 
 /// `item` must be already monomorphized.
@@ -1304,7 +1337,7 @@ fn collect_const_value<'tcx>(
 #[instrument(skip(tcx, mode), level = "debug")]
 fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionStrategy) -> Vec<MonoItem<'_>> {
     debug!("collecting roots");
-    let mut roots = Vec::new();
+    let mut roots = MonoItems::new();
 
     {
         let entry_fn = tcx.entry_fn(());
@@ -1596,4 +1629,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
 
 pub(crate) fn provide(providers: &mut Providers) {
     providers.hooks.should_codegen_locally = should_codegen_locally;
+    providers.items_of_instance = items_of_instance;
 }
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index 0cfc4371db5..eb576317678 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -2,6 +2,7 @@
 #![feature(array_windows)]
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
+#![feature(impl_trait_in_assoc_type)]
 #![feature(let_chains)]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index d53595929e7..02b361456e4 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -36,9 +36,7 @@ fn do_check_abi<'tcx>(
     target_feature_def: DefId,
     mut emit_err: impl FnMut(Option<&'static str>),
 ) {
-    let Some(feature_def) = tcx.sess.target.features_for_correct_vector_abi() else {
-        return;
-    };
+    let feature_def = tcx.sess.target.features_for_correct_vector_abi();
     let codegen_attrs = tcx.codegen_fn_attrs(target_feature_def);
     for arg_abi in abi.args.iter().chain(std::iter::once(&abi.ret)) {
         let size = arg_abi.layout.size;
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index e2a6d392ca0..84e08ea881d 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -1319,5 +1319,20 @@ pub(crate) fn provide(providers: &mut Providers) {
             .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}"))
     };
 
+    providers.size_estimate = |tcx, instance| {
+        match instance.def {
+            // "Normal" functions size estimate: the number of
+            // statements, plus one for the terminator.
+            InstanceKind::Item(..)
+            | InstanceKind::DropGlue(..)
+            | InstanceKind::AsyncDropGlueCtorShim(..) => {
+                let mir = tcx.instance_mir(instance.def);
+                mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
+            }
+            // Other compiler-generated shims size estimate: 1
+            _ => 1,
+        }
+    };
+
     collector::provide(providers);
 }
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 7ec4ad6dc35..37eb463cba6 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -650,8 +650,9 @@ pub(crate) struct LeftArrowOperator {
 #[diag(parse_remove_let)]
 pub(crate) struct RemoveLet {
     #[primary_span]
-    #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
     pub span: Span,
+    #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
+    pub suggestion: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 0ac6133e828..0012db471ef 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2683,6 +2683,13 @@ impl<'a> Parser<'a> {
                 //            ^^
                 //     }
                 //
+                // We account for macro calls that were meant as conditions as well.
+                //
+                //     if ... {
+                //     } else if macro! { foo bar } {
+                //            ^^
+                //     }
+                //
                 // If $cond is "statement-like" such as ExprKind::While then we
                 // want to suggest wrapping in braces.
                 //
@@ -2693,7 +2700,9 @@ impl<'a> Parser<'a> {
                 //     }
                 //     ^
                     if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
-                        && classify::expr_requires_semi_to_be_stmt(&cond) =>
+                        && (classify::expr_requires_semi_to_be_stmt(&cond)
+                            || matches!(cond.kind, ExprKind::MacCall(..)))
+                    =>
                 {
                     self.dcx().emit_err(errors::ExpectedElseBlock {
                         first_tok_span,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 3546e5b0f04..c4326427f67 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -685,7 +685,7 @@ impl<'a> Parser<'a> {
             self.bump();
             // Trim extra space after the `let`
             let span = lo.with_hi(self.token.span.lo());
-            self.dcx().emit_err(RemoveLet { span });
+            self.dcx().emit_err(RemoveLet { span: lo, suggestion: span });
             lo = self.token.span;
         }
 
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index b7cdae3e3e1..190cd9ed061 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -475,6 +475,7 @@ impl<'a> Parser<'a> {
     }
 
     fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'a> {
+        let prev = self.prev_token.span;
         let sp = self.token.span;
         let mut e = self.dcx().struct_span_err(sp, msg);
         let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
@@ -514,8 +515,97 @@ impl<'a> Parser<'a> {
                 } else {
                     stmt.span
                 };
+                self.suggest_fixes_misparsed_for_loop_head(
+                    &mut e,
+                    prev.between(sp),
+                    stmt_span,
+                    &stmt.kind,
+                );
+            }
+            Err(e) => {
+                self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
+                e.cancel();
+            }
+            _ => {}
+        }
+        e.span_label(sp, "expected `{`");
+        e
+    }
+
+    fn suggest_fixes_misparsed_for_loop_head(
+        &self,
+        e: &mut Diag<'_>,
+        between: Span,
+        stmt_span: Span,
+        stmt_kind: &StmtKind,
+    ) {
+        match (&self.token.kind, &stmt_kind) {
+            (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                if let ExprKind::Call(..) = expr.kind =>
+            {
+                // for _ in x y() {}
+                e.span_suggestion_verbose(
+                    between,
+                    "you might have meant to write a method call",
+                    ".".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                if let ExprKind::Field(..) = expr.kind =>
+            {
+                // for _ in x y.z {}
+                e.span_suggestion_verbose(
+                    between,
+                    "you might have meant to write a field access",
+                    ".".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            (token::CloseDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                if let ExprKind::Struct(expr) = &expr.kind
+                    && let None = expr.qself
+                    && expr.path.segments.len() == 1 =>
+            {
+                // This is specific to "mistyped `if` condition followed by empty body"
+                //
+                // for _ in x y {}
+                e.span_suggestion_verbose(
+                    between,
+                    "you might have meant to write a field access",
+                    ".".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                if let ExprKind::Lit(lit) = expr.kind
+                    && let None = lit.suffix
+                    && let token::LitKind::Integer | token::LitKind::Float = lit.kind =>
+            {
+                // for _ in x 0 {}
+                // for _ in x 0.0 {}
+                e.span_suggestion_verbose(
+                    between,
+                    format!("you might have meant to write a field access"),
+                    ".".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                if let ExprKind::Loop(..)
+                | ExprKind::If(..)
+                | ExprKind::While(..)
+                | ExprKind::Match(..)
+                | ExprKind::ForLoop { .. }
+                | ExprKind::TryBlock(..)
+                | ExprKind::Ret(..)
+                | ExprKind::Closure(..)
+                | ExprKind::Struct(..)
+                | ExprKind::Try(..) = expr.kind =>
+            {
+                // These are more likely to have been meant as a block body.
                 e.multipart_suggestion(
-                    "try placing this code inside a block",
+                    "you might have meant to write this as part of a block",
                     vec![
                         (stmt_span.shrink_to_lo(), "{ ".to_string()),
                         (stmt_span.shrink_to_hi(), " }".to_string()),
@@ -524,14 +614,19 @@ impl<'a> Parser<'a> {
                     Applicability::MaybeIncorrect,
                 );
             }
-            Err(e) => {
-                self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
-                e.cancel();
+            (token::OpenDelim(Delimiter::Brace), _) => {}
+            (_, _) => {
+                e.multipart_suggestion(
+                    "you might have meant to write this as part of a block",
+                    vec![
+                        (stmt_span.shrink_to_lo(), "{ ".to_string()),
+                        (stmt_span.shrink_to_hi(), " }".to_string()),
+                    ],
+                    // Speculative; has been misleading in the past (#46836).
+                    Applicability::MaybeIncorrect,
+                );
             }
-            _ => {}
         }
-        e.span_label(sp, "expected `{`");
-        e
     }
 
     fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index bdf940a04b5..293cee500bb 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1324,7 +1324,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         // This way they can use `macro_rules` defined later.
                         self.visit_vis(&item.vis);
                         self.visit_ident(&item.ident);
-                        item.kind.walk(item, AssocCtxt::Trait, self);
+                        item.kind.walk(item.span, item.id, &item.ident, &item.vis, (), self);
                         visit::walk_list!(self, visit_attribute, &item.attrs);
                     }
                     _ => visit::walk_item(self, item),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 42c6221dc57..5d4ba4be5b8 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -589,6 +589,7 @@ symbols! {
         cmse_nonsecure_entry,
         coerce_unsized,
         cold,
+        cold_path,
         collapse_debuginfo,
         column,
         compare_bytes,
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 88536926b11..112eb862663 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -598,7 +598,12 @@ const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
 const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
     &[/*(64, "zvl64b"), */ (128, "v")];
 // Always warn on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
-const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(128, "vis")*/];
+const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(64, "vis")*/];
+
+const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
+    &[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")];
+const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
+const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
 
 impl super::spec::Target {
     pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
@@ -620,20 +625,24 @@ impl super::spec::Target {
         }
     }
 
-    // Returns None if we do not support ABI checks on the given target yet.
-    pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> {
+    pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
         match &*self.arch {
-            "x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "aarch64" | "arm64ec" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "arm" => Some(ARM_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "powerpc" | "powerpc64" => Some(POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "loongarch64" => Some(&[]), // on-stack ABI, so we complain about all by-val vectors
-            "riscv32" | "riscv64" => Some(RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "wasm32" | "wasm64" => Some(WASM_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "sparc" | "sparc64" => Some(SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            // FIXME: add support for non-tier2 architectures
-            _ => None,
+            "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "loongarch64" => &[], // on-stack ABI, so we complain about all by-val vectors
+            "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "bpf" => &[], // no vector ABI
+            "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            // FIXME: for some tier3 targets, we are overly cautious and always give warnings
+            // when passing args in vector registers.
+            _ => &[],
         }
     }
 
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index b042720933b..e0576c25515 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -116,7 +116,7 @@ use crate::vec::Vec;
 /// `String`s are always valid UTF-8. If you need a non-UTF-8 string, consider
 /// [`OsString`]. It is similar, but without the UTF-8 constraint. Because UTF-8
 /// is a variable width encoding, `String`s are typically smaller than an array of
-/// the same `chars`:
+/// the same `char`s:
 ///
 /// ```
 /// use std::mem;
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 72e34e5faf5..8a986337aa1 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -1465,6 +1465,22 @@ pub const unsafe fn assume(b: bool) {
     }
 }
 
+/// Hints to the compiler that current code path is cold.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+///
+/// This intrinsic does not have a stable counterpart.
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+#[cfg(not(bootstrap))]
+#[rustc_nounwind]
+#[miri::intrinsic_fallback_is_spec]
+#[cold]
+pub const fn cold_path() {}
+
 /// Hints to the compiler that branch condition is likely to be true.
 /// Returns the value passed to it.
 ///
@@ -1480,13 +1496,21 @@ pub const unsafe fn assume(b: bool) {
     bootstrap,
     rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION")
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_intrinsic]
 #[rustc_nounwind]
-#[miri::intrinsic_fallback_is_spec]
+#[inline(always)]
 pub const fn likely(b: bool) -> bool {
-    b
+    #[cfg(bootstrap)]
+    {
+        b
+    }
+    #[cfg(not(bootstrap))]
+    if b {
+        true
+    } else {
+        cold_path();
+        false
+    }
 }
 
 /// Hints to the compiler that branch condition is likely to be false.
@@ -1504,13 +1528,21 @@ pub const fn likely(b: bool) -> bool {
     bootstrap,
     rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION")
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_intrinsic]
 #[rustc_nounwind]
-#[miri::intrinsic_fallback_is_spec]
+#[inline(always)]
 pub const fn unlikely(b: bool) -> bool {
-    b
+    #[cfg(bootstrap)]
+    {
+        b
+    }
+    #[cfg(not(bootstrap))]
+    if b {
+        cold_path();
+        true
+    } else {
+        false
+    }
 }
 
 /// Returns either `true_val` or `false_val` depending on condition `b` with a
@@ -3292,8 +3324,8 @@ pub const unsafe fn ptr_offset_from_unsigned<T>(_ptr: *const T, _base: *const T)
 
 /// See documentation of `<*const T>::guaranteed_eq` for details.
 /// Returns `2` if the result is unknown.
-/// Returns `1` if the pointers are guaranteed equal
-/// Returns `0` if the pointers are guaranteed inequal
+/// Returns `1` if the pointers are guaranteed equal.
+/// Returns `0` if the pointers are guaranteed inequal.
 #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020"))]
 #[rustc_intrinsic]
 #[rustc_nounwind]
@@ -3535,7 +3567,6 @@ pub(crate) macro const_eval_select {
 /// In other words, the following code has *Undefined Behavior*:
 ///
 /// ```no_run
-/// #![feature(is_val_statically_known)]
 /// #![feature(core_intrinsics)]
 /// # #![allow(internal_features)]
 /// use std::hint::unreachable_unchecked;
@@ -3548,7 +3579,6 @@ pub(crate) macro const_eval_select {
 /// may panic, or it may not:
 ///
 /// ```no_run
-/// #![feature(is_val_statically_known)]
 /// #![feature(core_intrinsics)]
 /// # #![allow(internal_features)]
 /// use std::intrinsics::is_val_statically_known;
@@ -3581,7 +3611,6 @@ pub(crate) macro const_eval_select {
 /// behave identically:
 ///
 /// ```
-/// #![feature(is_val_statically_known)]
 /// #![feature(core_intrinsics)]
 /// # #![allow(internal_features)]
 /// use std::intrinsics::is_val_statically_known;
@@ -3598,7 +3627,11 @@ pub(crate) macro const_eval_select {
 /// # _ = foo(&5_i32);
 /// # _ = bar(&5_i32);
 /// ```
-#[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_is_val_statically_known", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
@@ -4013,9 +4046,9 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
             count: usize = count,
         ) => {
             let zero_size = count == 0 || size == 0;
-            ub_checks::is_aligned_and_not_null(src, align, zero_size)
-                && ub_checks::is_aligned_and_not_null(dst, align, zero_size)
-                && ub_checks::is_nonoverlapping(src, dst, size, count)
+            ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
+                && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
+                && ub_checks::maybe_is_nonoverlapping(src, dst, size, count)
         }
     );
 
@@ -4119,8 +4152,8 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
                 align: usize = align_of::<T>(),
                 zero_size: bool = T::IS_ZST || count == 0,
             ) =>
-            ub_checks::is_aligned_and_not_null(src, align, zero_size)
-                && ub_checks::is_aligned_and_not_null(dst, align, zero_size)
+            ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
+                && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
         );
         copy(src, dst, count)
     }
@@ -4201,7 +4234,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
                 addr: *const () = dst as *const (),
                 align: usize = align_of::<T>(),
                 zero_size: bool = T::IS_ZST || count == 0,
-            ) => ub_checks::is_aligned_and_not_null(addr, align, zero_size)
+            ) => ub_checks::maybe_is_aligned_and_not_null(addr, align, zero_size)
         );
         write_bytes(dst, val, count)
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 6f7ea769420..3b8ac20e527 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -109,6 +109,7 @@
 // tidy-alphabetical-start
 #![cfg_attr(bootstrap, feature(const_exact_div))]
 #![cfg_attr(bootstrap, feature(const_fmt_arguments_new))]
+#![cfg_attr(bootstrap, feature(const_ub_checks))]
 #![feature(array_ptr_get)]
 #![feature(asm_experimental_arch)]
 #![feature(const_align_of_val)]
@@ -121,7 +122,6 @@
 #![feature(const_heap)]
 #![feature(const_nonnull_new)]
 #![feature(const_pin_2)]
-#![feature(const_ptr_is_null)]
 #![feature(const_ptr_sub_ptr)]
 #![feature(const_raw_ptr_comparison)]
 #![feature(const_size_of_val)]
@@ -132,14 +132,12 @@
 #![feature(const_type_id)]
 #![feature(const_type_name)]
 #![feature(const_typed_swap)]
-#![feature(const_ub_checks)]
 #![feature(core_intrinsics)]
 #![feature(coverage_attribute)]
 #![feature(do_not_recommend)]
 #![feature(internal_impls_macro)]
 #![feature(ip)]
 #![feature(is_ascii_octdigit)]
-#![feature(is_val_statically_known)]
 #![feature(lazy_get)]
 #![feature(link_cfg)]
 #![feature(non_null_from_ref)]
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 4d24b102096..318bb8ee4cd 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -2242,7 +2242,6 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        #[rustc_allow_const_fn_unstable(is_val_statically_known)]
         pub const fn wrapping_pow(self, mut exp: u32) -> Self {
             if exp == 0 {
                 return 1;
@@ -2808,7 +2807,6 @@ macro_rules! int_impl {
                       without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        #[rustc_allow_const_fn_unstable(is_val_statically_known)]
         pub const fn pow(self, mut exp: u32) -> Self {
             if exp == 0 {
                 return 1;
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 0a5101884f7..0383c13fa08 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2251,7 +2251,6 @@ macro_rules! uint_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        #[rustc_allow_const_fn_unstable(is_val_statically_known)]
         pub const fn wrapping_pow(self, mut exp: u32) -> Self {
             if exp == 0 {
                 return 1;
@@ -2791,7 +2790,6 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        #[rustc_allow_const_fn_unstable(is_val_statically_known)]
         pub const fn pow(self, mut exp: u32) -> Self {
             if exp == 0 {
                 return 1;
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 2d7507e2d53..0dbe819acb1 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -29,16 +29,18 @@ impl<T: ?Sized> *const T {
     /// assert!(!ptr.is_null());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
+    #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_diagnostic_item = "ptr_const_is_null"]
     #[inline]
+    #[rustc_allow_const_fn_unstable(const_eval_select)]
     pub const fn is_null(self) -> bool {
         // Compare via a cast to a thin pointer, so fat pointers are only
         // considering their "data" part for null-ness.
         let ptr = self as *const u8;
         const_eval_select!(
             @capture { ptr: *const u8 } -> bool:
-            if const #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] {
+            // This use of `const_raw_ptr_comparison` has been explicitly blessed by t-lang.
+            if const #[rustc_allow_const_fn_unstable(const_raw_ptr_comparison)] {
                 match (ptr).guaranteed_eq(null_mut()) {
                     Some(res) => res,
                     // To remain maximally convervative, we stop execution when we don't
@@ -280,7 +282,7 @@ impl<T: ?Sized> *const T {
     /// }
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
+    #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
         // SAFETY: the caller must guarantee that `self` is valid
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 603e9044217..805edddfe63 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1103,9 +1103,9 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
             count: usize = count,
         ) => {
             let zero_size = size == 0 || count == 0;
-            ub_checks::is_aligned_and_not_null(x, align, zero_size)
-                && ub_checks::is_aligned_and_not_null(y, align, zero_size)
-                && ub_checks::is_nonoverlapping(x, y, size, count)
+            ub_checks::maybe_is_aligned_and_not_null(x, align, zero_size)
+                && ub_checks::maybe_is_aligned_and_not_null(y, align, zero_size)
+                && ub_checks::maybe_is_nonoverlapping(x, y, size, count)
         }
     );
 
@@ -1216,7 +1216,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
                 addr: *const () = dst as *const (),
                 align: usize = align_of::<T>(),
                 is_zst: bool = T::IS_ZST,
-            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
+            ) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
         );
         mem::replace(&mut *dst, src)
     }
@@ -1369,7 +1369,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
                 addr: *const () = src as *const (),
                 align: usize = align_of::<T>(),
                 is_zst: bool = T::IS_ZST,
-            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
+            ) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
         );
         crate::intrinsics::read_via_copy(src)
     }
@@ -1573,7 +1573,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
                 addr: *mut () = dst as *mut (),
                 align: usize = align_of::<T>(),
                 is_zst: bool = T::IS_ZST,
-            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
+            ) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
         );
         intrinsics::write_via_move(dst, src)
     }
@@ -1745,7 +1745,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
                 addr: *const () = src as *const (),
                 align: usize = align_of::<T>(),
                 is_zst: bool = T::IS_ZST,
-            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
+            ) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
         );
         intrinsics::volatile_load(src)
     }
@@ -1825,7 +1825,7 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
                 addr: *mut () = dst as *mut (),
                 align: usize = align_of::<T>(),
                 is_zst: bool = T::IS_ZST,
-            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
+            ) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
         );
         intrinsics::volatile_store(dst, src);
     }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 344ba46a50e..f0204bd0f77 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -29,7 +29,7 @@ impl<T: ?Sized> *mut T {
     /// assert!(!ptr.is_null());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
+    #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_diagnostic_item = "ptr_is_null"]
     #[inline]
     pub const fn is_null(self) -> bool {
@@ -271,7 +271,7 @@ impl<T: ?Sized> *mut T {
     /// }
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
+    #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
         // SAFETY: the caller must guarantee that `self` is valid for a
@@ -619,7 +619,7 @@ impl<T: ?Sized> *mut T {
     /// println!("{s:?}"); // It'll print: "[4, 2, 3]".
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
+    #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
         // SAFETY: the caller must guarantee that `self` is be valid for
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 89840881c4d..319b76899bf 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -132,7 +132,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
                 align: usize = align_of::<T>(),
                 len: usize = len,
             ) =>
-            ub_checks::is_aligned_and_not_null(data, align, false)
+            ub_checks::maybe_is_aligned_and_not_null(data, align, false)
                 && ub_checks::is_valid_allocation_size(size, len)
         );
         &*ptr::slice_from_raw_parts(data, len)
@@ -186,7 +186,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m
                 align: usize = align_of::<T>(),
                 len: usize = len,
             ) =>
-            ub_checks::is_aligned_and_not_null(data, align, false)
+            ub_checks::maybe_is_aligned_and_not_null(data, align, false)
                 && ub_checks::is_valid_allocation_size(size, len)
         );
         &mut *ptr::slice_from_raw_parts_mut(data, len)
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 93b4ad5c1c9..7f2a5424787 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -469,7 +469,7 @@ impl AtomicBool {
     /// [valid]: crate::ptr#safety
     /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
     #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
-    #[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")]
+    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
         // SAFETY: guaranteed by the caller
         unsafe { &*ptr.cast() }
@@ -1264,7 +1264,7 @@ impl<T> AtomicPtr<T> {
     /// [valid]: crate::ptr#safety
     /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
     #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
-    #[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")]
+    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
         // SAFETY: guaranteed by the caller
         unsafe { &*ptr.cast() }
@@ -2263,7 +2263,7 @@ macro_rules! atomic_int {
             /// [valid]: crate::ptr#safety
             /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
             #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
-            #[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")]
+            #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")]
             pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {
                 // SAFETY: guaranteed by the caller
                 unsafe { &*ptr.cast() }
diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs
index 8fcbda141da..3e6110c9c88 100644
--- a/library/core/src/ub_checks.rs
+++ b/library/core/src/ub_checks.rs
@@ -64,8 +64,6 @@ macro_rules! assert_unsafe_precondition {
             #[rustc_no_mir_inline]
             #[inline]
             #[rustc_nounwind]
-            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))]
-            #[rustc_allow_const_fn_unstable(const_ptr_is_null, const_ub_checks)] // only for UB checks
             const fn precondition_check($($name:$ty),*) {
                 if !$e {
                     ::core::panicking::panic_nounwind(
@@ -116,12 +114,16 @@ pub(crate) const fn check_language_ub() -> bool {
 /// for `assert_unsafe_precondition!` with `check_language_ub`, in which case the
 /// check is anyway not executed in `const`.
 #[inline]
-#[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
-pub(crate) const fn is_aligned_and_not_null(ptr: *const (), align: usize, is_zst: bool) -> bool {
+#[rustc_allow_const_fn_unstable(const_eval_select)]
+pub(crate) const fn maybe_is_aligned_and_not_null(
+    ptr: *const (),
+    align: usize,
+    is_zst: bool,
+) -> bool {
     // This is just for safety checks so we can const_eval_select.
     const_eval_select!(
         @capture { ptr: *const (), align: usize, is_zst: bool } -> bool:
-        if const #[rustc_const_unstable(feature = "const_ub_checks", issue = "none")] {
+        if const {
             is_zst || !ptr.is_null()
         } else {
             ptr.is_aligned_to(align) && (is_zst || !ptr.is_null())
@@ -141,8 +143,8 @@ pub(crate) const fn is_valid_allocation_size(size: usize, len: usize) -> bool {
 /// Note that in const-eval this function just returns `true` and therefore must
 /// only be used with `assert_unsafe_precondition!`, similar to `is_aligned_and_not_null`.
 #[inline]
-#[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
-pub(crate) const fn is_nonoverlapping(
+#[rustc_allow_const_fn_unstable(const_eval_select)]
+pub(crate) const fn maybe_is_nonoverlapping(
     src: *const (),
     dst: *const (),
     size: usize,
diff --git a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
index dcfea77149e..eb39861d8c7 100644
--- a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
@@ -55,4 +55,4 @@ ENV RUST_CONFIGURE_ARGS \
 
 ENV SCRIPT \
   python3 ../x.py --stage 2 build && \
-  python3 ../x.py --stage 2 test tests/run-make --test-args clang
+  python3 ../x.py --stage 2 test tests/run-make
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 6d118ae5784..c1a021e9f8d 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -692,8 +692,6 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
     const quadcolon = /::\s*::/.exec(path);
     if (path.startsWith("::")) {
         throw ["Paths cannot start with ", "::"];
-    } else if (path.endsWith("::")) {
-        throw ["Paths cannot end with ", "::"];
     } else if (quadcolon !== null) {
         throw ["Unexpected ", quadcolon[0]];
     }
@@ -3974,18 +3972,19 @@ class DocSearch {
 
             if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) {
                 const elem = parsedQuery.elems[0];
-                for (const id of this.nameTrie.search(elem.normalizedPathLast, this.tailTable)) {
+                // use arrow functions to preserve `this`.
+                const handleNameSearch = id => {
                     const row = this.searchIndex[id];
                     if (!typePassesFilter(elem.typeFilter, row.ty) ||
                         (filterCrates !== null && row.crate !== filterCrates)) {
-                        continue;
+                        return;
                     }
 
                     let pathDist = 0;
                     if (elem.fullPath.length > 1) {
                         pathDist = checkPath(elem.pathWithoutLast, row);
                         if (pathDist === null) {
-                            continue;
+                            return;
                         }
                     }
 
@@ -4008,9 +4007,20 @@ class DocSearch {
                             maxEditDistance,
                         );
                     }
+                };
+                if (elem.normalizedPathLast !== "") {
+                    const last = elem.normalizedPathLast;
+                    for (const id of this.nameTrie.search(last, this.tailTable)) {
+                        handleNameSearch(id);
+                    }
                 }
                 const length = this.searchIndex.length;
+
                 for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) {
+                    // queries that end in :: bypass the trie
+                    if (elem.normalizedPathLast === "") {
+                        handleNameSearch(i);
+                    }
                     const row = this.searchIndex[i];
                     if (filterCrates !== null && row.crate !== filterCrates) {
                         continue;
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 4a2d8dc636445b276288543882e076f254b3ae9
+Subproject 69e595908e2c420e7f0d1be34e6c5b984c8cfb8
diff --git a/src/tools/miri/tests/pass/shims/time-with-isolation.stdout b/src/tools/miri/tests/pass/shims/time-with-isolation.stdout
index 2d7fb5f4a61..6058735f005 100644
--- a/src/tools/miri/tests/pass/shims/time-with-isolation.stdout
+++ b/src/tools/miri/tests/pass/shims/time-with-isolation.stdout
@@ -1,2 +1,2 @@
-The loop took around 1250ms
+The loop took around 1350ms
 (It's fine for this number to change when you `--bless` this test.)
diff --git a/src/tools/run-make-support/src/external_deps/c_build.rs b/src/tools/run-make-support/src/external_deps/c_build.rs
index f8d1666adda..9dd30713f95 100644
--- a/src/tools/run-make-support/src/external_deps/c_build.rs
+++ b/src/tools/run-make-support/src/external_deps/c_build.rs
@@ -1,7 +1,7 @@
 use std::path::PathBuf;
 
 use crate::artifact_names::{dynamic_lib_name, static_lib_name};
-use crate::external_deps::cc::{cc, cxx};
+use crate::external_deps::c_cxx_compiler::{cc, cxx};
 use crate::external_deps::llvm::llvm_ar;
 use crate::path_helpers::path;
 use crate::targets::{is_darwin, is_msvc, is_windows};
diff --git a/src/tools/run-make-support/src/external_deps/cc.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
index 011ad89e170..becb91ae989 100644
--- a/src/tools/run-make-support/src/external_deps/cc.rs
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
@@ -1,7 +1,7 @@
 use std::path::Path;
 
 use crate::command::Command;
-use crate::{env_var, is_msvc, is_windows, uname};
+use crate::{env_var, is_msvc};
 
 /// Construct a new platform-specific C compiler invocation.
 ///
@@ -127,99 +127,3 @@ impl Cc {
         self
     }
 }
-
-/// `EXTRACFLAGS`
-pub fn extra_c_flags() -> Vec<&'static str> {
-    // Adapted from tools.mk (trimmed):
-    //
-    // ```makefile
-    // ifdef IS_WINDOWS
-    //     ifdef IS_MSVC
-    //         EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
-    //     else
-    //         EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
-    //     endif
-    // else
-    //     ifeq ($(UNAME),Darwin)
-    //         EXTRACFLAGS := -lresolv
-    //     else
-    //         ifeq ($(UNAME),FreeBSD)
-    //             EXTRACFLAGS := -lm -lpthread -lgcc_s
-    //         else
-    //             ifeq ($(UNAME),SunOS)
-    //                 EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
-    //             else
-    //                 ifeq ($(UNAME),OpenBSD)
-    //                     EXTRACFLAGS := -lm -lpthread -lc++abi
-    //                 else
-    //                     EXTRACFLAGS := -lm -lrt -ldl -lpthread
-    //                 endif
-    //             endif
-    //         endif
-    //     endif
-    // endif
-    // ```
-
-    if is_windows() {
-        if is_msvc() {
-            vec![
-                "ws2_32.lib",
-                "userenv.lib",
-                "advapi32.lib",
-                "bcrypt.lib",
-                "ntdll.lib",
-                "synchronization.lib",
-            ]
-        } else {
-            vec!["-lws2_32", "-luserenv", "-lbcrypt", "-lntdll", "-lsynchronization"]
-        }
-    } else {
-        match uname() {
-            n if n.contains("Darwin") => vec!["-lresolv"],
-            n if n.contains("FreeBSD") => vec!["-lm", "-lpthread", "-lgcc_s"],
-            n if n.contains("SunOS") => {
-                vec!["-lm", "-lpthread", "-lposix4", "-lsocket", "-lresolv"]
-            }
-            n if n.contains("OpenBSD") => vec!["-lm", "-lpthread", "-lc++abi"],
-            _ => vec!["-lm", "-lrt", "-ldl", "-lpthread"],
-        }
-    }
-}
-
-/// `EXTRACXXFLAGS`
-pub fn extra_cxx_flags() -> Vec<&'static str> {
-    // Adapted from tools.mk (trimmed):
-    //
-    // ```makefile
-    // ifdef IS_WINDOWS
-    //     ifdef IS_MSVC
-    //     else
-    //         EXTRACXXFLAGS := -lstdc++
-    //     endif
-    // else
-    //     ifeq ($(UNAME),Darwin)
-    //         EXTRACXXFLAGS := -lc++
-    //     else
-    //         ifeq ($(UNAME),FreeBSD)
-    //         else
-    //             ifeq ($(UNAME),SunOS)
-    //             else
-    //                 ifeq ($(UNAME),OpenBSD)
-    //                 else
-    //                     EXTRACXXFLAGS := -lstdc++
-    //                 endif
-    //             endif
-    //         endif
-    //     endif
-    // endif
-    // ```
-    if is_windows() {
-        if is_msvc() { vec![] } else { vec!["-lstdc++"] }
-    } else {
-        match &uname()[..] {
-            "Darwin" => vec!["-lc++"],
-            "FreeBSD" | "SunOS" | "OpenBSD" => vec![],
-            _ => vec!["-lstdc++"],
-        }
-    }
-}
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
new file mode 100644
index 00000000000..49210d75e06
--- /dev/null
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
@@ -0,0 +1,97 @@
+use crate::{is_msvc, is_windows, uname};
+
+/// `EXTRACFLAGS`
+pub fn extra_c_flags() -> Vec<&'static str> {
+    // Adapted from tools.mk (trimmed):
+    //
+    // ```makefile
+    // ifdef IS_WINDOWS
+    //     ifdef IS_MSVC
+    //         EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
+    //     else
+    //         EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
+    //     endif
+    // else
+    //     ifeq ($(UNAME),Darwin)
+    //         EXTRACFLAGS := -lresolv
+    //     else
+    //         ifeq ($(UNAME),FreeBSD)
+    //             EXTRACFLAGS := -lm -lpthread -lgcc_s
+    //         else
+    //             ifeq ($(UNAME),SunOS)
+    //                 EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
+    //             else
+    //                 ifeq ($(UNAME),OpenBSD)
+    //                     EXTRACFLAGS := -lm -lpthread -lc++abi
+    //                 else
+    //                     EXTRACFLAGS := -lm -lrt -ldl -lpthread
+    //                 endif
+    //             endif
+    //         endif
+    //     endif
+    // endif
+    // ```
+
+    if is_windows() {
+        if is_msvc() {
+            vec![
+                "ws2_32.lib",
+                "userenv.lib",
+                "advapi32.lib",
+                "bcrypt.lib",
+                "ntdll.lib",
+                "synchronization.lib",
+            ]
+        } else {
+            vec!["-lws2_32", "-luserenv", "-lbcrypt", "-lntdll", "-lsynchronization"]
+        }
+    } else {
+        match uname() {
+            n if n.contains("Darwin") => vec!["-lresolv"],
+            n if n.contains("FreeBSD") => vec!["-lm", "-lpthread", "-lgcc_s"],
+            n if n.contains("SunOS") => {
+                vec!["-lm", "-lpthread", "-lposix4", "-lsocket", "-lresolv"]
+            }
+            n if n.contains("OpenBSD") => vec!["-lm", "-lpthread", "-lc++abi"],
+            _ => vec!["-lm", "-lrt", "-ldl", "-lpthread"],
+        }
+    }
+}
+
+/// `EXTRACXXFLAGS`
+pub fn extra_cxx_flags() -> Vec<&'static str> {
+    // Adapted from tools.mk (trimmed):
+    //
+    // ```makefile
+    // ifdef IS_WINDOWS
+    //     ifdef IS_MSVC
+    //     else
+    //         EXTRACXXFLAGS := -lstdc++
+    //     endif
+    // else
+    //     ifeq ($(UNAME),Darwin)
+    //         EXTRACXXFLAGS := -lc++
+    //     else
+    //         ifeq ($(UNAME),FreeBSD)
+    //         else
+    //             ifeq ($(UNAME),SunOS)
+    //             else
+    //                 ifeq ($(UNAME),OpenBSD)
+    //                 else
+    //                     EXTRACXXFLAGS := -lstdc++
+    //                 endif
+    //             endif
+    //         endif
+    //     endif
+    // endif
+    // ```
+    if is_windows() {
+        if is_msvc() { vec![] } else { vec!["-lstdc++"] }
+    } else {
+        match &uname()[..] {
+            "Darwin" => vec!["-lc++"],
+            "FreeBSD" | "SunOS" | "OpenBSD" => vec![],
+            _ => vec!["-lstdc++"],
+        }
+    }
+}
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/gcc.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/gcc.rs
new file mode 100644
index 00000000000..e02c4f97255
--- /dev/null
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/gcc.rs
@@ -0,0 +1,66 @@
+use std::path::Path;
+
+use crate::command::Command;
+
+/// Construct a gcc invocation.
+///
+/// WARNING: This assumes *a* `gcc` exists in the environment and is suitable for use.
+#[track_caller]
+pub fn gcc() -> Gcc {
+    Gcc::new()
+}
+
+/// A specific `gcc`.
+#[derive(Debug)]
+#[must_use]
+pub struct Gcc {
+    cmd: Command,
+}
+
+crate::macros::impl_common_helpers!(Gcc);
+
+impl Gcc {
+    /// Construct a `gcc` invocation. This assumes that *a* suitable `gcc` is available in the
+    /// environment.
+    ///
+    /// Note that this does **not** prepopulate the `gcc` invocation with `CC_DEFAULT_FLAGS`.
+    #[track_caller]
+    pub fn new() -> Self {
+        let cmd = Command::new("gcc");
+        Self { cmd }
+    }
+
+    /// Specify path of the input file.
+    pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
+        self.cmd.arg(path.as_ref());
+        self
+    }
+
+    /// Adds directories to the list that the linker searches for libraries.
+    /// Equivalent to `-L`.
+    pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
+        self.cmd.arg("-L");
+        self.cmd.arg(path.as_ref());
+        self
+    }
+
+    /// Specify `-o`.
+    pub fn out_exe(&mut self, name: &str) -> &mut Self {
+        self.cmd.arg("-o");
+        self.cmd.arg(name);
+        self
+    }
+
+    /// Specify path of the output binary.
+    pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
+        self.cmd.arg("-o");
+        self.cmd.arg(path.as_ref());
+        self
+    }
+
+    /// Optimize the output at `-O3`.
+    pub fn optimize(&mut self) -> &mut Self {
+        self.cmd.arg("-O3");
+        self
+    }
+}
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/mod.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/mod.rs
new file mode 100644
index 00000000000..9aaefd8aa47
--- /dev/null
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/mod.rs
@@ -0,0 +1,7 @@
+mod cc;
+mod extras;
+mod gcc;
+
+pub use cc::*;
+pub use extras::*;
+pub use gcc::*;
diff --git a/src/tools/run-make-support/src/external_deps/mod.rs b/src/tools/run-make-support/src/external_deps/mod.rs
index 80c34a9070f..129b06761ef 100644
--- a/src/tools/run-make-support/src/external_deps/mod.rs
+++ b/src/tools/run-make-support/src/external_deps/mod.rs
@@ -2,8 +2,8 @@
 //! such as `cc` or `python`.
 
 pub mod c_build;
+pub mod c_cxx_compiler;
 pub mod cargo;
-pub mod cc;
 pub mod clang;
 pub mod htmldocck;
 pub mod llvm;
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 6cf0aedfe9f..819bbc161e6 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -46,10 +46,10 @@ pub use wasmparser;
 // tidy-alphabetical-end
 
 // Re-exports of external dependencies.
-pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
+pub use external_deps::{c_build, c_cxx_compiler, clang, htmldocck, llvm, python, rustc, rustdoc};
 
 // These rely on external dependencies.
-pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
+pub use c_cxx_compiler::{Cc, Gcc, cc, cxx, extra_c_flags, extra_cxx_flags, gcc};
 pub use c_build::{
     build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx,
     build_native_static_lib_optimized,
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 327a547b295..68c481bda6e 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -3449,21 +3449,14 @@ impl Rewrite for ast::ForeignItem {
                     ref generics,
                     ref body,
                 } = **fn_kind;
-                if let Some(ref body) = body {
+                if body.is_some() {
                     let mut visitor = FmtVisitor::from_context(context);
                     visitor.block_indent = shape.indent;
                     visitor.last_pos = self.span.lo();
                     let inner_attrs = inner_attributes(&self.attrs);
                     let fn_ctxt = visit::FnCtxt::Foreign;
                     visitor.visit_fn(
-                        visit::FnKind::Fn(
-                            fn_ctxt,
-                            self.ident,
-                            sig,
-                            &self.vis,
-                            generics,
-                            Some(body),
-                        ),
+                        visit::FnKind::Fn(fn_ctxt, &self.ident, sig, &self.vis, generics, body),
                         &sig.decl,
                         self.span,
                         defaultness,
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index 8102fe7ad8f..9b116b620b7 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -390,7 +390,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 block = b;
                 self.rewrite_fn_before_block(
                     indent,
-                    ident,
+                    *ident,
                     &FnSig::from_fn_kind(&fk, fd, defaultness),
                     mk_sp(s.lo(), b.span.lo()),
                 )
@@ -540,21 +540,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                         ref generics,
                         ref body,
                     } = **fn_kind;
-                    if let Some(ref body) = body {
+                    if body.is_some() {
                         let inner_attrs = inner_attributes(&item.attrs);
                         let fn_ctxt = match sig.header.ext {
                             ast::Extern::None => visit::FnCtxt::Free,
                             _ => visit::FnCtxt::Foreign,
                         };
                         self.visit_fn(
-                            visit::FnKind::Fn(
-                                fn_ctxt,
-                                item.ident,
-                                sig,
-                                &item.vis,
-                                generics,
-                                Some(body),
-                            ),
+                            visit::FnKind::Fn(fn_ctxt, &item.ident, sig, &item.vis, generics, body),
                             &sig.decl,
                             item.span,
                             defaultness,
@@ -648,11 +641,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     ref generics,
                     ref body,
                 } = **fn_kind;
-                if let Some(ref body) = body {
+                if body.is_some() {
                     let inner_attrs = inner_attributes(&ai.attrs);
                     let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt);
                     self.visit_fn(
-                        visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, generics, Some(body)),
+                        visit::FnKind::Fn(fn_ctxt, &ai.ident, sig, &ai.vis, generics, body),
                         &sig.decl,
                         ai.span,
                         defaultness,
diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs
index 751d678e581..a66ccd37070 100644
--- a/src/tools/tidy/src/target_specific_tests.rs
+++ b/src/tools/tidy/src/target_specific_tests.rs
@@ -10,26 +10,6 @@ use crate::walk::filter_not_rust;
 const LLVM_COMPONENTS_HEADER: &str = "needs-llvm-components:";
 const COMPILE_FLAGS_HEADER: &str = "compile-flags:";
 
-const KNOWN_LLVM_COMPONENTS: &[&str] = &[
-    "aarch64",
-    "arm",
-    "avr",
-    "bpf",
-    "csky",
-    "hexagon",
-    "loongarch",
-    "m68k",
-    "mips",
-    "msp430",
-    "nvptx",
-    "powerpc",
-    "riscv",
-    "sparc",
-    "systemz",
-    "webassembly",
-    "x86",
-];
-
 #[derive(Default, Debug)]
 struct RevisionInfo<'a> {
     target_arch: Option<&'a str>,
@@ -94,20 +74,6 @@ pub fn check(tests_path: &Path, bad: &mut bool) {
                     // gathered.
                 }
             }
-            if let Some(llvm_components) = llvm_components {
-                for component in llvm_components {
-                    // Ensure the given component even exists.
-                    // This is somewhat redundant with COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS,
-                    // but helps detect such problems earlier (PR CI rather than bors CI).
-                    if !KNOWN_LLVM_COMPONENTS.contains(component) {
-                        eprintln!(
-                            "{}: revision {} specifies unknown LLVM component `{}`",
-                            file, rev, component
-                        );
-                        *bad = true;
-                    }
-                }
-            }
         }
     });
 }
diff --git a/tests/codegen/checked_math.rs b/tests/codegen/checked_math.rs
index 63f5c3d34f7..c612ddccdaa 100644
--- a/tests/codegen/checked_math.rs
+++ b/tests/codegen/checked_math.rs
@@ -90,7 +90,7 @@ pub fn checked_shr_signed(a: i32, b: u32) -> Option<i32> {
 #[no_mangle]
 pub fn checked_add_one_unwrap_unsigned(x: u32) -> u32 {
     // CHECK: %[[IS_MAX:.+]] = icmp eq i32 %x, -1
-    // CHECK: br i1 %[[IS_MAX]], label %[[NONE_BB:.+]], label %[[SOME_BB:.+]]
+    // CHECK: br i1 %[[IS_MAX]], label %[[NONE_BB:.+]], label %[[SOME_BB:.+]],
     // CHECK: [[SOME_BB]]:
     // CHECK: %[[R:.+]] = add nuw i32 %x, 1
     // CHECK: ret i32 %[[R]]
diff --git a/tests/codegen/intrinsics/cold_path.rs b/tests/codegen/intrinsics/cold_path.rs
new file mode 100644
index 00000000000..24ee84e07bf
--- /dev/null
+++ b/tests/codegen/intrinsics/cold_path.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -O
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::cold_path;
+
+#[no_mangle]
+pub fn test_cold_path(x: bool) {
+    cold_path();
+}
+
+// CHECK-LABEL: @test_cold_path(
+// CHECK-NOT: cold_path
diff --git a/tests/codegen/intrinsics/likely.rs b/tests/codegen/intrinsics/likely.rs
index 9dc31d21045..e318390db20 100644
--- a/tests/codegen/intrinsics/likely.rs
+++ b/tests/codegen/intrinsics/likely.rs
@@ -1,22 +1,35 @@
-//@ compile-flags: -C no-prepopulate-passes -Copt-level=1
-
+//@ compile-flags: -O
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
 
-use std::intrinsics::{likely, unlikely};
+use std::intrinsics::likely;
 
+#[inline(never)]
 #[no_mangle]
-pub fn check_likely(x: i32, y: i32) -> Option<i32> {
-    unsafe {
-        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true)
-        if likely(x == y) { None } else { Some(x + y) }
-    }
+pub fn path_a() {
+    println!("path a");
+}
+
+#[inline(never)]
+#[no_mangle]
+pub fn path_b() {
+    println!("path b");
 }
 
 #[no_mangle]
-pub fn check_unlikely(x: i32, y: i32) -> Option<i32> {
-    unsafe {
-        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false)
-        if unlikely(x == y) { None } else { Some(x + y) }
+pub fn test_likely(x: bool) {
+    if likely(x) {
+        path_a();
+    } else {
+        path_b();
     }
 }
+
+// CHECK-LABEL: @test_likely(
+// CHECK: br i1 %x, label %bb2, label %bb3, !prof ![[NUM:[0-9]+]]
+// CHECK: bb3:
+// CHECK-NOT: cold_path
+// CHECK: path_b
+// CHECK: bb2:
+// CHECK: path_a
+// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 2000, i32 1}
diff --git a/tests/codegen/intrinsics/likely_assert.rs b/tests/codegen/intrinsics/likely_assert.rs
new file mode 100644
index 00000000000..0ddbd6206ae
--- /dev/null
+++ b/tests/codegen/intrinsics/likely_assert.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -O
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn test_assert(x: bool) {
+    assert!(x);
+}
+
+// check that assert! emits branch weights
+
+// CHECK-LABEL: @test_assert(
+// CHECK: br i1 %x, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]]
+// CHECK: bb1:
+// CHECK: panic
+// CHECK: bb2:
+// CHECK: ret void
+// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 2000, i32 1}
diff --git a/tests/codegen/intrinsics/unlikely.rs b/tests/codegen/intrinsics/unlikely.rs
new file mode 100644
index 00000000000..2d776031a52
--- /dev/null
+++ b/tests/codegen/intrinsics/unlikely.rs
@@ -0,0 +1,35 @@
+//@ compile-flags: -O
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::unlikely;
+
+#[inline(never)]
+#[no_mangle]
+pub fn path_a() {
+    println!("path a");
+}
+
+#[inline(never)]
+#[no_mangle]
+pub fn path_b() {
+    println!("path b");
+}
+
+#[no_mangle]
+pub fn test_unlikely(x: bool) {
+    if unlikely(x) {
+        path_a();
+    } else {
+        path_b();
+    }
+}
+
+// CHECK-LABEL: @test_unlikely(
+// CHECK: br i1 %x, label %bb2, label %bb4, !prof ![[NUM:[0-9]+]]
+// CHECK: bb4:
+// CHECK: path_b
+// CHECK: bb2:
+// CHECK-NOT: cold_path
+// CHECK: path_a
+// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 1, i32 2000}
diff --git a/tests/crashes/123077-2.rs b/tests/crashes/123077-2.rs
deleted file mode 100644
index e086e330337..00000000000
--- a/tests/crashes/123077-2.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #123077
-//@ only-x86_64
-use std::arch::x86_64::{__m128, _mm_blend_ps};
-
-pub fn sse41_blend_noinline( ) -> __m128 {
-    let f = { |x, y| unsafe {
-        _mm_blend_ps(x, y, { |x, y| unsafe })
-    }};
-    f(x, y)
-}
-
-pub fn main() {}
diff --git a/tests/crashes/129150.rs b/tests/crashes/129150.rs
deleted file mode 100644
index 9f8c2ba1739..00000000000
--- a/tests/crashes/129150.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ known-bug: rust-lang/rust#129150
-//@ only-x86_64
-use std::arch::x86_64::_mm_blend_ps;
-
-pub fn main() {
-     _mm_blend_ps(1, 2, &const {} );
-}
diff --git a/tests/crashes/130687.rs b/tests/crashes/130687.rs
deleted file mode 100644
index 361be0905df..00000000000
--- a/tests/crashes/130687.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #130687
-//@ only-x86_64
-pub struct Data([u8; usize::MAX >> 16]);
-const _: &'static Data = &Data([0; usize::MAX >> 16]);
diff --git a/tests/crashes/131535.rs b/tests/crashes/131535.rs
deleted file mode 100644
index 47ccdf87f2d..00000000000
--- a/tests/crashes/131535.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #131535
-#![feature(non_lifetime_binders)]
-trait v0<> {}
-fn kind  :(v0<'_, > impl for<v4> v0<'_, v2 = impl v0<v4> + '_>) {}
diff --git a/tests/crashes/131637.rs b/tests/crashes/131637.rs
deleted file mode 100644
index 7d328384a74..00000000000
--- a/tests/crashes/131637.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ known-bug: #121637
-#![feature(non_lifetime_binders)]
-trait Trait<Type> {
-    type Type;
-
-    fn method(&self) -> impl for<T> Trait<impl Trait<T>>;
-}
diff --git a/tests/crashes/132530.rs b/tests/crashes/132530.rs
deleted file mode 100644
index b43da62bfc1..00000000000
--- a/tests/crashes/132530.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #132530
-
-#![feature(non_lifetime_binders)]
-
-trait Trait<'a, A> {
-    type Assoc<'a> = i32;
-}
-
-fn a() -> impl for<T> Trait<Assoc = impl Trait<T>> {}
diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs
index 9d232578979..9a0fd01d7e2 100644
--- a/tests/debuginfo/numeric-types.rs
+++ b/tests/debuginfo/numeric-types.rs
@@ -2,6 +2,14 @@
 
 //@ ignore-windows-gnu: #128981
 
+// Note: u128 visualization was not supported in 10.0.22621.3233 but was fixed in 10.0.26100.2161.
+
+// FIXME(#133107): this is temporarily marked as `only-64bit` because of course 32-bit msvc has
+// a different integer width and thus underlying integer type display. Only marked as such to
+// unblock the tree.
+//@ only-64bit
+//@ min-cdb-version: 10.0.26100.2161
+
 // Tests the visualizations for `NonZero<T>`, `Wrapping<T>` and
 // `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`.
 
@@ -48,8 +56,8 @@
 // cdb-check:nz_u64           : 0x64 [Type: core::num::nonzero::NonZero<u64>]
 // cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u64>]
 
-// 128-bit integers don't seem to work in CDB
 // cdb-command: dx nz_u128
+// cdb-check:nz_u128          : 111 [Type: core::num::nonzero::NonZero<u128>]
 // cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u128>]
 
 // cdb-command: dx nz_usize
@@ -58,101 +66,99 @@
 
 // cdb-command: dx w_i8
 // cdb-check:w_i8             : 10 [Type: core::num::wrapping::Wrapping<i8>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<i8>]
+// cdb-check:    [+0x000] __0              : 10 [Type: char]
 
 // cdb-command: dx w_i16
 // cdb-check:w_i16            : 20 [Type: core::num::wrapping::Wrapping<i16>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<i16>]
+// cdb-check:    [+0x000] __0              : 20 [Type: short]
 
 // cdb-command: dx w_i32
 // cdb-check:w_i32            : 30 [Type: core::num::wrapping::Wrapping<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<i32>]
+// cdb-check:    [+0x000] __0              : 30 [Type: int]
 
 // cdb-command: dx w_i64
 // cdb-check:w_i64            : 40 [Type: core::num::wrapping::Wrapping<i64>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<i64>]
+// cdb-check:    [+0x000] __0              : 40 [Type: __int64]
 
-// 128-bit integers don't seem to work in CDB
 // cdb-command: dx w_i128
-// cdb-check:w_i128           [Type: core::num::wrapping::Wrapping<i128>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<i128>]
+// cdb-check:w_i128           : 50 [Type: core::num::wrapping::Wrapping<i128>]
+// cdb-check:    [+0x000] __0              : 50 [Type: i128]
 
 // cdb-command: dx w_isize
 // cdb-check:w_isize          : 60 [Type: core::num::wrapping::Wrapping<isize>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<isize>]
+// cdb-check:    [+0x000] __0              : 60 [Type: __int64]
 
 // cdb-command: dx w_u8
 // cdb-check:w_u8             : 0x46 [Type: core::num::wrapping::Wrapping<u8>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<u8>]
+// cdb-check:    [+0x000] __0              : 0x46 [Type: unsigned char]
 
 // cdb-command: dx w_u16
 // cdb-check:w_u16            : 0x50 [Type: core::num::wrapping::Wrapping<u16>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<u16>]
+// cdb-check:    [+0x000] __0              : 0x50 [Type: unsigned short]
 
 // cdb-command: dx w_u32
 // cdb-check:w_u32            : 0x5a [Type: core::num::wrapping::Wrapping<u32>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<u32>]
+// cdb-check:    [+0x000] __0              : 0x5a [Type: unsigned int]
 
 // cdb-command: dx w_u64
 // cdb-check:w_u64            : 0x64 [Type: core::num::wrapping::Wrapping<u64>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<u64>]
+// cdb-check:    [+0x000] __0              : 0x64 [Type: unsigned __int64]
 
-// 128-bit integers don't seem to work in CDB
 // cdb-command: dx w_u128
-// cdb-check:w_u128           [Type: core::num::wrapping::Wrapping<u128>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<u128>]
+// cdb-check:w_u128           : 110 [Type: core::num::wrapping::Wrapping<u128>]
+// cdb-check:    [+0x000] __0              : 110 [Type: u128]
 
 // cdb-command: dx w_usize
 // cdb-check:w_usize          : 0x78 [Type: core::num::wrapping::Wrapping<usize>]
-// cdb-check:    [<Raw View>]     [Type: core::num::wrapping::Wrapping<usize>]
+// cdb-check:    [+0x000] __0              : 0x78 [Type: unsigned __int64]
 
 // cdb-command: dx a_bool_t
 // cdb-check:a_bool_t         : true [Type: core::sync::atomic::AtomicBool]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicBool]
+// cdb-check:    [+0x000] v                : 0x1 [Type: core::cell::UnsafeCell<u8>]
 
 // cdb-command: dx a_bool_f
 // cdb-check:a_bool_f         : false [Type: core::sync::atomic::AtomicBool]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicBool]
+// cdb-check:    [+0x000] v                : 0x0 [Type: core::cell::UnsafeCell<u8>]
 
 // cdb-command: dx a_i8
 // cdb-check:a_i8             : 2 [Type: core::sync::atomic::AtomicI8]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicI8]
+// cdb-check:    [+0x000] v                : 2 [Type: core::cell::UnsafeCell<i8>]
 
 // cdb-command: dx a_i16
 // cdb-check:a_i16            : 4 [Type: core::sync::atomic::AtomicI16]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicI16]
+// cdb-check:    [+0x000] v                : 4 [Type: core::cell::UnsafeCell<i16>]
 
 // cdb-command: dx a_i32
 // cdb-check:a_i32            : 8 [Type: core::sync::atomic::AtomicI32]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicI32]
+// cdb-check:    [+0x000] v                : 8 [Type: core::cell::UnsafeCell<i32>]
 
 // cdb-command: dx a_i64
 // cdb-check:a_i64            : 16 [Type: core::sync::atomic::AtomicI64]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicI64]
+// cdb-check:    [+0x000] v                : 16 [Type: core::cell::UnsafeCell<i64>]
 
 // cdb-command: dx a_isize
 // cdb-check:a_isize          : 32 [Type: core::sync::atomic::AtomicIsize]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicIsize]
+// cdb-check:    [+0x000] v                : 32 [Type: core::cell::UnsafeCell<isize>]
 
 // cdb-command: dx a_u8
 // cdb-check:a_u8             : 0x40 [Type: core::sync::atomic::AtomicU8]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicU8]
+// cdb-check:    [+0x000] v                : 0x40 [Type: core::cell::UnsafeCell<u8>]
 
 // cdb-command: dx a_u16
 // cdb-check:a_u16            : 0x80 [Type: core::sync::atomic::AtomicU16]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicU16]
+// cdb-check:    [+0x000] v                : 0x80 [Type: core::cell::UnsafeCell<u16>]
 
 // cdb-command: dx a_u32
 // cdb-check:a_u32            : 0x100 [Type: core::sync::atomic::AtomicU32]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicU32]
+// cdb-check:    [+0x000] v                : 0x100 [Type: core::cell::UnsafeCell<u32>]
 
 // cdb-command: dx a_u64
 // cdb-check:a_u64            : 0x200 [Type: core::sync::atomic::AtomicU64]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicU64]
+// cdb-check:    [+0x000] v                : 0x200 [Type: core::cell::UnsafeCell<u64>]
 
 // cdb-command: dx a_usize
 // cdb-check:a_usize          : 0x400 [Type: core::sync::atomic::AtomicUsize]
-// cdb-check:    [<Raw View>]     [Type: core::sync::atomic::AtomicUsize]
+// cdb-check:    [+0x000] v                : 0x400 [Type: core::cell::UnsafeCell<usize>]
 
 
 // === GDB TESTS ===================================================================================
diff --git a/tests/debuginfo/range-types.rs b/tests/debuginfo/range-types.rs
index 8c18fd9addd..068a55a5767 100644
--- a/tests/debuginfo/range-types.rs
+++ b/tests/debuginfo/range-types.rs
@@ -1,7 +1,10 @@
 // Testing the display of range types in cdb.
 
-// cdb-only
-//@ min-cdb-version: 10.0.18317.1001
+//@ only-cdb
+
+// FIXME(jieyouxu): triple check in CI if the directive actually works
+//@ min-cdb-version: 10.0.26100.2161
+
 //@ compile-flags:-g
 
 // === CDB TESTS ==================================================================================
@@ -10,23 +13,26 @@
 
 // cdb-command: dx r1,d
 // cdb-check:r1,d             : (3..5) [Type: core::ops::range::Range<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::ops::range::Range<i32>]
+// cdb-check:    [+0x000] start            : 3 [Type: int]
+// cdb-check:    [+0x004] end              : 5 [Type: int]
 
 // cdb-command: dx r2,d
 // cdb-check:r2,d             : (2..) [Type: core::ops::range::RangeFrom<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::ops::range::RangeFrom<i32>]
+// cdb-check:    [+0x000] start            : 2 [Type: int]
 
 // cdb-command: dx r3,d
 // cdb-check:r3,d             : (1..=4) [Type: core::ops::range::RangeInclusive<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::ops::range::RangeInclusive<i32>]
+// cdb-check:    [+0x000] start            : 1 [Type: int]
+// cdb-check:    [+0x004] end              : 4 [Type: int]
+// cdb-check:    [+0x008] exhausted        : false [Type: bool]
 
 // cdb-command: dx r4,d
 // cdb-check:r4,d             : (..10) [Type: core::ops::range::RangeTo<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::ops::range::RangeTo<i32>]
+// cdb-check:    [+0x000] end              : 10 [Type: int]
 
 // cdb-command: dx r5,d
 // cdb-check:r5,d             : (..=3) [Type: core::ops::range::RangeToInclusive<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::ops::range::RangeToInclusive<i32>]
+// cdb-check:    [+0x000] end              : 3 [Type: int]
 
 // cdb-command: dx r6,d
 // cdb-check:r6,d             [Type: core::ops::range::RangeFull]
diff --git a/tests/debuginfo/unit-type.rs b/tests/debuginfo/unit-type.rs
index 42c0ff11f71..0ffa2fe490a 100644
--- a/tests/debuginfo/unit-type.rs
+++ b/tests/debuginfo/unit-type.rs
@@ -1,5 +1,8 @@
 //@ compile-flags:-g
 
+// FIXME(jieyouxu): triple check if this works in CI
+//@ min-cdb-version: 10.0.26100.2161
+
 // === GDB TESTS ===================================================================================
 
 // gdb-command: run
@@ -26,18 +29,18 @@
 // cdb-check: Breakpoint 0 hit
 
 // cdb-command: dx _ref
-// cdb-check: _ref             : 0x[...] : () [Type: tuple$<> *]
+// cdb-check: _ref             : 0x[...] [Type: tuple$<> *]
 
 // cdb-command: dx _ptr
-// cdb-check: _ptr             : 0x[...] : () [Type: tuple$<> *]
+// cdb-check: _ptr             : 0x[...] [Type: tuple$<> *]
 
 // cdb-command: dx _local
-// cdb-check: _local           : () [Type: tuple$<>]
+// cdb-check: _local           [Type: tuple$<>]
 
 // cdb-command: dx _field,d
 // cdb-check: _field,d         [Type: unit_type::_TypeContainingUnitField]
 // cdb-check:     [+0x[...]] _a               : 123 [Type: unsigned int]
-// cdb-check:     [+0x[...]] _unit            : () [Type: tuple$<>]
+// cdb-check:     [+0x[...]] _unit            [Type: tuple$<>]
 // cdb-check:     [+0x[...]] _b               : 456 [Type: unsigned __int64]
 
 // Check that we can cast "void pointers" to their actual type in the debugger
diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir
index 935e67fc3c0..cff5b4c7243 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir
@@ -13,7 +13,9 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
                 scope 6 (inlined core::num::<impl u16>::checked_add) {
                     let mut _5: (u16, bool);
                     let mut _6: bool;
-                    let mut _7: bool;
+                    scope 7 (inlined unlikely) {
+                        let _7: ();
+                    }
                 }
             }
             scope 5 (inlined convert::num::ptr_try_from_impls::<impl TryFrom<usize> for u16>::try_from) {
@@ -21,11 +23,11 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
                 let mut _4: u16;
             }
         }
-        scope 7 (inlined Option::<u16>::is_none) {
-            scope 8 (inlined Option::<u16>::is_some) {
+        scope 8 (inlined Option::<u16>::is_none) {
+            scope 9 (inlined Option::<u16>::is_some) {
             }
         }
-        scope 9 (inlined core::num::<impl u16>::wrapping_add) {
+        scope 10 (inlined core::num::<impl u16>::wrapping_add) {
         }
     }
 
@@ -39,29 +41,26 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
     bb1: {
         _4 = copy _2 as u16 (IntToInt);
         StorageDead(_3);
-        StorageLive(_7);
         StorageLive(_6);
         StorageLive(_5);
         _5 = AddWithOverflow(copy _1, copy _4);
         _6 = copy (_5.1: bool);
-        _7 = unlikely(move _6) -> [return: bb2, unwind unreachable];
+        switchInt(copy _6) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
-        switchInt(move _7) -> [0: bb3, otherwise: bb4];
-    }
-
-    bb3: {
         StorageDead(_5);
         StorageDead(_6);
-        StorageDead(_7);
         goto -> bb7;
     }
 
+    bb3: {
+        _7 = cold_path() -> [return: bb4, unwind unreachable];
+    }
+
     bb4: {
         StorageDead(_5);
         StorageDead(_6);
-        StorageDead(_7);
         goto -> bb6;
     }
 
diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir
index bf1ffd1ef32..6e0242a220d 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir
@@ -13,7 +13,9 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
                 scope 6 (inlined core::num::<impl u16>::checked_add) {
                     let mut _5: (u16, bool);
                     let mut _6: bool;
-                    let mut _7: bool;
+                    scope 7 (inlined unlikely) {
+                        let _7: ();
+                    }
                 }
             }
             scope 5 (inlined convert::num::ptr_try_from_impls::<impl TryFrom<usize> for u16>::try_from) {
@@ -21,11 +23,11 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
                 let mut _4: u16;
             }
         }
-        scope 7 (inlined Option::<u16>::is_none) {
-            scope 8 (inlined Option::<u16>::is_some) {
+        scope 8 (inlined Option::<u16>::is_none) {
+            scope 9 (inlined Option::<u16>::is_some) {
             }
         }
-        scope 9 (inlined core::num::<impl u16>::wrapping_add) {
+        scope 10 (inlined core::num::<impl u16>::wrapping_add) {
         }
     }
 
@@ -39,29 +41,26 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
     bb1: {
         _4 = copy _2 as u16 (IntToInt);
         StorageDead(_3);
-        StorageLive(_7);
         StorageLive(_6);
         StorageLive(_5);
         _5 = AddWithOverflow(copy _1, copy _4);
         _6 = copy (_5.1: bool);
-        _7 = unlikely(move _6) -> [return: bb2, unwind unreachable];
+        switchInt(copy _6) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
-        switchInt(move _7) -> [0: bb3, otherwise: bb4];
-    }
-
-    bb3: {
         StorageDead(_5);
         StorageDead(_6);
-        StorageDead(_7);
         goto -> bb7;
     }
 
+    bb3: {
+        _7 = cold_path() -> [return: bb4, unwind unreachable];
+    }
+
     bb4: {
         StorageDead(_5);
         StorageDead(_6);
-        StorageDead(_7);
         goto -> bb6;
     }
 
diff --git a/tests/run-make/mte-ffi/rmake.rs b/tests/run-make/mte-ffi/rmake.rs
index f4fafb796e3..50f5f14191b 100644
--- a/tests/run-make/mte-ffi/rmake.rs
+++ b/tests/run-make/mte-ffi/rmake.rs
@@ -1,14 +1,12 @@
-// Tests that MTE tags and values stored in the top byte of a pointer (TBI) are
-// preserved across FFI boundaries (C <-> Rust).
-// This test does not require MTE: whilst the test will use MTE if available, if it is not,
-// arbitrary tag bits are set using TBI.
+//! Tests that MTE tags and values stored in the top byte of a pointer (TBI) are preserved across
+//! FFI boundaries (C <-> Rust). This test does not require MTE: whilst the test will use MTE if
+//! available, if it is not, arbitrary tag bits are set using TBI.
 
-// This test is only valid for AArch64.
-// The linker must be explicitly specified when cross-compiling, so it is limited to
-// `aarch64-unknown-linux-gnu`.
 //@ only-aarch64-unknown-linux-gnu
+// Reason: this test is only valid for AArch64 with `gcc`. The linker must be explicitly specified
+// when cross-compiling, so it is limited to `aarch64-unknown-linux-gnu`.
 
-use run_make_support::{cc, dynamic_lib_name, extra_c_flags, run, rustc, target};
+use run_make_support::{dynamic_lib_name, extra_c_flags, gcc, run, rustc, target};
 
 fn main() {
     run_test("int");
@@ -29,7 +27,8 @@ fn run_test(variant: &str) {
         .target(target())
         .linker("aarch64-linux-gnu-gcc")
         .run();
-    cc().input(format!("bar_{variant}.c"))
+    gcc()
+        .input(format!("bar_{variant}.c"))
         .input(dynamic_lib_name("foo"))
         .out_exe("test")
         .args(&flags)
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index 068298e7236..8bffef61c8f 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -144,14 +144,6 @@ const PARSED = [
         error: "Unexpected `:: ::`",
     },
     {
-        query: "a::b::",
-        elems: [],
-        foundElems: 0,
-        userQuery: "a::b::",
-        returned: [],
-        error: "Paths cannot end with `::`",
-    },
-    {
         query: ":a",
         elems: [],
         foundElems: 0,
diff --git a/tests/rustdoc-js-std/path-end-empty.js b/tests/rustdoc-js-std/path-end-empty.js
new file mode 100644
index 00000000000..6e853c61b4d
--- /dev/null
+++ b/tests/rustdoc-js-std/path-end-empty.js
@@ -0,0 +1,6 @@
+const EXPECTED = {
+    'query': 'Option::',
+    'others': [
+        { 'path': 'std::option::Option', 'name': 'get_or_insert_default' },
+    ],
+}
diff --git a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
index d7f37f36681..3534228f73e 100644
--- a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
+++ b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
@@ -64,7 +64,7 @@ fn check_instance(instance: &Instance) {
     if instance.has_body() {
         let Some(body) = instance.body() else { unreachable!("Expected a body") };
         assert!(!body.blocks.is_empty());
-        assert_eq!(&name, "likely");
+        assert_eq!(&name, "select_unpredictable");
     } else {
         assert!(instance.body().is_none());
         assert_matches!(name.as_str(), "size_of_val" | "vtable_size");
@@ -78,7 +78,7 @@ fn check_def(fn_def: FnDef) {
 
     let name = intrinsic.fn_name();
     match name.as_str() {
-        "likely" => {
+        "select_unpredictable" => {
             assert!(!intrinsic.must_be_overridden());
             assert!(fn_def.has_body());
         }
@@ -132,7 +132,7 @@ fn generate_input(path: &str) -> std::io::Result<()> {
         pub fn use_intrinsics(init: bool) -> bool {{
             let vtable_sz = unsafe {{ vtable_size(0 as *const ()) }};
             let sz = unsafe {{ size_of_val("hi") }};
-            likely(init && sz == 2)
+            select_unpredictable(init && sz == 2, false, true)
         }}
         "#
     )?;
diff --git a/tests/ui/consts/const-ptr-is-null.rs b/tests/ui/consts/const-ptr-is-null.rs
index 82c293c0ad6..92cf87a9782 100644
--- a/tests/ui/consts/const-ptr-is-null.rs
+++ b/tests/ui/consts/const-ptr-is-null.rs
@@ -1,4 +1,3 @@
-#![feature(const_ptr_is_null)]
 use std::ptr;
 
 const IS_NULL: () = {
diff --git a/tests/ui/consts/const-ptr-is-null.stderr b/tests/ui/consts/const-ptr-is-null.stderr
index 5fd35142818..f71b3752772 100644
--- a/tests/ui/consts/const-ptr-is-null.stderr
+++ b/tests/ui/consts/const-ptr-is-null.stderr
@@ -8,7 +8,7 @@ note: inside `std::ptr::const_ptr::<impl *const T>::is_null::compiletime`
 note: inside `std::ptr::const_ptr::<impl *const i32>::is_null`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
 note: inside `MAYBE_NULL`
-  --> $DIR/const-ptr-is-null.rs:17:14
+  --> $DIR/const-ptr-is-null.rs:16:14
    |
 LL |     assert!(!ptr.wrapping_sub(512).is_null());
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/consts/is_val_statically_known.rs b/tests/ui/consts/is_val_statically_known.rs
index a9059817bcc..d55910d32d3 100644
--- a/tests/ui/consts/is_val_statically_known.rs
+++ b/tests/ui/consts/is_val_statically_known.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 
-#![feature(core_intrinsics, is_val_statically_known)]
+#![feature(core_intrinsics)]
 
 use std::intrinsics::is_val_statically_known;
 
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
new file mode 100644
index 00000000000..b923a768cbf
--- /dev/null
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
@@ -0,0 +1,12 @@
+//! Ensure we do not ICE when a promoted fails to evaluate due to running out of memory.
+//! Also see <https://github.com/rust-lang/rust/issues/130687>.
+
+// Needs the max type size to be much bigger than the RAM people typically have.
+//@ only-64bit
+
+pub struct Data([u8; (1 << 47) - 1]);
+const _: &'static Data = &Data([0; (1 << 47) - 1]);
+//~^ERROR: evaluation of constant value failed
+//~| tried to allocate more memory than available to compiler
+
+fn main() {}
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
new file mode 100644
index 00000000000..50e920f05f9
--- /dev/null
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:32
+   |
+LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
+   |                                ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
+
+note: erroneous constant encountered
+  --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:26
+   |
+LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/ptr_is_null.rs b/tests/ui/consts/ptr_is_null.rs
index bbf13802312..8b41f5718e8 100644
--- a/tests/ui/consts/ptr_is_null.rs
+++ b/tests/ui/consts/ptr_is_null.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: --crate-type=lib
 //@ check-pass
 
-#![feature(const_ptr_is_null)]
 #![allow(useless_ptr_null_checks)]
 
 const FOO: &usize = &42;
diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs
index b35af76da3e..af1c20976d7 100644
--- a/tests/ui/delegation/unsupported.rs
+++ b/tests/ui/delegation/unsupported.rs
@@ -10,15 +10,11 @@ mod opaque {
     mod to_reuse {
         use super::Trait;
 
-        pub fn opaque_ret() -> impl Trait { unimplemented!() }
-        //~^ warn: this function depends on never type fallback being `()`
-        //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+        pub fn opaque_ret() -> impl Trait { () }
     }
 
     trait ToReuse {
-        fn opaque_ret() -> impl Trait { unimplemented!() }
-        //~^ warn: this function depends on never type fallback being `()`
-        //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+        fn opaque_ret() -> impl Trait { () }
     }
 
     // FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls.
diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr
index 9391763dca2..2b0bcf9d84e 100644
--- a/tests/ui/delegation/unsupported.stderr
+++ b/tests/ui/delegation/unsupported.stderr
@@ -1,74 +1,43 @@
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:25:5: 25:24>::{synthetic#0}`
-  --> $DIR/unsupported.rs:26:25
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::{synthetic#0}`
+  --> $DIR/unsupported.rs:22:25
    |
 LL |         reuse to_reuse::opaque_ret;
    |                         ^^^^^^^^^^
    |
 note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
-  --> $DIR/unsupported.rs:26:25
+  --> $DIR/unsupported.rs:22:25
    |
 LL |         reuse to_reuse::opaque_ret;
    |                         ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:25:5: 25:24>::{synthetic#0}`, completing the cycle
-note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:25:5: 25:24>` is well-formed
-  --> $DIR/unsupported.rs:25:5
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::{synthetic#0}`, completing the cycle
+note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>` is well-formed
+  --> $DIR/unsupported.rs:21:5
    |
 LL |     impl ToReuse for u8 {
    |     ^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-warning: this function depends on never type fallback being `()`
-  --> $DIR/unsupported.rs:13:9
-   |
-LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
-   = help: specify the types explicitly
-note: in edition 2024, the requirement `!: opaque::Trait` will fail
-  --> $DIR/unsupported.rs:13:32
-   |
-LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
-   |                                ^^^^^^^^^^
-   = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
-
-warning: this function depends on never type fallback being `()`
-  --> $DIR/unsupported.rs:19:9
-   |
-LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
-   = help: specify the types explicitly
-note: in edition 2024, the requirement `!: opaque::Trait` will fail
-  --> $DIR/unsupported.rs:19:28
-   |
-LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
-   |                            ^^^^^^^^^^
-
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:28:5: 28:25>::{synthetic#0}`
-  --> $DIR/unsupported.rs:29:24
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::{synthetic#0}`
+  --> $DIR/unsupported.rs:25:24
    |
 LL |         reuse ToReuse::opaque_ret;
    |                        ^^^^^^^^^^
    |
 note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
-  --> $DIR/unsupported.rs:29:24
+  --> $DIR/unsupported.rs:25:24
    |
 LL |         reuse ToReuse::opaque_ret;
    |                        ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:28:5: 28:25>::{synthetic#0}`, completing the cycle
-note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:28:5: 28:25>` is well-formed
-  --> $DIR/unsupported.rs:28:5
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::{synthetic#0}`, completing the cycle
+note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>` is well-formed
+  --> $DIR/unsupported.rs:24:5
    |
 LL |     impl ToReuse for u16 {
    |     ^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: recursive delegation is not supported yet
-  --> $DIR/unsupported.rs:42:22
+  --> $DIR/unsupported.rs:38:22
    |
 LL |         pub reuse to_reuse2::foo;
    |                              --- callee defined here
@@ -77,14 +46,14 @@ LL |     reuse to_reuse1::foo;
    |                      ^^^
 
 error[E0283]: type annotations needed
-  --> $DIR/unsupported.rs:52:18
+  --> $DIR/unsupported.rs:48:18
    |
 LL |     reuse Trait::foo;
    |                  ^^^ cannot infer type
    |
    = note: cannot satisfy `_: effects::Trait`
 
-error: aborting due to 4 previous errors; 2 warnings emitted
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0283, E0391.
 For more information about an error, try `rustc --explain E0283`.
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
index 3fed16f0ee7..75bc598d17b 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
@@ -16,7 +16,7 @@ fn main() {
 
 fn m() {
     //[e2021]~^ this function depends on never type fallback being `()`
-    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     let x: () = match true {
         true => Default::default(),
         //[e2024]~^ error: the trait bound `!: Default` is not satisfied
@@ -28,7 +28,7 @@ fn m() {
 
 fn q() -> Option<()> {
     //[e2021]~^ this function depends on never type fallback being `()`
-    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     fn deserialize<T: Default>() -> Option<T> {
         Some(T::default())
     }
@@ -45,7 +45,7 @@ fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
 }
 fn meow() -> Result<(), ()> {
     //[e2021]~^ this function depends on never type fallback being `()`
-    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     help::<(), _>(1)?;
     //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
     Ok(())
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index fdc97e54d4e..454e88d4569 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn m() {
    | ^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
@@ -24,7 +24,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn q() -> Option<()> {
    | ^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
@@ -43,7 +43,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn meow() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `(): From<!>` will fail
diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs
index 71d36f3a2d9..32e83e74139 100644
--- a/tests/ui/editions/never-type-fallback-breaking.rs
+++ b/tests/ui/editions/never-type-fallback-breaking.rs
@@ -16,7 +16,7 @@ fn main() {
 
 fn m() {
     //[e2021]~^ this function depends on never type fallback being `()`
-    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     let x = match true {
         true => Default::default(),
         //[e2024]~^ error: the trait bound `!: Default` is not satisfied
@@ -28,7 +28,7 @@ fn m() {
 
 fn q() -> Option<()> {
     //[e2021]~^ this function depends on never type fallback being `()`
-    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     fn deserialize<T: Default>() -> Option<T> {
         Some(T::default())
     }
@@ -45,7 +45,7 @@ fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
 }
 fn meow() -> Result<(), ()> {
     //[e2021]~^ this function depends on never type fallback being `()`
-    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     help(1)?;
     //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
     Ok(())
diff --git a/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-macro.rs b/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-macro.rs
new file mode 100644
index 00000000000..2efdc2342c1
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-macro.rs
@@ -0,0 +1,20 @@
+// A macro_rules macro in 2015 that has an RPIT without `use<>` that would
+// cause a problem with 2024 capturing rules.
+
+#[macro_export]
+macro_rules! macro_rpit {
+    () => {
+        fn test_mbe(x: &Vec<i32>) -> impl std::fmt::Display {
+            x[0]
+        }
+
+        pub fn from_mbe() {
+            let mut x = vec![];
+            x.push(1);
+
+            let element = test_mbe(&x);
+            x.push(2);
+            println!("{element}");
+        }
+    };
+}
diff --git a/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs b/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs
new file mode 100644
index 00000000000..e197dcfef80
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs
@@ -0,0 +1,29 @@
+// A proc-macro in 2015 that has an RPIT without `use<>` that would cause a
+// problem with 2024 capturing rules.
+
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn pm_rpit(input: TokenStream) -> TokenStream {
+    "fn test_pm(x: &Vec<i32>) -> impl std::fmt::Display {
+    x[0]
+}
+
+pub fn from_pm() {
+    let mut x = vec![];
+    x.push(1);
+
+    let element = test_pm(&x);
+    x.push(2);
+    println!(\"{element}\");
+}
+"
+    .parse()
+    .unwrap()
+}
diff --git a/tests/ui/impl-trait/precise-capturing/external-macro.rs b/tests/ui/impl-trait/precise-capturing/external-macro.rs
new file mode 100644
index 00000000000..492e8036461
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/external-macro.rs
@@ -0,0 +1,26 @@
+// Tests that code generated from an external macro (MBE and proc-macro) that
+// has an RPIT will not fail when the call-site is 2024.
+// https://github.com/rust-lang/rust/issues/132917
+
+//@ aux-crate: no_use_pm=no-use-pm.rs
+//@ aux-crate: no_use_macro=no-use-macro.rs
+//@ edition: 2024
+//@ compile-flags:-Z unstable-options
+//@ check-pass
+
+no_use_pm::pm_rpit!{}
+
+no_use_macro::macro_rpit!{}
+
+fn main() {
+    let mut x = vec![];
+    x.push(1);
+
+    let element = test_pm(&x);
+    x.push(2);
+    println!("{element}");
+
+    let element = test_mbe(&x);
+    x.push(2);
+    println!("{element}");
+}
diff --git a/tests/ui/intrinsics/reify-intrinsic.rs b/tests/ui/intrinsics/reify-intrinsic.rs
index 6c52651f060..0d047ccf4a3 100644
--- a/tests/ui/intrinsics/reify-intrinsic.rs
+++ b/tests/ui/intrinsics/reify-intrinsic.rs
@@ -13,9 +13,9 @@ fn b() {
 }
 
 fn c() {
-    let _: [unsafe extern "rust-intrinsic" fn(bool) -> bool; 2] = [
-        std::intrinsics::likely, //~ ERROR cannot coerce
-        std::intrinsics::unlikely,
+    let _: [unsafe extern "rust-intrinsic" fn(f32) -> f32; 2] = [
+        std::intrinsics::floorf32, //~ ERROR cannot coerce
+        std::intrinsics::log2f32,
     ];
 }
 
diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr
index 7af17147f28..a456e81e762 100644
--- a/tests/ui/intrinsics/reify-intrinsic.stderr
+++ b/tests/ui/intrinsics/reify-intrinsic.stderr
@@ -18,11 +18,11 @@ LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize)
 error[E0308]: cannot coerce intrinsics to function pointers
   --> $DIR/reify-intrinsic.rs:17:9
    |
-LL |         std::intrinsics::likely,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
+LL |         std::intrinsics::floorf32,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
    |
    = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(_) -> _`
-                 found fn item `fn(_) -> _ {likely}`
+                 found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {floorf32}`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs
new file mode 100644
index 00000000000..8d854c6c237
--- /dev/null
+++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs
@@ -0,0 +1,31 @@
+//@ only-x86_64
+
+const fn foo<const U: i32>() -> i32 {
+    U
+}
+
+fn main() {
+    std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
+    //~^ invalid argument to a legacy const generic
+
+    std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, 5 + || ());
+    //~^ invalid argument to a legacy const generic
+
+    std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<{ 1 + 2 }>());
+    //~^ invalid argument to a legacy const generic
+
+    std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<3>());
+    //~^ invalid argument to a legacy const generic
+
+    std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, &const {});
+    //~^ invalid argument to a legacy const generic
+
+    std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, {
+        struct F();
+        //~^ invalid argument to a legacy const generic
+        1
+    });
+
+    std::arch::x86_64::_mm_inserti_si64(loop {}, loop {}, || (), 1 + || ());
+    //~^ invalid argument to a legacy const generic
+}
diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr
new file mode 100644
index 00000000000..7e05ae4f20c
--- /dev/null
+++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr
@@ -0,0 +1,82 @@
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:8:55
+   |
+LL |     std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
+   |                                                       ^^^^^
+   |
+help: try using a const generic argument instead
+   |
+LL |     std::arch::x86_64::_mm_blend_ps::<{ || () }>(loop {}, loop {});
+   |                                    +++++++++++++ ~~~~~~~~~~~~~~~~
+
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:11:59
+   |
+LL |     std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, 5 + || ());
+   |                                                           ^^^^^
+   |
+help: try using a const generic argument instead
+   |
+LL |     std::arch::x86_64::_mm_blend_ps::<{ 5 + (|| ()) }>(loop {}, loop {});
+   |                                    +++++++++++++++++++ ~~~~~~~~~~~~~~~~
+
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:14:61
+   |
+LL |     std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<{ 1 + 2 }>());
+   |                                                             ^^^^^^^^^
+   |
+help: try using a const generic argument instead
+   |
+LL |     std::arch::x86_64::_mm_blend_ps::<{ foo::<{ 1 + 2 }>() }>(loop {}, loop {});
+   |                                    ++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~
+
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:17:61
+   |
+LL |     std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<3>());
+   |                                                             ^
+   |
+help: try using a const generic argument instead
+   |
+LL |     std::arch::x86_64::_mm_blend_ps::<{ foo::<3>() }>(loop {}, loop {});
+   |                                    ++++++++++++++++++ ~~~~~~~~~~~~~~~~
+
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:20:56
+   |
+LL |     std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, &const {});
+   |                                                        ^^^^^^^^
+   |
+help: try using a const generic argument instead
+   |
+LL |     std::arch::x86_64::_mm_blend_ps::<{ &const {} }>(loop {}, loop {});
+   |                                    +++++++++++++++++ ~~~~~~~~~~~~~~~~
+
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:24:9
+   |
+LL |         struct F();
+   |         ^^^^^^^^^^^
+   |
+help: try using a const generic argument instead
+   |
+LL ~     std::arch::x86_64::_mm_blend_ps::<{ {
+LL +     struct F();
+LL +     1
+LL ~ } }>(loop {}, loop {});
+   |
+
+error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
+  --> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:29:59
+   |
+LL |     std::arch::x86_64::_mm_inserti_si64(loop {}, loop {}, || (), 1 + || ());
+   |                                                           ^^^^^
+   |
+help: try using a const generic argument instead
+   |
+LL |     std::arch::x86_64::_mm_inserti_si64::<{ || () }, { 1 + (|| ()) }>(loop {}, loop {});
+   |                                        ++++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/issues/issue-39848.stderr b/tests/ui/issues/issue-39848.stderr
index a6c6c61f170..1ffed2d4a1d 100644
--- a/tests/ui/issues/issue-39848.stderr
+++ b/tests/ui/issues/issue-39848.stderr
@@ -16,10 +16,10 @@ LL |         if $tgt.has_$field() {}
 LL |     get_opt!(bar, foo);
    |     ------------------ in this macro invocation
    = note: this error originates in the macro `get_opt` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: try placing this code inside a block
+help: you might have meant to write a method call
    |
-LL |         if $tgt.has_{ $field() } {}
-   |                     +          +
+LL |         if $tgt.has_.$field() {}
+   |                     +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/let-else/let-else-if.stderr b/tests/ui/let-else/let-else-if.stderr
index 7e2215c8c05..ad36b423150 100644
--- a/tests/ui/let-else/let-else-if.stderr
+++ b/tests/ui/let-else/let-else-if.stderr
@@ -4,7 +4,7 @@ error: conditional `else if` is not supported for `let...else`
 LL |     let Some(_) = Some(()) else if true {
    |                                 ^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL ~     let Some(_) = Some(()) else { if true {
 LL |
diff --git a/tests/ui/lint/issue-104392.stderr b/tests/ui/lint/issue-104392.stderr
index 8e466439ae6..4d8d8c56d41 100644
--- a/tests/ui/lint/issue-104392.stderr
+++ b/tests/ui/lint/issue-104392.stderr
@@ -6,7 +6,7 @@ LL |     { unsafe 92 }
    |       |
    |       while parsing this `unsafe` expression
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     { unsafe { 92 } }
    |              +    +
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
index 7cf4aa6cdd4..ada37ccd640 100644
--- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
@@ -10,7 +10,7 @@
     unused_mut,
     unused_variables
 )]
-#![deny(unused_parens)]
+#![deny(unused_parens, unused_braces)]
 
 fn lint_on_top_level() {
     let a = 0; //~ ERROR unnecessary parentheses around pattern
@@ -43,8 +43,10 @@ fn no_lint_ops() {
 fn lint_break_if_not_followed_by_block() {
     #![allow(unreachable_code)]
     loop { if break {} } //~ ERROR unnecessary parentheses
-    loop { if break ({ println!("hello") }) {} } //~ ERROR unnecessary parentheses
-    loop { if (break { println!("hello") }) {} }
+    loop { if break { println!("hello") } {} }
+    //~^ ERROR unnecessary parentheses around `if` condition
+    //~| ERROR unnecessary parentheses around `break` value
+    loop { if (break println!("hello")) {} } //~ ERROR unnecessary braces around `break` value
 }
 
 // Don't lint in these cases (#64106).
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
index 013255dc213..67066c3bee3 100644
--- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
@@ -10,7 +10,7 @@
     unused_mut,
     unused_variables
 )]
-#![deny(unused_parens)]
+#![deny(unused_parens, unused_braces)]
 
 fn lint_on_top_level() {
     let (a) = 0; //~ ERROR unnecessary parentheses around pattern
@@ -43,8 +43,10 @@ fn no_lint_ops() {
 fn lint_break_if_not_followed_by_block() {
     #![allow(unreachable_code)]
     loop { if (break) {} } //~ ERROR unnecessary parentheses
-    loop { if (break ({ println!("hello") })) {} } //~ ERROR unnecessary parentheses
-    loop { if (break { println!("hello") }) {} }
+    loop { if (break ({ println!("hello") })) {} }
+    //~^ ERROR unnecessary parentheses around `if` condition
+    //~| ERROR unnecessary parentheses around `break` value
+    loop { if (break { println!("hello") }) {} } //~ ERROR unnecessary braces around `break` value
 }
 
 // Don't lint in these cases (#64106).
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
index f916bba8194..d5fdaef42d8 100644
--- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
@@ -7,7 +7,7 @@ LL |     let (a) = 0;
 note: the lint level is defined here
   --> $DIR/issue-54538-unused-parens-lint.rs:13:9
    |
-LL | #![deny(unused_parens)]
+LL | #![deny(unused_parens, unused_braces)]
    |         ^^^^^^^^^^^^^
 help: remove these parentheses
    |
@@ -99,8 +99,37 @@ LL -     loop { if (break ({ println!("hello") })) {} }
 LL +     loop { if break ({ println!("hello") }) {} }
    |
 
+error: unnecessary parentheses around `break` value
+  --> $DIR/issue-54538-unused-parens-lint.rs:46:22
+   |
+LL |     loop { if (break ({ println!("hello") })) {} }
+   |                      ^                     ^
+   |
+help: remove these parentheses
+   |
+LL -     loop { if (break ({ println!("hello") })) {} }
+LL +     loop { if (break { println!("hello") }) {} }
+   |
+
+error: unnecessary braces around `break` value
+  --> $DIR/issue-54538-unused-parens-lint.rs:49:22
+   |
+LL |     loop { if (break { println!("hello") }) {} }
+   |                      ^^                 ^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-54538-unused-parens-lint.rs:13:24
+   |
+LL | #![deny(unused_parens, unused_braces)]
+   |                        ^^^^^^^^^^^^^
+help: remove these braces
+   |
+LL -     loop { if (break { println!("hello") }) {} }
+LL +     loop { if (break println!("hello")) {} }
+   |
+
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:71:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:73:12
    |
 LL |     if let (0 | 1) = 0 {}
    |            ^     ^
@@ -112,7 +141,7 @@ LL +     if let 0 | 1 = 0 {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:72:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:74:13
    |
 LL |     if let ((0 | 1),) = (0,) {}
    |             ^     ^
@@ -124,7 +153,7 @@ LL +     if let (0 | 1,) = (0,) {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:73:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:75:13
    |
 LL |     if let [(0 | 1)] = [0] {}
    |             ^     ^
@@ -136,7 +165,7 @@ LL +     if let [0 | 1] = [0] {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:74:16
+  --> $DIR/issue-54538-unused-parens-lint.rs:76:16
    |
 LL |     if let 0 | (1 | 2) = 0 {}
    |                ^     ^
@@ -148,7 +177,7 @@ LL +     if let 0 | 1 | 2 = 0 {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:76:15
+  --> $DIR/issue-54538-unused-parens-lint.rs:78:15
    |
 LL |     if let TS((0 | 1)) = TS(0) {}
    |               ^     ^
@@ -160,7 +189,7 @@ LL +     if let TS(0 | 1) = TS(0) {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:78:20
+  --> $DIR/issue-54538-unused-parens-lint.rs:80:20
    |
 LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
    |                    ^     ^
@@ -172,7 +201,7 @@ LL +     if let NS { f: 0 | 1 } = (NS { f: 0 }) {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:88:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
    |
 LL |         (_) => {}
    |         ^ ^
@@ -184,7 +213,7 @@ LL +         _ => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:89:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:91:9
    |
 LL |         (y) => {}
    |         ^ ^
@@ -196,7 +225,7 @@ LL +         y => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:92:9
    |
 LL |         (ref r) => {}
    |         ^     ^
@@ -208,7 +237,7 @@ LL +         ref r => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:91:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:93:9
    |
 LL |         (e @ 1...2) => {}
    |         ^         ^
@@ -220,7 +249,7 @@ LL +         e @ 1...2 => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:97:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:99:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^            ^
@@ -232,7 +261,7 @@ LL +         e @ &(1...2) => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:98:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:100:10
    |
 LL |         &(_) => {}
    |          ^ ^
@@ -244,7 +273,7 @@ LL +         &_ => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:109:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:111:9
    |
 LL |         (_) => {}
    |         ^ ^
@@ -256,7 +285,7 @@ LL +         _ => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:110:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:112:9
    |
 LL |         (y) => {}
    |         ^ ^
@@ -268,7 +297,7 @@ LL +         y => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:111:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:113:9
    |
 LL |         (ref r) => {}
    |         ^     ^
@@ -280,7 +309,7 @@ LL +         ref r => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:112:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:114:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^         ^
@@ -292,7 +321,7 @@ LL +         e @ 1..=2 => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:118:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:120:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^            ^
@@ -304,7 +333,7 @@ LL +         e @ &(1..=2) => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:119:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:121:10
    |
 LL |         &(_) => {}
    |          ^ ^
@@ -315,5 +344,5 @@ LL -         &(_) => {}
 LL +         &_ => {}
    |
 
-error: aborting due to 26 previous errors
+error: aborting due to 28 previous errors
 
diff --git a/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.fixed b/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.fixed
new file mode 100644
index 00000000000..9343d906cdc
--- /dev/null
+++ b/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.fixed
@@ -0,0 +1,32 @@
+//@ run-rustfix
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn foo() {
+    loop {
+        break (_ = 42);
+        // lint unused_parens should not be triggered here.
+    }
+
+    let _ = loop {
+        let a = 1;
+        let b = 2;
+        break a + b; //~ERROR unnecessary parentheses
+    };
+
+    loop {
+        if break return () {
+            //~^ ERROR unnecessary parentheses
+        }
+        if break return () {
+            //~^ ERROR unnecessary parentheses
+        }
+    }
+
+    return (_ = 42);
+    // lint unused_parens should not be triggered here.
+}
+
+fn main() {
+    let _ = foo();
+}
diff --git a/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.rs b/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.rs
new file mode 100644
index 00000000000..fe9cba3e168
--- /dev/null
+++ b/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.rs
@@ -0,0 +1,32 @@
+//@ run-rustfix
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn foo() {
+    loop {
+        break (_ = 42);
+        // lint unused_parens should not be triggered here.
+    }
+
+    let _ = loop {
+        let a = 1;
+        let b = 2;
+        break (a + b); //~ERROR unnecessary parentheses
+    };
+
+    loop {
+        if (break return ()) {
+            //~^ ERROR unnecessary parentheses
+        }
+        if break (return ()) {
+            //~^ ERROR unnecessary parentheses
+        }
+    }
+
+    return (_ = 42);
+    // lint unused_parens should not be triggered here.
+}
+
+fn main() {
+    let _ = foo();
+}
diff --git a/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.stderr b/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.stderr
new file mode 100644
index 00000000000..c41cf32bade
--- /dev/null
+++ b/tests/ui/lint/unused/unused-parens-assign-expr-in-ret-issue-131989.stderr
@@ -0,0 +1,43 @@
+error: unnecessary parentheses around `break` value
+  --> $DIR/unused-parens-assign-expr-in-ret-issue-131989.rs:14:15
+   |
+LL |         break (a + b);
+   |               ^     ^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-parens-assign-expr-in-ret-issue-131989.rs:2:9
+   |
+LL | #![deny(unused_parens)]
+   |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -         break (a + b);
+LL +         break a + b;
+   |
+
+error: unnecessary parentheses around `if` condition
+  --> $DIR/unused-parens-assign-expr-in-ret-issue-131989.rs:18:12
+   |
+LL |         if (break return ()) {
+   |            ^               ^
+   |
+help: remove these parentheses
+   |
+LL -         if (break return ()) {
+LL +         if break return () {
+   |
+
+error: unnecessary parentheses around `break` value
+  --> $DIR/unused-parens-assign-expr-in-ret-issue-131989.rs:21:18
+   |
+LL |         if break (return ()) {
+   |                  ^         ^
+   |
+help: remove these parentheses
+   |
+LL -         if break (return ()) {
+LL +         if break return () {
+   |
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused_parens_json_suggestion.fixed b/tests/ui/lint/unused_parens_json_suggestion.fixed
index 89fd0d86614..f26bedc3fd5 100644
--- a/tests/ui/lint/unused_parens_json_suggestion.fixed
+++ b/tests/ui/lint/unused_parens_json_suggestion.fixed
@@ -9,7 +9,7 @@
 // test of the JSON error format.
 
 #![deny(unused_parens)]
-#![allow(unreachable_code)]
+#![allow(unreachable_code, unused_braces)]
 
 fn main() {
     // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not
diff --git a/tests/ui/lint/unused_parens_json_suggestion.rs b/tests/ui/lint/unused_parens_json_suggestion.rs
index 4526084196c..af3d88f71bb 100644
--- a/tests/ui/lint/unused_parens_json_suggestion.rs
+++ b/tests/ui/lint/unused_parens_json_suggestion.rs
@@ -9,7 +9,7 @@
 // test of the JSON error format.
 
 #![deny(unused_parens)]
-#![allow(unreachable_code)]
+#![allow(unreachable_code, unused_braces)]
 
 fn main() {
     // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not
diff --git a/tests/ui/lint/unused_parens_json_suggestion.stderr b/tests/ui/lint/unused_parens_json_suggestion.stderr
index 1f4928cd464..2ce31817d29 100644
--- a/tests/ui/lint/unused_parens_json_suggestion.stderr
+++ b/tests/ui/lint/unused_parens_json_suggestion.stderr
@@ -1,4 +1,4 @@
-{"$message_type":"diagnostic","message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":633,"byte_end":634,"line_start":17,"line_end":17,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":439,"byte_end":452,"line_start":11,"line_end":11,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":633,"byte_end":634,"line_start":17,"line_end":17,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around assigned value
+{"$message_type":"diagnostic","message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":636,"byte_end":637,"line_start":17,"line_end":17,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":648,"byte_end":649,"line_start":17,"line_end":17,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":439,"byte_end":452,"line_start":11,"line_end":11,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":636,"byte_end":637,"line_start":17,"line_end":17,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":648,"byte_end":649,"line_start":17,"line_end":17,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around assigned value
   --> $DIR/unused_parens_json_suggestion.rs:17:14
    |
 LL |     let _a = (1 / (2 + 3));
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.fixed b/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
index e2774d5d7e5..899c24f83ed 100644
--- a/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
@@ -9,7 +9,7 @@
 // test of the JSON error format.
 
 #![deny(unused_parens)]
-#![allow(unreachable_code)]
+#![allow(unreachable_code, unused_braces)]
 
 fn main() {
 
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.rs b/tests/ui/lint/unused_parens_remove_json_suggestion.rs
index b3ac87178db..7f5d935c4ac 100644
--- a/tests/ui/lint/unused_parens_remove_json_suggestion.rs
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.rs
@@ -9,7 +9,7 @@
 // test of the JSON error format.
 
 #![deny(unused_parens)]
-#![allow(unreachable_code)]
+#![allow(unreachable_code, unused_braces)]
 
 fn main() {
 
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
index 9268fc1abc4..975de4edfdf 100644
--- a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
@@ -1,4 +1,4 @@
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":525,"byte_end":526,"line_start":18,"line_end":18,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":528,"byte_end":529,"line_start":18,"line_end":18,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":439,"byte_end":452,"line_start":11,"line_end":11,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":525,"byte_end":526,"line_start":18,"line_end":18,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":528,"byte_end":529,"line_start":18,"line_end":18,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":540,"byte_end":541,"line_start":18,"line_end":18,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":543,"byte_end":544,"line_start":18,"line_end":18,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":439,"byte_end":452,"line_start":11,"line_end":11,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":540,"byte_end":541,"line_start":18,"line_end":18,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":543,"byte_end":544,"line_start":18,"line_end":18,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:18:8
    |
 LL |     if (_b) {
@@ -16,7 +16,7 @@ LL +     if _b {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":622,"byte_end":623,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":624,"byte_end":625,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":622,"byte_end":623,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":624,"byte_end":625,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":637,"byte_end":638,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":639,"byte_end":640,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":637,"byte_end":638,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":639,"byte_end":640,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:29:7
    |
 LL |     if(c) {
@@ -29,7 +29,7 @@ LL +     if c {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":668,"byte_end":669,"line_start":33,"line_end":33,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":670,"byte_end":671,"line_start":33,"line_end":33,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":668,"byte_end":669,"line_start":33,"line_end":33,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":670,"byte_end":671,"line_start":33,"line_end":33,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":683,"byte_end":684,"line_start":33,"line_end":33,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":685,"byte_end":686,"line_start":33,"line_end":33,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":683,"byte_end":684,"line_start":33,"line_end":33,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":685,"byte_end":686,"line_start":33,"line_end":33,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:33:8
    |
 LL |     if (c){
@@ -42,7 +42,7 @@ LL +     if c {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":716,"byte_end":717,"line_start":37,"line_end":37,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":730,"byte_end":731,"line_start":37,"line_end":37,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":716,"byte_end":717,"line_start":37,"line_end":37,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":730,"byte_end":731,"line_start":37,"line_end":37,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":731,"byte_end":732,"line_start":37,"line_end":37,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":745,"byte_end":746,"line_start":37,"line_end":37,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":731,"byte_end":732,"line_start":37,"line_end":37,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":745,"byte_end":746,"line_start":37,"line_end":37,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:37:11
    |
 LL |     while (false && true){
@@ -55,7 +55,7 @@ LL +     while false && true {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":744,"byte_end":745,"line_start":38,"line_end":38,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":746,"byte_end":747,"line_start":38,"line_end":38,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":744,"byte_end":745,"line_start":38,"line_end":38,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":746,"byte_end":747,"line_start":38,"line_end":38,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":759,"byte_end":760,"line_start":38,"line_end":38,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":761,"byte_end":762,"line_start":38,"line_end":38,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":759,"byte_end":760,"line_start":38,"line_end":38,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":761,"byte_end":762,"line_start":38,"line_end":38,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:38:12
    |
 LL |         if (c) {
@@ -68,7 +68,7 @@ LL +         if c {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":44,"line_end":44,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":822,"line_start":44,"line_end":44,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":44,"line_end":44,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":822,"line_start":44,"line_end":44,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":822,"byte_end":823,"line_start":44,"line_end":44,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":836,"byte_end":837,"line_start":44,"line_end":44,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":822,"byte_end":823,"line_start":44,"line_end":44,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":836,"byte_end":837,"line_start":44,"line_end":44,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:44:10
    |
 LL |     while(true && false) {
@@ -81,7 +81,7 @@ LL +     while true && false {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":842,"byte_end":843,"line_start":45,"line_end":45,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":849,"byte_end":850,"line_start":45,"line_end":45,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":842,"byte_end":843,"line_start":45,"line_end":45,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":849,"byte_end":850,"line_start":45,"line_end":45,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":857,"byte_end":858,"line_start":45,"line_end":45,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":864,"byte_end":865,"line_start":45,"line_end":45,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":857,"byte_end":858,"line_start":45,"line_end":45,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":864,"byte_end":865,"line_start":45,"line_end":45,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
   --> $DIR/unused_parens_remove_json_suggestion.rs:45:18
    |
 LL |         for _ in (0 .. 3){
@@ -94,7 +94,7 @@ LL +         for _ in 0 .. 3 {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":909,"byte_end":910,"line_start":50,"line_end":50,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":916,"byte_end":917,"line_start":50,"line_end":50,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":909,"byte_end":910,"line_start":50,"line_end":50,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":916,"byte_end":917,"line_start":50,"line_end":50,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":924,"byte_end":925,"line_start":50,"line_end":50,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":931,"byte_end":932,"line_start":50,"line_end":50,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":924,"byte_end":925,"line_start":50,"line_end":50,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":931,"byte_end":932,"line_start":50,"line_end":50,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
   --> $DIR/unused_parens_remove_json_suggestion.rs:50:14
    |
 LL |     for _ in (0 .. 3) {
@@ -107,7 +107,7 @@ LL +     for _ in 0 .. 3 {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":934,"byte_end":935,"line_start":51,"line_end":51,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":948,"byte_end":949,"line_start":51,"line_end":51,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":934,"byte_end":935,"line_start":51,"line_end":51,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":948,"byte_end":949,"line_start":51,"line_end":51,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":949,"byte_end":950,"line_start":51,"line_end":51,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":963,"byte_end":964,"line_start":51,"line_end":51,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":949,"byte_end":950,"line_start":51,"line_end":51,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":963,"byte_end":964,"line_start":51,"line_end":51,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:51:15
    |
 LL |         while (true && false) {
diff --git a/tests/ui/missing/missing-block-hint.stderr b/tests/ui/missing/missing-block-hint.stderr
index 18719289abd..7a08d70d0ce 100644
--- a/tests/ui/missing/missing-block-hint.stderr
+++ b/tests/ui/missing/missing-block-hint.stderr
@@ -25,7 +25,7 @@ note: the `if` expression is missing a block after this condition
    |
 LL |         if (foo)
    |            ^^^^^
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |             { bar; }
    |             +      +
diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
index 6bc4501b6a3..e8d0be10d4d 100644
--- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr
+++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn smeg() {
    | ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail
diff --git a/tests/ui/never_type/defaulted-never-note.rs b/tests/ui/never_type/defaulted-never-note.rs
index 40861e73b39..badb5d4c51d 100644
--- a/tests/ui/never_type/defaulted-never-note.rs
+++ b/tests/ui/never_type/defaulted-never-note.rs
@@ -27,7 +27,7 @@ fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
 //[fallback]~| NOTE required by a bound in `foo`
 fn smeg() {
     //[nofallback]~^ warn: this function depends on never type fallback being `()`
-    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     let _x = return;
     foo(_x);
     //[fallback]~^ ERROR the trait bound
diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.rs b/tests/ui/never_type/dependency-on-fallback-to-unit.rs
index 5448d0be2c6..fad4c7c7df7 100644
--- a/tests/ui/never_type/dependency-on-fallback-to-unit.rs
+++ b/tests/ui/never_type/dependency-on-fallback-to-unit.rs
@@ -7,7 +7,7 @@ fn main() {
 
 fn def() {
     //~^ warn: this function depends on never type fallback being `()`
-    //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     match true {
         false => <_>::default(),
         true => return,
@@ -18,7 +18,7 @@ fn def() {
 // <https://github.com/rust-lang/rust/issues/39216>
 fn question_mark() -> Result<(), ()> {
     //~^ warn: this function depends on never type fallback being `()`
-    //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     deserialize()?;
     Ok(())
 }
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 79f47bb5fbc..2f10428ee93 100644
--- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
+++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn def() {
    | ^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
@@ -24,7 +24,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn question_mark() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
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 d40d1da76f9..35b245bd743 100644
--- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn assignment() {
    | ^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: UnitDefault` will fail
@@ -24,7 +24,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn assignment_rev() {
    | ^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: UnitDefault` will fail
diff --git a/tests/ui/never_type/diverging-fallback-control-flow.rs b/tests/ui/never_type/diverging-fallback-control-flow.rs
index 575e2e9273c..647667126d4 100644
--- a/tests/ui/never_type/diverging-fallback-control-flow.rs
+++ b/tests/ui/never_type/diverging-fallback-control-flow.rs
@@ -29,7 +29,7 @@ impl UnitDefault for () {
 
 fn assignment() {
     //[nofallback]~^ warn: this function depends on never type fallback being `()`
-    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     let x;
 
     if true {
@@ -41,7 +41,7 @@ fn assignment() {
 
 fn assignment_rev() {
     //[nofallback]~^ warn: this function depends on never type fallback being `()`
-    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     let x;
 
     if true {
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 d11c21d9573..689791fc460 100644
--- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn main() {
    | ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Test` will fail
diff --git a/tests/ui/never_type/diverging-fallback-no-leak.rs b/tests/ui/never_type/diverging-fallback-no-leak.rs
index c6d59c7f273..75ca491bf46 100644
--- a/tests/ui/never_type/diverging-fallback-no-leak.rs
+++ b/tests/ui/never_type/diverging-fallback-no-leak.rs
@@ -13,7 +13,7 @@ fn unconstrained_arg<T: Test>(_: T) {}
 
 fn main() {
     //[nofallback]~^ warn: this function depends on never type fallback being `()`
-    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
 
     // Here the type variable falls back to `!`,
     // and hence we get a type error.
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 30a5e60a758..42018c54609 100644
--- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn main() {
    | ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: UnitReturn` will fail
diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.rs b/tests/ui/never_type/diverging-fallback-unconstrained-return.rs
index 927991db513..fdea3a94d28 100644
--- a/tests/ui/never_type/diverging-fallback-unconstrained-return.rs
+++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.rs
@@ -27,7 +27,7 @@ fn unconstrained_return<T: UnitReturn>() -> T {
 
 fn main() {
     //[nofallback]~^ warn: this function depends on never type fallback being `()`
-    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
 
     // In Ye Olde Days, the `T` parameter of `unconstrained_return`
     // winds up "entangled" with the `!` type that results from
diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
index fb0166dd9e0..b5b5d87e7dd 100644
--- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
+++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn main() {
    | ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Bar` will fail
diff --git a/tests/ui/never_type/fallback-closure-ret.rs b/tests/ui/never_type/fallback-closure-ret.rs
index 30f9ac54d0b..f1423354f13 100644
--- a/tests/ui/never_type/fallback-closure-ret.rs
+++ b/tests/ui/never_type/fallback-closure-ret.rs
@@ -20,6 +20,6 @@ fn foo<R: Bar>(_: impl Fn() -> R) {}
 
 fn main() {
     //[nofallback]~^ warn: this function depends on never type fallback being `()`
-    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     foo(|| panic!());
 }
diff --git a/tests/ui/never_type/impl_trait_fallback.rs b/tests/ui/never_type/impl_trait_fallback.rs
index fbe13dbe2ac..bd4caeb2b72 100644
--- a/tests/ui/never_type/impl_trait_fallback.rs
+++ b/tests/ui/never_type/impl_trait_fallback.rs
@@ -7,6 +7,6 @@ impl T for () {}
 
 fn should_ret_unit() -> impl T {
     //~^ warn: this function depends on never type fallback being `()`
-    //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
     panic!()
 }
diff --git a/tests/ui/never_type/impl_trait_fallback.stderr b/tests/ui/never_type/impl_trait_fallback.stderr
index 4496746e018..768c226e989 100644
--- a/tests/ui/never_type/impl_trait_fallback.stderr
+++ b/tests/ui/never_type/impl_trait_fallback.stderr
@@ -4,7 +4,7 @@ warning: this function depends on never type fallback being `()`
 LL | fn should_ret_unit() -> impl T {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: T` will fail
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 6a48a7b9b47..03bb0ca5f3a 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
@@ -4,7 +4,7 @@ warning: never type fallback affects this call to an `unsafe` function
 LL |         unsafe { mem::zeroed() }
    |                  ^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -19,7 +19,7 @@ warning: never type fallback affects this call to an `unsafe` function
 LL |             core::mem::transmute(Zst)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -33,7 +33,7 @@ warning: never type fallback affects this union access
 LL |         unsafe { Union { a: () }.b }
    |                  ^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
 
@@ -43,7 +43,7 @@ warning: never type fallback affects this raw pointer dereference
 LL |         unsafe { *ptr::from_ref(&()).cast() }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -57,7 +57,7 @@ warning: never type fallback affects this call to an `unsafe` function
 LL |         unsafe { internally_create(x) }
    |                  ^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -71,7 +71,7 @@ warning: never type fallback affects this call to an `unsafe` function
 LL |         unsafe { zeroed() }
    |                  ^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -85,7 +85,7 @@ warning: never type fallback affects this `unsafe` function
 LL |         let zeroed = mem::zeroed;
    |                      ^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -99,7 +99,7 @@ warning: never type fallback affects this `unsafe` function
 LL |         let f = internally_create;
    |                 ^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -113,7 +113,7 @@ warning: never type fallback affects this call to an `unsafe` method
 LL |             S(marker::PhantomData).create_out_of_thin_air()
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
 
@@ -126,7 +126,7 @@ LL |             match send_message::<_ /* ?0 */>() {
 LL |         msg_send!();
    |         ----------- in this macro invocation
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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)
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 844cd62c267..cf12d699f2e 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
@@ -4,7 +4,7 @@ error: never type fallback affects this call to an `unsafe` function
 LL |         unsafe { mem::zeroed() }
    |                  ^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -19,7 +19,7 @@ error: never type fallback affects this call to an `unsafe` function
 LL |             core::mem::transmute(Zst)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -33,7 +33,7 @@ error: never type fallback affects this union access
 LL |         unsafe { Union { a: () }.b }
    |                  ^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
 
@@ -43,7 +43,7 @@ error: never type fallback affects this raw pointer dereference
 LL |         unsafe { *ptr::from_ref(&()).cast() }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -57,7 +57,7 @@ error: never type fallback affects this call to an `unsafe` function
 LL |         unsafe { internally_create(x) }
    |                  ^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -71,7 +71,7 @@ error: never type fallback affects this call to an `unsafe` function
 LL |         unsafe { zeroed() }
    |                  ^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -85,7 +85,7 @@ error: never type fallback affects this `unsafe` function
 LL |         let zeroed = mem::zeroed;
    |                      ^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -99,7 +99,7 @@ error: never type fallback affects this `unsafe` function
 LL |         let f = internally_create;
    |                 ^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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
@@ -113,7 +113,7 @@ error: never type fallback affects this call to an `unsafe` method
 LL |             S(marker::PhantomData).create_out_of_thin_air()
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
 
@@ -126,7 +126,7 @@ LL |             match send_message::<_ /* ?0 */>() {
 LL |         msg_send!();
    |         ----------- in this macro invocation
    |
-   = warning: this will change its meaning in a future release!
+   = warning: this changes meaning in Rust 2024 and in a future release in all editions!
    = 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)
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs
index c96f4dda3f8..19b51eea2f5 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs
@@ -13,7 +13,7 @@ fn _zero() {
         unsafe { mem::zeroed() }
         //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function
         //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
         //[e2024]~| warning: the type `!` does not permit zero-initialization
     } else {
         return;
@@ -30,7 +30,7 @@ fn _trans() {
             core::mem::transmute(Zst)
             //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function
             //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function
-            //~| warn: this will change its meaning in a future release!
+            //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
         }
     } else {
         return;
@@ -47,7 +47,7 @@ fn _union() {
         unsafe { Union { a: () }.b }
         //[e2015]~^ warn: never type fallback affects this union access
         //[e2024]~^^ error: never type fallback affects this union access
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
     } else {
         return;
     };
@@ -58,7 +58,7 @@ fn _deref() {
         unsafe { *ptr::from_ref(&()).cast() }
         //[e2015]~^ warn: never type fallback affects this raw pointer dereference
         //[e2024]~^^ error: never type fallback affects this raw pointer dereference
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
     } else {
         return;
     };
@@ -79,7 +79,7 @@ fn _only_generics() {
         unsafe { internally_create(x) }
         //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function
         //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
 
         x.unwrap()
     } else {
@@ -92,12 +92,12 @@ fn _stored_function() {
         let zeroed = mem::zeroed;
         //[e2015]~^ warn: never type fallback affects this `unsafe` function
         //[e2024]~^^ error: never type fallback affects this `unsafe` function
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
 
         unsafe { zeroed() }
         //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function
         //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
     } else {
         return;
     };
@@ -115,7 +115,7 @@ fn _only_generics_stored_function() {
         let f = internally_create;
         //[e2015]~^ warn: never type fallback affects this `unsafe` function
         //[e2024]~^^ error: never type fallback affects this `unsafe` function
-        //~| warn: this will change its meaning in a future release!
+        //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
 
         unsafe { f(x) }
 
@@ -140,7 +140,7 @@ fn _method() {
             S(marker::PhantomData).create_out_of_thin_air()
             //[e2015]~^ warn: never type fallback affects this call to an `unsafe` method
             //[e2024]~^^ error: never type fallback affects this call to an `unsafe` method
-            //~| warn: this will change its meaning in a future release!
+            //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
         }
     } else {
         return;
@@ -158,7 +158,7 @@ fn _objc() {
             match send_message::<_ /* ?0 */>() {
                 //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function
                 //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function
-                //~| warn: this will change its meaning in a future release!
+                //~| warn: this changes meaning in Rust 2024 and in a future release in all editions!
                 Ok(x) => x,
                 Err(_) => loop {},
             }
diff --git a/tests/ui/parser/bad-if-statements.stderr b/tests/ui/parser/bad-if-statements.stderr
index ee839db6455..320b1176993 100644
--- a/tests/ui/parser/bad-if-statements.stderr
+++ b/tests/ui/parser/bad-if-statements.stderr
@@ -29,7 +29,7 @@ note: the `if` expression is missing a block after this condition
    |
 LL |     if true x
    |        ^^^^
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     if true { x }
    |             +   +
@@ -65,7 +65,7 @@ note: the `if` expression is missing a block after this condition
    |
 LL |     if true x else {}
    |        ^^^^
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     if true { x } else {}
    |             +   +
diff --git a/tests/ui/parser/block-no-opening-brace.stderr b/tests/ui/parser/block-no-opening-brace.stderr
index 83360944ed5..b65de4eac3f 100644
--- a/tests/ui/parser/block-no-opening-brace.stderr
+++ b/tests/ui/parser/block-no-opening-brace.stderr
@@ -6,7 +6,7 @@ LL |     loop
 LL |         let x = 0;
    |         ^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |         { let x = 0; }
    |         +            +
@@ -21,7 +21,7 @@ LL |     while true
 LL |         let x = 0;
    |         ^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |         { let x = 0; }
    |         +            +
@@ -32,7 +32,7 @@ error: expected `{`, found keyword `let`
 LL |         let x = 0;
    |         ^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |         { let x = 0; }
    |         +            +
diff --git a/tests/ui/parser/closure-return-syntax.stderr b/tests/ui/parser/closure-return-syntax.stderr
index eb8428854af..aacc31ed871 100644
--- a/tests/ui/parser/closure-return-syntax.stderr
+++ b/tests/ui/parser/closure-return-syntax.stderr
@@ -4,7 +4,7 @@ error: expected `{`, found `22`
 LL |     let x = || -> i32 22;
    |                       ^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     let x = || -> i32 { 22 };
    |                       +    +
diff --git a/tests/ui/parser/else-no-if.stderr b/tests/ui/parser/else-no-if.stderr
index 2e3e8f6b50e..eec64b0f4bc 100644
--- a/tests/ui/parser/else-no-if.stderr
+++ b/tests/ui/parser/else-no-if.stderr
@@ -30,7 +30,7 @@ error: expected `{`, found `falsy`
 LL |     } else falsy();
    |            ^^^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     } else { falsy() };
    |            +         +
@@ -41,7 +41,7 @@ error: expected `{`, found keyword `loop`
 LL |     } else loop{}
    |            ^^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     } else { loop{} }
    |            +        +
@@ -65,7 +65,7 @@ error: expected `{`, found `falsy`
 LL |     } else falsy!();
    |            ^^^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     } else { falsy!() };
    |            +          +
@@ -74,12 +74,14 @@ error: expected `{`, found `falsy`
   --> $DIR/else-no-if.rs:47:12
    |
 LL |     } else falsy! {} {
-   |            ^^^^^ expected `{`
+   |       ---- ^^^^^
+   |       |
+   |       expected an `if` or a block after this `else`
    |
-help: try placing this code inside a block
+help: add an `if` if this is the condition of a chained `else if` statement
    |
-LL |     } else { falsy! {} } {
-   |            +           +
+LL |     } else if falsy! {} {
+   |            ++
 
 error: expected `{`, found `falsy`
   --> $DIR/else-no-if.rs:54:12
@@ -87,7 +89,7 @@ error: expected `{`, found `falsy`
 LL |     } else falsy! {};
    |            ^^^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     } else { falsy! {} };
    |            +           +
diff --git a/tests/ui/parser/label-after-block-like.stderr b/tests/ui/parser/label-after-block-like.stderr
index be8c679d8ce..4dea225e3f3 100644
--- a/tests/ui/parser/label-after-block-like.stderr
+++ b/tests/ui/parser/label-after-block-like.stderr
@@ -23,7 +23,7 @@ note: the `if` expression is missing a block after this condition
    |
 LL |     if let () = () 'a {}
    |        ^^^^^^^^^^^
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     if let () = () { 'a {} }
    |                    +       +
@@ -53,7 +53,7 @@ note: the `if` expression is missing a block after this condition
    |
 LL |     if true 'a {}
    |        ^^^^
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     if true { 'a {} }
    |             +       +
@@ -80,7 +80,7 @@ LL |     loop 'a {}
    |     |
    |     while parsing this `loop` expression
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     loop { 'a {} }
    |          +       +
@@ -108,7 +108,7 @@ LL |     while true 'a {}
    |     |     this `while` condition successfully parsed
    |     while parsing the body of this `while` expression
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     while true { 'a {} }
    |                +       +
@@ -136,7 +136,7 @@ LL |     while let () = () 'a {}
    |     |     this `while` condition successfully parsed
    |     while parsing the body of this `while` expression
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     while let () = () { 'a {} }
    |                       +       +
@@ -161,7 +161,7 @@ error: expected `{`, found `'a`
 LL |     for _ in 0..0 'a {}
    |                   ^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     for _ in 0..0 { 'a {} }
    |                   +       +
@@ -188,7 +188,7 @@ LL |     unsafe 'a {}
    |     |
    |     while parsing this `unsafe` expression
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |     unsafe { 'a {} }
    |            +       +
diff --git a/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.fixed b/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.fixed
new file mode 100644
index 00000000000..ea9dc4cf6cc
--- /dev/null
+++ b/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.fixed
@@ -0,0 +1,39 @@
+//@ run-rustfix
+#![allow(dead_code)]
+fn main() {
+    for _ in [1, 2, 3].iter().map(|x| x) {}
+    //~^ ERROR expected `{`, found `map`
+    //~| HELP you might have meant to write a method call
+}
+fn foo5() {
+    let x = (vec![1, 2, 3],);
+    for _ in x.0 {}
+    //~^ ERROR expected `{`, found `0`
+    //~| HELP you might have meant to write a field access
+}
+fn foo6() {
+    let x = ((vec![1, 2, 3],),);
+    for _ in x.0.0 {}
+    //~^ ERROR expected `{`, found `0.0`
+    //~| HELP you might have meant to write a field access
+}
+fn foo7() {
+    let x = Some(vec![1, 2, 3]);
+    for _ in x.unwrap() {}
+    //~^ ERROR expected `{`, found `unwrap`
+    //~| HELP you might have meant to write a method call
+}
+fn foo8() {
+    let x = S { a: A { b: vec![1, 2, 3] } };
+    for _ in x.a.b {}
+    //~^ ERROR expected `{`, found `a`
+    //~| HELP you might have meant to write a field access
+}
+
+struct S {
+    a: A,
+}
+
+struct A {
+    b: Vec<i32>,
+}
diff --git a/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.rs b/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.rs
new file mode 100644
index 00000000000..1833f458a8a
--- /dev/null
+++ b/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.rs
@@ -0,0 +1,39 @@
+//@ run-rustfix
+#![allow(dead_code)]
+fn main() {
+    for _ in [1, 2, 3].iter()map(|x| x) {}
+    //~^ ERROR expected `{`, found `map`
+    //~| HELP you might have meant to write a method call
+}
+fn foo5() {
+    let x = (vec![1, 2, 3],);
+    for _ in x 0 {}
+    //~^ ERROR expected `{`, found `0`
+    //~| HELP you might have meant to write a field access
+}
+fn foo6() {
+    let x = ((vec![1, 2, 3],),);
+    for _ in x 0.0 {}
+    //~^ ERROR expected `{`, found `0.0`
+    //~| HELP you might have meant to write a field access
+}
+fn foo7() {
+    let x = Some(vec![1, 2, 3]);
+    for _ in x unwrap() {}
+    //~^ ERROR expected `{`, found `unwrap`
+    //~| HELP you might have meant to write a method call
+}
+fn foo8() {
+    let x = S { a: A { b: vec![1, 2, 3] } };
+    for _ in x a.b {}
+    //~^ ERROR expected `{`, found `a`
+    //~| HELP you might have meant to write a field access
+}
+
+struct S {
+    a: A,
+}
+
+struct A {
+    b: Vec<i32>,
+}
diff --git a/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.stderr b/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.stderr
new file mode 100644
index 00000000000..87f76efffa6
--- /dev/null
+++ b/tests/ui/parser/recover/missing-dot-on-if-condition-expression-fixable.stderr
@@ -0,0 +1,57 @@
+error: expected `{`, found `map`
+  --> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30
+   |
+LL |     for _ in [1, 2, 3].iter()map(|x| x) {}
+   |                              ^^^ expected `{`
+   |
+help: you might have meant to write a method call
+   |
+LL |     for _ in [1, 2, 3].iter().map(|x| x) {}
+   |                              +
+
+error: expected `{`, found `0`
+  --> $DIR/missing-dot-on-if-condition-expression-fixable.rs:10:16
+   |
+LL |     for _ in x 0 {}
+   |                ^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in x.0 {}
+   |               +
+
+error: expected `{`, found `0.0`
+  --> $DIR/missing-dot-on-if-condition-expression-fixable.rs:16:16
+   |
+LL |     for _ in x 0.0 {}
+   |                ^^^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in x.0.0 {}
+   |               +
+
+error: expected `{`, found `unwrap`
+  --> $DIR/missing-dot-on-if-condition-expression-fixable.rs:22:16
+   |
+LL |     for _ in x unwrap() {}
+   |                ^^^^^^ expected `{`
+   |
+help: you might have meant to write a method call
+   |
+LL |     for _ in x.unwrap() {}
+   |               +
+
+error: expected `{`, found `a`
+  --> $DIR/missing-dot-on-if-condition-expression-fixable.rs:28:16
+   |
+LL |     for _ in x a.b {}
+   |                ^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in x.a.b {}
+   |               +
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/parser/recover/missing-dot-on-if-condition-expression.rs b/tests/ui/parser/recover/missing-dot-on-if-condition-expression.rs
new file mode 100644
index 00000000000..c4a9ed66a83
--- /dev/null
+++ b/tests/ui/parser/recover/missing-dot-on-if-condition-expression.rs
@@ -0,0 +1,57 @@
+fn main() {
+    for _ in [1, 2, 3].iter()map(|x| x) {}
+    //~^ ERROR expected `{`, found `map`
+    //~| HELP you might have meant to write a method call
+}
+fn foo1() {
+    for _ in 1.3f64 cos() {}
+    //~^ ERROR expected `{`, found `cos`
+    //~| HELP you might have meant to write a method call
+}
+fn foo2() {
+    for _ in 1.3 cos {}
+    //~^ ERROR expected `{`, found `cos`
+    //~| HELP you might have meant to write a field access
+}
+fn foo3() {
+    for _ in 1 cos() {}
+    //~^ ERROR expected `{`, found `cos`
+    //~| HELP you might have meant to write a method call
+}
+fn foo4() {
+    for _ in 1 cos {}
+    //~^ ERROR expected `{`, found `cos`
+    //~| HELP you might have meant to write a field access
+}
+fn foo5() {
+    let x = (vec![1, 2, 3],);
+    for _ in x 0 {}
+    //~^ ERROR expected `{`, found `0`
+    //~| HELP you might have meant to write a field access
+}
+fn foo6() {
+    let x = ((vec![1, 2, 3],),);
+    for _ in x 0.0 {}
+    //~^ ERROR expected `{`, found `0.0`
+    //~| HELP you might have meant to write a field access
+}
+fn foo7() {
+    let x = Some(vec![1, 2, 3]);
+    for _ in x unwrap() {}
+    //~^ ERROR expected `{`, found `unwrap`
+    //~| HELP you might have meant to write a method call
+}
+fn foo8() {
+    let x = S { a: A { b: vec![1, 2, 3] } };
+    for _ in x a.b {}
+    //~^ ERROR expected `{`, found `a`
+    //~| HELP you might have meant to write a field access
+}
+
+struct S {
+    a: A,
+}
+
+struct A {
+    b: Vec<i32>,
+}
diff --git a/tests/ui/parser/recover/missing-dot-on-if-condition-expression.stderr b/tests/ui/parser/recover/missing-dot-on-if-condition-expression.stderr
new file mode 100644
index 00000000000..bfb72b95682
--- /dev/null
+++ b/tests/ui/parser/recover/missing-dot-on-if-condition-expression.stderr
@@ -0,0 +1,101 @@
+error: expected `{`, found `map`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:2:30
+   |
+LL |     for _ in [1, 2, 3].iter()map(|x| x) {}
+   |                              ^^^ expected `{`
+   |
+help: you might have meant to write a method call
+   |
+LL |     for _ in [1, 2, 3].iter().map(|x| x) {}
+   |                              +
+
+error: expected `{`, found `cos`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:7:21
+   |
+LL |     for _ in 1.3f64 cos() {}
+   |                     ^^^ expected `{`
+   |
+help: you might have meant to write a method call
+   |
+LL |     for _ in 1.3f64.cos() {}
+   |                    +
+
+error: expected `{`, found `cos`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:12:18
+   |
+LL |     for _ in 1.3 cos {}
+   |                  ^^^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in 1.3.cos {}
+   |                 +
+
+error: expected `{`, found `cos`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:17:16
+   |
+LL |     for _ in 1 cos() {}
+   |                ^^^ expected `{`
+   |
+help: you might have meant to write a method call
+   |
+LL |     for _ in 1.cos() {}
+   |               +
+
+error: expected `{`, found `cos`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:22:16
+   |
+LL |     for _ in 1 cos {}
+   |                ^^^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in 1.cos {}
+   |               +
+
+error: expected `{`, found `0`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:28:16
+   |
+LL |     for _ in x 0 {}
+   |                ^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in x.0 {}
+   |               +
+
+error: expected `{`, found `0.0`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:34:16
+   |
+LL |     for _ in x 0.0 {}
+   |                ^^^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in x.0.0 {}
+   |               +
+
+error: expected `{`, found `unwrap`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:40:16
+   |
+LL |     for _ in x unwrap() {}
+   |                ^^^^^^ expected `{`
+   |
+help: you might have meant to write a method call
+   |
+LL |     for _ in x.unwrap() {}
+   |               +
+
+error: expected `{`, found `a`
+  --> $DIR/missing-dot-on-if-condition-expression.rs:46:16
+   |
+LL |     for _ in x a.b {}
+   |                ^ expected `{`
+   |
+help: you might have meant to write a field access
+   |
+LL |     for _ in x.a.b {}
+   |               +
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/parser/unnecessary-let.fixed b/tests/ui/parser/unnecessary-let.fixed
new file mode 100644
index 00000000000..bdee07e76aa
--- /dev/null
+++ b/tests/ui/parser/unnecessary-let.fixed
@@ -0,0 +1,13 @@
+//@ run-rustfix
+
+fn main() {
+    for _x in [1, 2, 3] {}
+    //~^ ERROR expected pattern, found `let`
+    //~| ERROR missing `in` in `for` loop
+
+    match 1 {
+        1 => {}
+        //~^ ERROR expected pattern, found `let`
+        _ => {}
+    }
+}
diff --git a/tests/ui/parser/unnecessary-let.rs b/tests/ui/parser/unnecessary-let.rs
index 6279109621d..a889d9f7789 100644
--- a/tests/ui/parser/unnecessary-let.rs
+++ b/tests/ui/parser/unnecessary-let.rs
@@ -1,5 +1,7 @@
+//@ run-rustfix
+
 fn main() {
-    for let x of [1, 2, 3] {}
+    for let _x of [1, 2, 3] {}
     //~^ ERROR expected pattern, found `let`
     //~| ERROR missing `in` in `for` loop
 
diff --git a/tests/ui/parser/unnecessary-let.stderr b/tests/ui/parser/unnecessary-let.stderr
index 05ac1faafd4..0b28123747a 100644
--- a/tests/ui/parser/unnecessary-let.stderr
+++ b/tests/ui/parser/unnecessary-let.stderr
@@ -1,31 +1,31 @@
 error: expected pattern, found `let`
-  --> $DIR/unnecessary-let.rs:2:9
+  --> $DIR/unnecessary-let.rs:4:9
    |
-LL |     for let x of [1, 2, 3] {}
-   |         ^^^^
+LL |     for let _x of [1, 2, 3] {}
+   |         ^^^
    |
 help: remove the unnecessary `let` keyword
    |
-LL -     for let x of [1, 2, 3] {}
-LL +     for x of [1, 2, 3] {}
+LL -     for let _x of [1, 2, 3] {}
+LL +     for _x of [1, 2, 3] {}
    |
 
 error: missing `in` in `for` loop
-  --> $DIR/unnecessary-let.rs:2:15
+  --> $DIR/unnecessary-let.rs:4:16
    |
-LL |     for let x of [1, 2, 3] {}
-   |               ^^
+LL |     for let _x of [1, 2, 3] {}
+   |                ^^
    |
 help: try using `in` here instead
    |
-LL |     for let x in [1, 2, 3] {}
-   |               ~~
+LL |     for let _x in [1, 2, 3] {}
+   |                ~~
 
 error: expected pattern, found `let`
-  --> $DIR/unnecessary-let.rs:7:9
+  --> $DIR/unnecessary-let.rs:9:9
    |
 LL |         let 1 => {}
-   |         ^^^^
+   |         ^^^
    |
 help: remove the unnecessary `let` keyword
    |
diff --git a/tests/ui/pattern/usefulness/conflicting_bindings.rs b/tests/ui/pattern/usefulness/conflicting_bindings.rs
index 0b3e7ce9e9a..16737e0a894 100644
--- a/tests/ui/pattern/usefulness/conflicting_bindings.rs
+++ b/tests/ui/pattern/usefulness/conflicting_bindings.rs
@@ -10,6 +10,8 @@ fn main() {
     //~^ ERROR: mutable more than once
     if let Some(ref mut y @ ref mut z) = x && true {}
     //~^ ERROR: mutable more than once
+    if let Some(_) = Some(()) && let Some(ref mut y @ ref mut z) = x && true {}
+    //~^ ERROR: mutable more than once
     while let Some(ref mut y @ ref mut z) = x {}
     //~^ ERROR: mutable more than once
     while let Some(ref mut y @ ref mut z) = x && true {}
diff --git a/tests/ui/pattern/usefulness/conflicting_bindings.stderr b/tests/ui/pattern/usefulness/conflicting_bindings.stderr
index 679fc83e7f5..6f6504e6f64 100644
--- a/tests/ui/pattern/usefulness/conflicting_bindings.stderr
+++ b/tests/ui/pattern/usefulness/conflicting_bindings.stderr
@@ -31,7 +31,15 @@ LL |     if let Some(ref mut y @ ref mut z) = x && true {}
    |                 value is mutably borrowed by `y` here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/conflicting_bindings.rs:13:20
+  --> $DIR/conflicting_bindings.rs:13:43
+   |
+LL |     if let Some(_) = Some(()) && let Some(ref mut y @ ref mut z) = x && true {}
+   |                                           ^^^^^^^^^   --------- value is mutably borrowed by `z` here
+   |                                           |
+   |                                           value is mutably borrowed by `y` here
+
+error: cannot borrow value as mutable more than once at a time
+  --> $DIR/conflicting_bindings.rs:15:20
    |
 LL |     while let Some(ref mut y @ ref mut z) = x {}
    |                    ^^^^^^^^^   --------- value is mutably borrowed by `z` here
@@ -39,7 +47,7 @@ LL |     while let Some(ref mut y @ ref mut z) = x {}
    |                    value is mutably borrowed by `y` here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/conflicting_bindings.rs:15:20
+  --> $DIR/conflicting_bindings.rs:17:20
    |
 LL |     while let Some(ref mut y @ ref mut z) = x && true {}
    |                    ^^^^^^^^^   --------- value is mutably borrowed by `z` here
@@ -47,7 +55,7 @@ LL |     while let Some(ref mut y @ ref mut z) = x && true {}
    |                    value is mutably borrowed by `y` here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/conflicting_bindings.rs:18:9
+  --> $DIR/conflicting_bindings.rs:20:9
    |
 LL |         ref mut y @ ref mut z => {}
    |         ^^^^^^^^^   --------- value is mutably borrowed by `z` here
@@ -55,12 +63,12 @@ LL |         ref mut y @ ref mut z => {}
    |         value is mutably borrowed by `y` here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/conflicting_bindings.rs:21:24
+  --> $DIR/conflicting_bindings.rs:23:24
    |
 LL |         () if let Some(ref mut y @ ref mut z) = x => {}
    |                        ^^^^^^^^^   --------- value is mutably borrowed by `z` here
    |                        |
    |                        value is mutably borrowed by `y` here
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs
index 5c333cd7795..47653efffb7 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs
@@ -94,4 +94,15 @@ fn use_in_arm_ok(c: bool) {
     };
 }
 
+fn use_in_same_chain(c: bool) {
+    let x: Box<_> = Box::new(1);
+
+    let v = (1, 2);
+
+    match v {
+        (1, 2) if let y = x && c && let z = x => false, //~ ERROR use of moved value: `x`
+        _ => true,
+    };
+}
+
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
index 087e54244b3..123c5f19430 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
@@ -60,6 +60,22 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         (1, 2) if let ref y = x && c => false,
    |                       +++
 
-error: aborting due to 4 previous errors
+error[E0382]: use of moved value: `x`
+  --> $DIR/move-guard-if-let-chain.rs:103:41
+   |
+LL |     let x: Box<_> = Box::new(1);
+   |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+...
+LL |         (1, 2) if let y = x && c && let z = x => false,
+   |                       -                 ^ value used here after move
+   |                       |
+   |                       value moved here
+   |
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |         (1, 2) if let ref y = x && c && let z = x => false,
+   |                       +++
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
new file mode 100644
index 00000000000..389c76337f0
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
@@ -0,0 +1,25 @@
+// issue-103476
+//@ compile-flags: -Zlint-mir -Zunstable-options
+//@ edition: 2024
+//@ check-pass
+
+#![feature(let_chains)]
+#![allow(irrefutable_let_patterns)]
+
+struct Pd;
+
+impl Pd {
+    fn it(&self) -> It {
+        todo!()
+    }
+}
+
+pub struct It<'a>(Box<dyn Tr<'a>>);
+
+trait Tr<'a> {}
+
+fn f(m: Option<Pd>) {
+    if let Some(n) = m && let it = n.it() {};
+}
+
+fn main() {}
diff --git a/tests/ui/structs-enums/enum-rec/issue-17431-6.rs b/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
index 0183bdba111..a3b510848dc 100644
--- a/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
@@ -1,8 +1,6 @@
-//@ ignore-apple: cycle error does not appear on apple
+use std::cell::UnsafeCell;
 
-use std::sync::Mutex;
-
-enum Foo { X(Mutex<Option<Foo>>) }
+enum Foo { X(UnsafeCell<Option<Foo>>) }
 //~^ ERROR recursive type `Foo` has infinite size
 //~| ERROR cycle detected
 
diff --git a/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr b/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
index 22f8519d0ef..b192593d266 100644
--- a/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
@@ -1,18 +1,18 @@
 error[E0072]: recursive type `Foo` has infinite size
-  --> $DIR/issue-17431-6.rs:5:1
+  --> $DIR/issue-17431-6.rs:3:1
    |
-LL | enum Foo { X(Mutex<Option<Foo>>) }
-   | ^^^^^^^^                  --- recursive without indirection
+LL | enum Foo { X(UnsafeCell<Option<Foo>>) }
+   | ^^^^^^^^                       --- recursive without indirection
    |
 help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
-LL | enum Foo { X(Mutex<Option<Box<Foo>>>) }
-   |                           ++++   +
+LL | enum Foo { X(UnsafeCell<Option<Box<Foo>>>) }
+   |                                ++++   +
 
 error[E0391]: cycle detected when computing when `Foo` needs drop
-  --> $DIR/issue-17431-6.rs:5:1
+  --> $DIR/issue-17431-6.rs:3:1
    |
-LL | enum Foo { X(Mutex<Option<Foo>>) }
+LL | enum Foo { X(UnsafeCell<Option<Foo>>) }
    | ^^^^^^^^
    |
    = note: ...which immediately requires computing when `Foo` needs drop again
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
index dda42580e0f..2a301788525 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
@@ -7,6 +7,7 @@ fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
     //~^ ERROR associated type `Assoc` not found for `Trait`
     //~| ERROR associated type `Assoc` not found for `Trait`
     //~| the trait bound `{integer}: Trait<()>` is not satisfied
+    //~| ERROR cannot capture late-bound type parameter in nested `impl Trait`
     16
 }
 
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
index 6e5bd34ce38..38dcdbd0af2 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
@@ -1,3 +1,9 @@
+error: cannot capture late-bound type parameter in nested `impl Trait`
+  --> $DIR/non-lifetime-binder-in-constraint.rs:6:58
+   |
+LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
+   |                          - parameter defined here        ^
+
 error[E0220]: associated type `Assoc` not found for `Trait`
   --> $DIR/non-lifetime-binder-in-constraint.rs:6:39
    |
@@ -27,7 +33,7 @@ help: this trait has no implementations, consider adding one
 LL | trait Trait<T: ?Sized> {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0220, E0277.
 For more information about an error, try `rustc --explain E0220`.
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs b/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
index 23951c34270..23f3666618b 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
@@ -5,6 +5,7 @@ trait Trait<T> {}
 
 fn f() -> impl for<T> Trait<impl Trait<T>> {}
 //~^ ERROR nested `impl Trait` is not allowed
-//~| ERROR the trait bound `(): Trait<impl Trait<T>>` is not satisfied
+//~| ERROR the trait bound `(): Trait<impl Trait<{type error}>>` is not satisfied
+//~| ERROR cannot capture late-bound type parameter in nested `impl Trait`
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr b/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
index 5859d952b75..3c352c9889c 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
+++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
@@ -7,11 +7,19 @@ LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
    |           |                 nested `impl Trait` here
    |           outer `impl Trait`
 
-error[E0277]: the trait bound `(): Trait<impl Trait<T>>` is not satisfied
+error: cannot capture late-bound type parameter in nested `impl Trait`
+  --> $DIR/non-lifetime-binder.rs:6:40
+   |
+LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
+   |                    -                   ^
+   |                    |
+   |                    parameter defined here
+
+error[E0277]: the trait bound `(): Trait<impl Trait<{type error}>>` is not satisfied
   --> $DIR/non-lifetime-binder.rs:6:11
    |
 LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<T>>` is not implemented for `()`
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<{type error}>>` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/non-lifetime-binder.rs:4:1
@@ -19,7 +27,7 @@ help: this trait has no implementations, consider adding one
 LL | trait Trait<T> {}
    | ^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0666.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsafe/unsafe-block-without-braces.stderr b/tests/ui/unsafe/unsafe-block-without-braces.stderr
index d29e49d73a6..3d8234c15e7 100644
--- a/tests/ui/unsafe/unsafe-block-without-braces.stderr
+++ b/tests/ui/unsafe/unsafe-block-without-braces.stderr
@@ -6,7 +6,7 @@ LL |     unsafe //{
 LL |         std::mem::transmute::<f32, u32>(1.0);
    |         ^^^ expected `{`
    |
-help: try placing this code inside a block
+help: you might have meant to write this as part of a block
    |
 LL |         { std::mem::transmute::<f32, u32>(1.0); }
    |         +                                       +
diff --git a/triagebot.toml b/triagebot.toml
index d5bc549ca9f..c5942fe27cd 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -997,7 +997,6 @@ compiler = [
     "@oli-obk",
     "@petrochenkov",
     "@pnkfelix",
-    "@TaKO8Ki",
     "@wesleywiser",
 ]
 libs = [
@@ -1048,7 +1047,6 @@ diagnostics = [
     "@davidtwco",
     "@estebank",
     "@oli-obk",
-    "@TaKO8Ki",
     "@chenyukang",
 ]
 parser = [