From 7269972f7336a27980ea19353a29bad0d2a1faa9 Mon Sep 17 00:00:00 2001
From: Andrew Walbran <qwandor@google.com>
Date: Fri, 2 Jun 2023 13:50:18 +0100
Subject: [PATCH 01/11] Add trustzone and virtualization target features for
 aarch32.

These are LLVM target features which allow the `smc` and `hvc`
instructions respectively to be used in inline assembly.
---
 compiler/rustc_codegen_ssa/src/target_features.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index c5976a65411fd..6a3a31a0d60ae 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -44,6 +44,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     // #[target_feature].
     ("thumb-mode", Some(sym::arm_target_feature)),
     ("thumb2", Some(sym::arm_target_feature)),
+    ("trustzone", Some(sym::arm_target_feature)),
     ("v5te", Some(sym::arm_target_feature)),
     ("v6", Some(sym::arm_target_feature)),
     ("v6k", Some(sym::arm_target_feature)),
@@ -53,6 +54,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("vfp2", Some(sym::arm_target_feature)),
     ("vfp3", Some(sym::arm_target_feature)),
     ("vfp4", Some(sym::arm_target_feature)),
+    ("virtualization", Some(sym::arm_target_feature)),
     // tidy-alphabetical-end
 ];
 

From 001b081cc1bfd24657e2dccbd9c8289f9a9d67a5 Mon Sep 17 00:00:00 2001
From: Igor Gutorov <igootorov@gmail.com>
Date: Wed, 14 Jun 2023 19:50:32 +0300
Subject: [PATCH 02/11] alloc: Allow comparing `Box`s over different allocators

---
 library/alloc/src/boxed.rs | 35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 1768687e8cd02..ce0d19f1a3cfc 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1311,39 +1311,56 @@ impl Clone for Box<str> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> {
+impl<T, A1, A2> PartialEq<Box<T, A2>> for Box<T, A1>
+where
+    T: ?Sized + PartialEq,
+    A1: Allocator,
+    A2: Allocator,
+{
     #[inline]
-    fn eq(&self, other: &Self) -> bool {
+    fn eq(&self, other: &Box<T, A2>) -> bool {
         PartialEq::eq(&**self, &**other)
     }
+
     #[inline]
-    fn ne(&self, other: &Self) -> bool {
+    fn ne(&self, other: &Box<T, A2>) -> bool {
         PartialEq::ne(&**self, &**other)
     }
 }
+
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> {
+impl<T, A1, A2> PartialOrd<Box<T, A2>> for Box<T, A1>
+where
+    T: ?Sized + PartialOrd,
+    A1: Allocator,
+    A2: Allocator,
+{
     #[inline]
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &Box<T, A2>) -> Option<Ordering> {
         PartialOrd::partial_cmp(&**self, &**other)
     }
+
     #[inline]
-    fn lt(&self, other: &Self) -> bool {
+    fn lt(&self, other: &Box<T, A2>) -> bool {
         PartialOrd::lt(&**self, &**other)
     }
+
     #[inline]
-    fn le(&self, other: &Self) -> bool {
+    fn le(&self, other: &Box<T, A2>) -> bool {
         PartialOrd::le(&**self, &**other)
     }
+
     #[inline]
-    fn ge(&self, other: &Self) -> bool {
+    fn ge(&self, other: &Box<T, A2>) -> bool {
         PartialOrd::ge(&**self, &**other)
     }
+
     #[inline]
-    fn gt(&self, other: &Self) -> bool {
+    fn gt(&self, other: &Box<T, A2>) -> bool {
         PartialOrd::gt(&**self, &**other)
     }
 }
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> {
     #[inline]

From a56c829e747a6ee2e1a1d8d20472f3a5a4d95c79 Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro.albini@ferrous-systems.com>
Date: Fri, 9 Jun 2023 11:16:25 +0200
Subject: [PATCH 03/11] merge target spec and --print=cfg for compiletest
 target info

---
 src/tools/compiletest/src/common.rs | 88 ++++++++---------------------
 1 file changed, 24 insertions(+), 64 deletions(-)

diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 1b46c42fa4cf1..40cf42995b7bf 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -453,7 +453,7 @@ impl TargetCfgs {
         let mut all_families = HashSet::new();
         let mut all_pointer_widths = HashSet::new();
 
-        for (target, cfg) in targets.into_iter() {
+        for (target, cfg) in targets.iter() {
             all_archs.insert(cfg.arch.clone());
             all_oses.insert(cfg.os.clone());
             all_oses_and_envs.insert(cfg.os_and_env());
@@ -464,11 +464,11 @@ impl TargetCfgs {
             }
             all_pointer_widths.insert(format!("{}bit", cfg.pointer_width));
 
-            all_targets.insert(target.into());
+            all_targets.insert(target.clone());
         }
 
         Self {
-            current: Self::get_current_target_config(config),
+            current: Self::get_current_target_config(config, &targets),
             all_targets,
             all_archs,
             all_oses,
@@ -480,16 +480,20 @@ impl TargetCfgs {
         }
     }
 
-    fn get_current_target_config(config: &Config) -> TargetCfg {
-        let mut arch = None;
-        let mut os = None;
-        let mut env = None;
-        let mut abi = None;
-        let mut families = Vec::new();
-        let mut pointer_width = None;
-        let mut endian = None;
-        let mut panic = None;
-
+    fn get_current_target_config(
+        config: &Config,
+        targets: &HashMap<String, TargetCfg>,
+    ) -> TargetCfg {
+        let mut cfg = targets[&config.target].clone();
+
+        // To get the target information for the current target, we take the target spec obtained
+        // from `--print=all-target-specs-json`, and then we enrich it with the information
+        // gathered from `--print=cfg --target=$target`.
+        //
+        // This is done because some parts of the target spec can be overridden with `-C` flags,
+        // which are respected for `--print=cfg` but not for `--print=all-target-specs-json`. The
+        // code below extracts them from `--print=cfg`: make sure to only override fields that can
+        // actually be changed with `-C` flags.
         for config in
             rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines()
         {
@@ -507,60 +511,16 @@ impl TargetCfgs {
                 })
                 .unwrap_or_else(|| (config, None));
 
-            match name {
-                "target_arch" => {
-                    arch = Some(value.expect("target_arch should be a key-value pair").to_string());
-                }
-                "target_os" => {
-                    os = Some(value.expect("target_os sould be a key-value pair").to_string());
-                }
-                "target_env" => {
-                    env = Some(value.expect("target_env should be a key-value pair").to_string());
-                }
-                "target_abi" => {
-                    abi = Some(value.expect("target_abi should be a key-value pair").to_string());
-                }
-                "target_family" => {
-                    families
-                        .push(value.expect("target_family should be a key-value pair").to_string());
-                }
-                "target_pointer_width" => {
-                    pointer_width = Some(
-                        value
-                            .expect("target_pointer_width should be a key-value pair")
-                            .parse::<u32>()
-                            .expect("target_pointer_width should be a valid u32"),
-                    );
-                }
-                "target_endian" => {
-                    endian = Some(match value.expect("target_endian should be a key-value pair") {
-                        "big" => Endian::Big,
-                        "little" => Endian::Little,
-                        _ => panic!("target_endian should be either 'big' or 'little'"),
-                    });
-                }
-                "panic" => {
-                    panic = Some(match value.expect("panic should be a key-value pair") {
-                        "abort" => PanicStrategy::Abort,
-                        "unwind" => PanicStrategy::Unwind,
-                        _ => panic!("panic should be either 'abort' or 'unwind'"),
-                    });
-                }
-                _ => (),
+            match (name, value) {
+                // Can be overridden with `-C panic=$strategy`.
+                ("panic", Some("abort")) => cfg.panic = PanicStrategy::Abort,
+                ("panic", Some("unwind")) => cfg.panic = PanicStrategy::Unwind,
+                ("panic", other) => panic!("unexpected value for panic cfg: {other:?}"),
+                _ => {}
             }
         }
 
-        TargetCfg {
-            arch: arch.expect("target configuration should specify target_arch"),
-            os: os.expect("target configuration should specify target_os"),
-            env: env.expect("target configuration should specify target_env"),
-            abi: abi.expect("target configuration should specify target_abi"),
-            families,
-            pointer_width: pointer_width
-                .expect("target configuration should specify target_pointer_width"),
-            endian: endian.expect("target configuration should specify target_endian"),
-            panic: panic.expect("target configuration should specify panic"),
-        }
+        cfg
     }
 }
 

From 04f658f3d3d7b5bc0b563fbc2d7d3f578cc3ea2b Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro.albini@ferrous-systems.com>
Date: Fri, 9 Jun 2023 11:32:49 +0200
Subject: [PATCH 04/11] avoid dynamic linking on targets that do not support
 dynamic linking

---
 src/tools/compiletest/src/common.rs  | 2 ++
 src/tools/compiletest/src/runtest.rs | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 40cf42995b7bf..85a8fbcffbe2d 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -542,6 +542,8 @@ pub struct TargetCfg {
     endian: Endian,
     #[serde(rename = "panic-strategy", default)]
     pub(crate) panic: PanicStrategy,
+    #[serde(default)]
+    pub(crate) dynamic_linking: bool,
 }
 
 impl TargetCfg {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 25b16e38e534a..5c8ee7895d3b8 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1810,8 +1810,8 @@ impl<'test> TestCx<'test> {
             || self.config.target.contains("wasm32")
             || self.config.target.contains("nvptx")
             || self.is_vxworks_pure_static()
-            || self.config.target.contains("sgx")
             || self.config.target.contains("bpf")
+            || !self.config.target_cfg().dynamic_linking
         {
             // We primarily compile all auxiliary libraries as dynamic libraries
             // to avoid code size bloat and large binaries as much as possible

From 767c4b9ef17370622aafdb1eae86c12d962f45ad Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro.albini@ferrous-systems.com>
Date: Wed, 17 May 2023 10:41:41 +0200
Subject: [PATCH 05/11] add support for needs-dynamic-linking

---
 src/tools/compiletest/src/header/needs.rs | 5 +++++
 tests/ui/issues/issue-12133-3.rs          | 2 +-
 tests/ui/issues/issue-85461.rs            | 1 +
 tests/ui/proc-macro/crt-static.rs         | 1 +
 4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 18b3b913a682f..0e306696a90c9 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -130,6 +130,11 @@ pub(super) fn handle_needs(
             condition: config.git_hash,
             ignore_reason: "ignored when git hashes have been omitted for building",
         },
+        Need {
+            name: "needs-dynamic-linking",
+            condition: config.target_cfg().dynamic_linking,
+            ignore_reason: "ignored on targets without dynamic linking",
+        },
     ];
 
     let (name, comment) = match ln.split_once([':', ' ']) {
diff --git a/tests/ui/issues/issue-12133-3.rs b/tests/ui/issues/issue-12133-3.rs
index e6b16e2da1dca..988b61e3bafa8 100644
--- a/tests/ui/issues/issue-12133-3.rs
+++ b/tests/ui/issues/issue-12133-3.rs
@@ -4,7 +4,7 @@
 // aux-build:issue-12133-dylib2.rs
 // ignore-emscripten no dylib support
 // ignore-musl
-// ignore-sgx no dylib support
+// needs-dynamic-linking
 
 // pretty-expanded FIXME #23616
 
diff --git a/tests/ui/issues/issue-85461.rs b/tests/ui/issues/issue-85461.rs
index 9655108876f19..092105df24e21 100644
--- a/tests/ui/issues/issue-85461.rs
+++ b/tests/ui/issues/issue-85461.rs
@@ -1,6 +1,7 @@
 // compile-flags: -Cinstrument-coverage -Ccodegen-units=4 --crate-type dylib -Copt-level=0
 // build-pass
 // needs-profiler-support
+// needs-dynamic-linking
 
 // Regression test for #85461 where MSVC sometimes fails to link instrument-coverage binaries
 // with dead code and #[inline(always)].
diff --git a/tests/ui/proc-macro/crt-static.rs b/tests/ui/proc-macro/crt-static.rs
index 020128fa21446..78592f82709d4 100644
--- a/tests/ui/proc-macro/crt-static.rs
+++ b/tests/ui/proc-macro/crt-static.rs
@@ -7,6 +7,7 @@
 // build-pass
 // force-host
 // no-prefer-dynamic
+// needs-dynamic-linking
 
 #![crate_type = "proc-macro"]
 

From c462291e0c864b7d0e218bde12c9560f99cede3b Mon Sep 17 00:00:00 2001
From: Gary Guo <gary@garyguo.net>
Date: Fri, 23 Jun 2023 17:48:54 +0100
Subject: [PATCH 06/11] Make `UnwindAction::Continue` explicit in MIR dump

---
 compiler/rustc_middle/src/mir/terminator.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 561ef371b0904..1b9c1438f406c 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -272,7 +272,8 @@ impl<'tcx> Debug for TerminatorKind<'tcx> {
 
         let unwind = match self.unwind() {
             // Not needed or included in successors
-            None | Some(UnwindAction::Continue) | Some(UnwindAction::Cleanup(_)) => None,
+            None | Some(UnwindAction::Cleanup(_)) => None,
+            Some(UnwindAction::Continue) => Some("unwind continue"),
             Some(UnwindAction::Unreachable) => Some("unwind unreachable"),
             Some(UnwindAction::Terminate) => Some("unwind terminate"),
         };

From 19ce326a08634a4014fb82d8475e4501f1ef5d28 Mon Sep 17 00:00:00 2001
From: Gary Guo <gary@garyguo.net>
Date: Fri, 23 Jun 2023 17:53:09 +0100
Subject: [PATCH 07/11] Bless tests

---
 ...Cfg-elaborate-drops.after.panic-unwind.mir |  4 +--
 .../basic_assignment.main.ElaborateDrops.diff |  2 +-
 ...ain.ElaborateDrops.before.panic-unwind.mir |  6 ++--
 ...await.a-{closure#0}.generator_resume.0.mir |  2 +-
 ...await.b-{closure#0}.generator_resume.0.mir |  2 +-
 .../terminators.direct_call.built.after.mir   |  2 +-
 .../terminators.drop_first.built.after.mir    |  2 +-
 .../terminators.drop_second.built.after.mir   |  2 +-
 .../terminators.indirect_call.built.after.mir |  2 +-
 ...y_len.norm2.InstSimplify.panic-unwind.diff |  4 +--
 ...pl#0}-clone.InstSimplify.panic-unwind.diff |  2 +-
 ...aggregate.main.ConstProp.panic-unwind.diff |  2 +-
 ...ate.main.PreCodegen.after.panic-unwind.mir |  2 +-
 ...dex.main.ConstProp.32bit.panic-unwind.diff |  4 +--
 ...dex.main.ConstProp.64bit.panic-unwind.diff |  4 +--
 ...v_by_zero.main.ConstProp.panic-unwind.diff |  8 +++---
 ...d_by_zero.main.ConstProp.panic-unwind.diff |  8 +++---
 ...ces.main.ConstProp.32bit.panic-unwind.diff |  4 +--
 ...ces.main.ConstProp.64bit.panic-unwind.diff |  4 +--
 .../boxes.main.ConstProp.panic-unwind.diff    |  2 +-
 ...ecked_add.main.ConstProp.panic-unwind.diff |  4 +--
 ...racefully.main.ConstProp.panic-unwind.diff |  2 +-
 ...fication.hello.ConstProp.panic-unwind.diff |  2 +-
 .../indirect.main.ConstProp.panic-unwind.diff |  4 +--
 ..._overflow.main.ConstProp.panic-unwind.diff |  4 +--
 ...sue_66971.main.ConstProp.panic-unwind.diff |  2 +-
 ...sue_67019.main.ConstProp.panic-unwind.diff |  2 +-
 ...dex.main.ConstProp.32bit.panic-unwind.diff |  4 +--
 ...dex.main.ConstProp.64bit.panic-unwind.diff |  4 +--
 ...tial_read.main.ConstProp.panic-unwind.diff |  2 +-
 ...op_assign.main.ConstProp.panic-unwind.diff |  2 +-
 ...et_of.concrete.ConstProp.panic-unwind.diff |  8 +++---
 ...set_of.generic.ConstProp.panic-unwind.diff |  8 +++---
 ...eat.main.ConstProp.32bit.panic-unwind.diff |  4 +--
 ...eat.main.ConstProp.64bit.panic-unwind.diff |  4 +--
 ...turn_place.add.ConstProp.panic-unwind.diff |  4 +--
 ...ace.add.PreCodegen.before.panic-unwind.mir |  2 +-
 ...opagation.main.ConstProp.panic-unwind.diff |  2 +-
 ...len.main.ConstProp.32bit.panic-unwind.diff |  4 +--
 ...len.main.ConstProp.64bit.panic-unwind.diff |  4 +--
 ...witch_int.main.ConstProp.panic-unwind.diff |  4 +--
 ...ndition-after-const-prop.panic-unwind.diff |  4 +--
 ...opagation.main.ConstProp.panic-unwind.diff |  2 +-
 ...orrowed_local.f.CopyProp.panic-unwind.diff |  4 +--
 .../branch.foo.CopyProp.panic-unwind.diff     |  6 ++--
 ...agation_arg.bar.CopyProp.panic-unwind.diff |  2 +-
 ...agation_arg.foo.CopyProp.panic-unwind.diff |  2 +-
 ...stom_move_arg.f.CopyProp.panic-unwind.diff |  8 +++---
 .../cycle.main.CopyProp.panic-unwind.diff     |  4 +--
 ...es_79191.f.CopyProp.after.panic-unwind.mir |  2 +-
 ...s_better.f.CopyProp.after.panic-unwind.mir |  2 +-
 ...sue_107511.main.CopyProp.panic-unwind.diff | 10 +++----
 .../move_arg.f.CopyProp.panic-unwind.diff     |  4 +--
 ...ve_projection.f.CopyProp.panic-unwind.diff |  6 ++--
 ...eborrow.demiraw.CopyProp.panic-unwind.diff |  4 +--
 .../reborrow.miraw.CopyProp.panic-unwind.diff |  4 +--
 .../reborrow.remut.CopyProp.panic-unwind.diff |  4 +--
 .../reborrow.reraw.CopyProp.panic-unwind.diff |  4 +--
 ...d.main.DataflowConstProp.panic-unwind.diff |  8 +++---
 ...w.main.DataflowConstProp.panic-unwind.diff |  4 +--
 ...b.main.DataflowConstProp.panic-unwind.diff |  4 +--
 ...r.main.DataflowConstProp.panic-unwind.diff |  2 +-
 ...r.main.DataflowConstProp.panic-unwind.diff |  4 +--
 ...cle.DeadStoreElimination.panic-unwind.diff |  4 +--
 ...ment_2.DeduplicateBlocks.panic-unwind.diff |  2 +-
 ...omplex_case.main.Derefer.panic-unwind.diff |  6 ++--
 ...inline_test.main.Derefer.panic-unwind.diff |  4 +--
 ...inator_test.main.Derefer.panic-unwind.diff |  4 +--
 ...o.DestinationPropagation.panic-unwind.diff |  8 +++---
 ...r.DestinationPropagation.panic-unwind.diff |  4 +--
 ...o.DestinationPropagation.panic-unwind.diff |  4 +--
 ...n.DestinationPropagation.panic-unwind.diff |  6 ++--
 ...tinationPropagation.after.panic-unwind.mir |  2 +-
 ...tinationPropagation.after.panic-unwind.mir |  2 +-
 ...o.DestinationPropagation.panic-unwind.diff |  4 +--
 ...n.DestinationPropagation.panic-unwind.diff |  2 +-
 ...f.DestinationPropagation.panic-unwind.diff |  6 ++--
 ...-Fn-call.AddMovesForPackedDrops.before.mir |  2 +-
 ...nential_common.ConstProp.panic-unwind.diff |  8 +++---
 .../asm_unwind.main.Inline.panic-unwind.diff  |  4 +--
 ...trivial_bound.foo.Inline.panic-unwind.diff |  2 +-
 .../inline/cycle.g.Inline.panic-unwind.diff   |  4 +--
 .../cycle.main.Inline.panic-unwind.diff       |  4 +--
 ...n_trait.get_query.Inline.panic-unwind.diff |  6 ++--
 ...yn_trait.mk_cycle.Inline.panic-unwind.diff |  2 +-
 ...try_execute_query.Inline.panic-unwind.diff |  4 +--
 ...tial_runtime.main.Inline.panic-unwind.diff | 28 +++++++++----------
 ...lined_no_sanitize.Inline.panic-unwind.diff |  2 +-
 ...ed_target_feature.Inline.panic-unwind.diff |  2 +-
 ...nlined_c_variadic.Inline.panic-unwind.diff |  2 +-
 ...lined_no_sanitize.Inline.panic-unwind.diff |  2 +-
 ...ed_target_feature.Inline.panic-unwind.diff |  2 +-
 .../inline_cycle.one.Inline.panic-unwind.diff |  2 +-
 .../inline_cycle.two.Inline.panic-unwind.diff |  4 +--
 ...ycle_generic.main.Inline.panic-unwind.diff |  4 +--
 ...nline_diverging.f.Inline.panic-unwind.diff |  2 +-
 ...nline_diverging.g.Inline.panic-unwind.diff |  4 +--
 ...nline_diverging.h.Inline.panic-unwind.diff |  2 +-
 ...ne_generator.main.Inline.panic-unwind.diff |  2 +-
 ...to_box_place.main.Inline.panic-unwind.diff |  2 +-
 ...options.main.Inline.after.panic-unwind.mir |  8 +++---
 ...nline_shims.clone.Inline.panic-unwind.diff |  2 +-
 ...inline_shims.drop.Inline.panic-unwind.diff |  6 ++--
 ...ecialization.main.Inline.panic-unwind.diff |  2 +-
 ..._method.test.Inline.after.panic-unwind.mir |  2 +-
 ...thod_2.test2.Inline.after.panic-unwind.mir |  2 +-
 ...ssue_106141.outer.Inline.panic-unwind.diff |  6 ++--
 ...l_unsigned_bigger.Inline.panic-unwind.diff |  2 +-
 ..._unsigned_smaller.Inline.panic-unwind.diff |  2 +-
 ...shr_signed_bigger.Inline.panic-unwind.diff |  2 +-
 ...hr_signed_smaller.Inline.panic-unwind.diff |  2 +-
 ...e_101973.inner.ConstProp.panic-unwind.diff |  8 +++---
 ...AbortUnwindingCalls.after.panic-unwind.mir |  2 +-
 ...1110.test.ElaborateDrops.panic-unwind.diff |  2 +-
 ...1888.main.ElaborateDrops.panic-unwind.diff |  2 +-
 ...est.ElaborateDrops.before.panic-unwind.mir |  6 ++--
 ...mplifyComparisonIntegral.panic-unwind.diff |  2 +-
 ...to_digit.PreCodegen.after.panic-unwind.mir |  6 ++--
 ..._bound.NormalizeArrayLen.panic-unwind.diff |  2 +-
 ...nd_mut.NormalizeArrayLen.panic-unwind.diff |  4 +--
 ...bound.LowerSliceLenCalls.panic-unwind.diff |  4 +--
 ...ain.ElaborateDrops.before.panic-unwind.mir |  2 +-
 ...e.nrvo.RenameReturnPlace.panic-unwind.diff |  2 +-
 ...cked_ops.step_forward.PreCodegen.after.mir |  4 +--
 .../loops.filter_mapped.PreCodegen.after.mir  |  4 +--
 .../loops.int_range.PreCodegen.after.mir      |  4 +--
 .../loops.mapped.PreCodegen.after.mir         |  4 +--
 .../loops.vec_move.PreCodegen.after.mir       |  4 +--
 ...ble.main.ConstProp.32bit.panic-unwind.diff |  8 +++---
 ...ble.main.ConstProp.64bit.panic-unwind.diff |  8 +++---
 ...cementOfAggregates.32bit.panic-unwind.diff |  4 +--
 ...cementOfAggregates.64bit.panic-unwind.diff |  4 +--
 ...ard_loop.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ive_loop.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ter_next.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ter_next.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ex_range.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ex_usize.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ted_loop.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ard_loop.PreCodegen.after.panic-unwind.mir |  2 +-
 ...nge_loop.PreCodegen.after.panic-unwind.mir |  2 +-
 ...rse_loop.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ext_back.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ter_next.PreCodegen.after.panic-unwind.mir |  2 +-
 ...ns.outer.PreCodegen.after.panic-unwind.mir |  2 +-
 ...e_prop.debuginfo.ReferencePropagation.diff |  2 +-
 ...dominate_storage.ReferencePropagation.diff |  2 +-
 ..._prop.maybe_dead.ReferencePropagation.diff |  6 ++--
 ...multiple_storage.ReferencePropagation.diff |  2 +-
 ...ence_propagation.ReferencePropagation.diff | 20 ++++++-------
 ...gation_const_ptr.ReferencePropagation.diff | 22 +++++++--------
 ..._propagation_mut.ReferencePropagation.diff | 20 ++++++-------
 ...pagation_mut_ptr.ReferencePropagation.diff | 20 ++++++-------
 ...ique_with_copies.ReferencePropagation.diff |  4 +--
 ...ain.RemoveStorageMarkers.panic-unwind.diff |  4 +--
 ....opt.RemoveUnneededDrops.panic-unwind.diff |  2 +-
 ...copy.RemoveUnneededDrops.panic-unwind.diff |  2 +-
 ...Cfg-elaborate-drops.after.panic-unwind.mir |  6 ++--
 ...mplifyCfg-make_shim.after.panic-unwind.mir |  2 +-
 ...Cfg-elaborate-drops.after.panic-unwind.mir |  4 +--
 ...ndition-after-const-prop.panic-unwind.diff |  2 +-
 ...foo.SimplifyLocals-final.panic-unwind.diff |  2 +-
 ...Locals-before-const-prop.panic-unwind.diff |  8 +++---
 ...ify_match.main.ConstProp.panic-unwind.diff |  2 +-
 ...n.UnreachablePropagation.panic-unwind.diff |  2 +-
 ...n.UnreachablePropagation.panic-unwind.diff |  4 +--
 ...ile_loop.PreCodegen.after.panic-unwind.mir |  4 +--
 tests/run-make/const_fn_mir/dump.mir          |  6 ++--
 168 files changed, 344 insertions(+), 344 deletions(-)

diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index 2f6c92d9e859d..4b05610f73105 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -36,7 +36,7 @@ fn main() -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = _3;
-        _5 = foo(move _6) -> bb1;
+        _5 = foo(move _6) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -45,7 +45,7 @@ fn main() -> () {
         _7 = _2;
         _8 = Len(_1);
         _9 = Lt(_7, _8);
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2;
+        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb2, unwind continue];
     }
 
     bb2: {
diff --git a/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff b/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff
index 41732211628ea..9c7b3c5197b67 100644
--- a/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff
+++ b/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff
@@ -58,7 +58,7 @@
   
       bb4: {
           StorageDead(_5);
--         drop(_4) -> bb5;
+-         drop(_4) -> [return: bb5, unwind continue];
 +         goto -> bb5;
       }
   
diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir
index cf63c4f19dacd..a72d22a9c9ffb 100644
--- a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir
@@ -19,7 +19,7 @@ fn main() -> () {
         StorageLive(_1);
         _2 = SizeOf(S);
         _3 = AlignOf(S);
-        _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1;
+        _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -30,7 +30,7 @@ fn main() -> () {
 
     bb2: {
         _1 = move _5;
-        drop(_5) -> bb3;
+        drop(_5) -> [return: bb3, unwind continue];
     }
 
     bb3: {
@@ -45,7 +45,7 @@ fn main() -> () {
         StorageDead(_7);
         StorageDead(_6);
         _0 = const ();
-        drop(_1) -> bb5;
+        drop(_1) -> [return: bb5, unwind continue];
     }
 
     bb5: {
diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
index 7e8206b02fcbf..074ebddf78bb4 100644
--- a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
@@ -30,7 +30,7 @@ fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]>
     }
 
     bb2: {
-        assert(const false, "`async fn` resumed after completion") -> bb2;
+        assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind continue];
     }
 
     bb3: {
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
index ed1388718519f..f774f32eb23e8 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
@@ -310,7 +310,7 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>,
     }
 
     bb28: {
-        assert(const false, "`async fn` resumed after completion") -> bb28;
+        assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind continue];
     }
 
     bb29: {
diff --git a/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir b/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir
index 534d7615180af..07044ceaef440 100644
--- a/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir
+++ b/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir
@@ -4,7 +4,7 @@ fn direct_call(_1: i32) -> i32 {
     let mut _0: i32;
 
     bb0: {
-        _0 = ident::<i32>(_1) -> bb1;
+        _0 = ident::<i32>(_1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir b/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir
index aba724a4b0d33..6524f754d9c48 100644
--- a/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir
+++ b/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir
@@ -4,7 +4,7 @@ fn drop_first(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () {
     let mut _0: ();
 
     bb0: {
-        drop(_1) -> bb1;
+        drop(_1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir b/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir
index 32d770bb0c139..ed3728121bd65 100644
--- a/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir
+++ b/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir
@@ -4,7 +4,7 @@ fn drop_second(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () {
     let mut _0: ();
 
     bb0: {
-        drop(_2) -> bb1;
+        drop(_2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir b/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir
index 56371c7866605..3b849354dcd8e 100644
--- a/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir
+++ b/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir
@@ -4,7 +4,7 @@ fn indirect_call(_1: i32, _2: fn(i32) -> i32) -> i32 {
     let mut _0: i32;
 
     bb0: {
-        _0 = _2(_1) -> bb1;
+        _0 = _2(_1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-unwind.diff b/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-unwind.diff
index ab7a34f840d5a..4833c1089e3c5 100644
--- a/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-unwind.diff
+++ b/tests/mir-opt/combine_array_len.norm2.InstSimplify.panic-unwind.diff
@@ -32,7 +32,7 @@
 -         _4 = Len(_1);
 +         _4 = const 2_usize;
           _5 = Lt(_3, _4);
-          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
+          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -44,7 +44,7 @@
 -         _8 = Len(_1);
 +         _8 = const 2_usize;
           _9 = Lt(_7, _8);
-          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2;
+          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff
index ee0f9fbf82894..1a4372afe697f 100644
--- a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff
+++ b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff
@@ -21,7 +21,7 @@
           _4 = &((*_1).0: T);
 -         _3 = &(*_4);
 +         _3 = _4;
-          _2 = <T as Clone>::clone(move _3) -> bb1;
+          _2 = <T as Clone>::clone(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-unwind.diff
index 73b5baafb3323..e4650046bdf1f 100644
--- a/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/aggregate.main.ConstProp.panic-unwind.diff
@@ -27,7 +27,7 @@
           StorageLive(_5);
 -         _5 = _1;
 +         _5 = const 1_u8;
-          _4 = foo(move _5) -> bb1;
+          _4 = foo(move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-unwind.mir
index 93d461a38c4ae..9590c7f90aa37 100644
--- a/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.panic-unwind.mir
@@ -23,7 +23,7 @@ fn main() -> () {
         StorageLive(_4);
         StorageLive(_5);
         _5 = const 1_u8;
-        _4 = foo(move _5) -> bb1;
+        _4 = foo(move _5) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-unwind.diff
index 9ac2fac6c0045..ec11395c3762d 100644
--- a/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.panic-unwind.diff
@@ -20,10 +20,10 @@
           _3 = const 2_usize;
 -         _4 = Len(_2);
 -         _5 = Lt(_3, _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
 +         _4 = const 4_usize;
 +         _5 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-unwind.diff
index 9ac2fac6c0045..ec11395c3762d 100644
--- a/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.panic-unwind.diff
@@ -20,10 +20,10 @@
           _3 = const 2_usize;
 -         _4 = Len(_2);
 -         _5 = Lt(_3, _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
 +         _4 = const 4_usize;
 +         _5 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-unwind.diff
index 2aff357cc3e66..a5b51681ec978 100644
--- a/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.panic-unwind.diff
@@ -24,21 +24,21 @@
           StorageLive(_3);
 -         _3 = _1;
 -         _4 = Eq(_3, const 0_i32);
--         assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1;
+-         assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> [success: bb1, unwind continue];
 +         _3 = const 0_i32;
 +         _4 = const true;
-+         assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1;
++         assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _5 = Eq(_3, const -1_i32);
 -         _6 = Eq(const 1_i32, const i32::MIN);
 -         _7 = BitAnd(move _5, move _6);
--         assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2;
+-         assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
 +         _5 = const false;
 +         _6 = const false;
 +         _7 = const false;
-+         assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2;
++         assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-unwind.diff
index db93de9630b53..4afddf3c92d7c 100644
--- a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.panic-unwind.diff
@@ -24,21 +24,21 @@
           StorageLive(_3);
 -         _3 = _1;
 -         _4 = Eq(_3, const 0_i32);
--         assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1;
+-         assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> [success: bb1, unwind continue];
 +         _3 = const 0_i32;
 +         _4 = const true;
-+         assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1;
++         assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _5 = Eq(_3, const -1_i32);
 -         _6 = Eq(const 1_i32, const i32::MIN);
 -         _7 = BitAnd(move _5, move _6);
--         assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2;
+-         assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
 +         _5 = const false;
 +         _6 = const false;
 +         _7 = const false;
-+         assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2;
++         assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff
index f39468d9684bc..2c0e4844ecc3b 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff
@@ -36,9 +36,9 @@
           _6 = const 3_usize;
           _7 = const 3_usize;
 -         _8 = Lt(_6, _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
 +         _8 = const false;
-+         assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff
index f39468d9684bc..2c0e4844ecc3b 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff
@@ -36,9 +36,9 @@
           _6 = const 3_usize;
           _7 = const 3_usize;
 -         _8 = Lt(_6, _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
 +         _8 = const false;
-+         assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-unwind.diff
index 8e3c2f6c8448a..6214766c7ee5c 100644
--- a/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/boxes.main.ConstProp.panic-unwind.diff
@@ -26,7 +26,7 @@
 -         _5 = AlignOf(i32);
 +         _4 = const 4_usize;
 +         _5 = const 4_usize;
-          _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1;
+          _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff
index 175e2b51a37c6..125407bf285a3 100644
--- a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff
@@ -12,9 +12,9 @@
       bb0: {
           StorageLive(_1);
 -         _2 = CheckedAdd(const 1_u32, const 1_u32);
--         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1;
+-         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind continue];
 +         _2 = const (2_u32, false);
-+         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1;
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-unwind.diff
index 01ec24916c895..850b743feb1ca 100644
--- a/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.panic-unwind.diff
@@ -24,7 +24,7 @@
           StorageLive(_4);
           StorageLive(_5);
           _5 = _1;
-          _4 = read(move _5) -> bb1;
+          _4 = read(move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff
index 4593ffaac2bd1..7496d25430977 100644
--- a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff
@@ -14,7 +14,7 @@
       }
   
       bb1: {
-          _2 = begin_panic::<&str>(const "explicit panic");
+          _2 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
       }
   
       bb2: {
diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff
index affef00bb7327..ccfa35f001b57 100644
--- a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff
@@ -15,10 +15,10 @@
           StorageLive(_2);
 -         _2 = const 2_u32 as u8 (IntToInt);
 -         _3 = CheckedAdd(_2, const 1_u8);
--         assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1;
+-         assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
 +         _2 = const 2_u8;
 +         _3 = const (3_u8, false);
-+         assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1;
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff
index 9dae4b404aad2..4f8e0f0f599b0 100644
--- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff
@@ -21,9 +21,9 @@
           StorageLive(_3);
           _3 = const 1_u8;
 -         _4 = CheckedAdd(_2, _3);
--         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1;
+-         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
 +         _4 = const (0_u8, true);
-+         assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1;
++         assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff
index e83c18735b612..5e3443228cd25 100644
--- a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = (const (), const 0_u8, const 0_u8);
-          _1 = encode(move _2) -> bb1;
+          _1 = encode(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff
index cbbc2582973a7..95776030162ec 100644
--- a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff
@@ -14,7 +14,7 @@
 +         _3 = const (1_u8, 2_u8);
           _2 = (move _3,);
           StorageDead(_3);
-          _1 = test(move _2) -> bb1;
+          _1 = test(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-unwind.diff
index be245b424c14c..658607116c87a 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.panic-unwind.diff
@@ -20,10 +20,10 @@
           _3 = const 2_usize;
 -         _4 = Len(_2);
 -         _5 = Lt(_3, _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
 +         _4 = const 5000_usize;
 +         _5 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-unwind.diff
index be245b424c14c..658607116c87a 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.panic-unwind.diff
@@ -20,10 +20,10 @@
           _3 = const 2_usize;
 -         _4 = Len(_2);
 -         _5 = Lt(_3, _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
 +         _4 = const 5000_usize;
 +         _5 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-unwind.diff
index 50006f5f5b5a1..7ba2b483dc3fb 100644
--- a/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.panic-unwind.diff
@@ -14,7 +14,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = foo() -> bb1;
+          _1 = foo() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff
index 69a0c3e2429e4..15ef0fa4dfff7 100644
--- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff
@@ -23,7 +23,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = foo() -> bb1;
+          _1 = foo() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.panic-unwind.diff
index 29cad611b5404..bbb807d8fcdc5 100644
--- a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.panic-unwind.diff
@@ -29,7 +29,7 @@
           StorageLive(_2);
 -         _2 = OffsetOf(Alpha, [0]);
 +         _2 = const 4_usize;
-          _1 = must_use::<usize>(move _2) -> bb1;
+          _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -38,7 +38,7 @@
           StorageLive(_4);
 -         _4 = OffsetOf(Alpha, [1]);
 +         _4 = const 0_usize;
-          _3 = must_use::<usize>(move _4) -> bb2;
+          _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -47,7 +47,7 @@
           StorageLive(_6);
 -         _6 = OffsetOf(Alpha, [2, 0]);
 +         _6 = const 2_usize;
-          _5 = must_use::<usize>(move _6) -> bb3;
+          _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -56,7 +56,7 @@
           StorageLive(_8);
 -         _8 = OffsetOf(Alpha, [2, 1]);
 +         _8 = const 3_usize;
-          _7 = must_use::<usize>(move _8) -> bb4;
+          _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
       }
   
       bb4: {
diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.panic-unwind.diff
index 2a58a1a5ceb45..fd5206e460c6d 100644
--- a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.panic-unwind.diff
@@ -28,7 +28,7 @@
           StorageLive(_1);
           StorageLive(_2);
           _2 = OffsetOf(Gamma<T>, [0]);
-          _1 = must_use::<usize>(move _2) -> bb1;
+          _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -36,7 +36,7 @@
           StorageLive(_3);
           StorageLive(_4);
           _4 = OffsetOf(Gamma<T>, [1]);
-          _3 = must_use::<usize>(move _4) -> bb2;
+          _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -44,7 +44,7 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = OffsetOf(Delta<T>, [1]);
-          _5 = must_use::<usize>(move _6) -> bb3;
+          _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -52,7 +52,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = OffsetOf(Delta<T>, [2]);
-          _7 = must_use::<usize>(move _8) -> bb4;
+          _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
       }
   
       bb4: {
diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-unwind.diff
index f94708605eef8..571f279a8c140 100644
--- a/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.panic-unwind.diff
@@ -22,10 +22,10 @@
           _4 = const 2_usize;
 -         _5 = Len(_3);
 -         _6 = Lt(_4, _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
 +         _5 = const 8_usize;
 +         _6 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-unwind.diff
index f94708605eef8..571f279a8c140 100644
--- a/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.panic-unwind.diff
@@ -22,10 +22,10 @@
           _4 = const 2_usize;
 -         _5 = Len(_3);
 -         _6 = Lt(_4, _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
 +         _5 = const 8_usize;
 +         _6 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff
index f89e9dd5b6356..79f85fcef110e 100644
--- a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff
@@ -7,9 +7,9 @@
   
       bb0: {
 -         _1 = CheckedAdd(const 2_u32, const 2_u32);
--         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1;
+-         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
 +         _1 = const (4_u32, false);
-+         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1;
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir
index 148f16c7ee2da..9a06469746361 100644
--- a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir
+++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir
@@ -6,7 +6,7 @@ fn add() -> u32 {
 
     bb0: {
         _1 = const (4_u32, false);
-        assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1;
+        assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-unwind.diff
index d7d6e8e435e24..a7d7a7224cea7 100644
--- a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.panic-unwind.diff
@@ -17,7 +17,7 @@
           StorageLive(_3);
 -         _3 = _1;
 +         _3 = const 1_u32;
-          _2 = consume(move _3) -> bb1;
+          _2 = consume(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff
index b07ec0ad50251..c0f290a9ab491 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff
@@ -27,10 +27,10 @@
           _6 = const 1_usize;
 -         _7 = Len((*_2));
 -         _8 = Lt(_6, _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
 +         _7 = const 3_usize;
 +         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff
index b07ec0ad50251..c0f290a9ab491 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff
@@ -27,10 +27,10 @@
           _6 = const 1_usize;
 -         _7 = Len((*_2));
 -         _8 = Lt(_6, _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
 +         _7 = const 3_usize;
 +         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-unwind.diff
index 02dca4d3dea56..1ce28e979a5b0 100644
--- a/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/switch_int.main.ConstProp.panic-unwind.diff
@@ -13,11 +13,11 @@
       }
   
       bb1: {
-          _0 = foo(const -1_i32) -> bb3;
+          _0 = foo(const -1_i32) -> [return: bb3, unwind continue];
       }
   
       bb2: {
-          _0 = foo(const 0_i32) -> bb3;
+          _0 = foo(const 0_i32) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff
index 72ce94e142950..e598a0d3df007 100644
--- a/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff
@@ -13,11 +13,11 @@
       }
   
       bb1: {
-          _0 = foo(const -1_i32) -> bb3;
+          _0 = foo(const -1_i32) -> [return: bb3, unwind continue];
       }
   
       bb2: {
-          _0 = foo(const 0_i32) -> bb3;
+          _0 = foo(const 0_i32) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff
index d44c69ca44038..6255f9ec59622 100644
--- a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff
@@ -18,7 +18,7 @@
           StorageLive(_3);
 -         _3 = _1;
 +         _3 = const (1_u32, 2_u32);
-          _2 = consume(move _3) -> bb1;
+          _2 = consume(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-unwind.diff
index 074f827024189..b702e3b7d1ed7 100644
--- a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.panic-unwind.diff
@@ -13,11 +13,11 @@
           _2 = &_1;
           _3 = _1;
           _4 = &_3;
-          _0 = cmp_ref(_2, _4) -> bb1;
+          _0 = cmp_ref(_2, _4) -> [return: bb1, unwind continue];
       }
   
       bb1: {
-          _0 = opaque::<u8>(_3) -> bb2;
+          _0 = opaque::<u8>(_3) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-unwind.diff
index 0dcc5cef7340a..2f92d8818cff3 100644
--- a/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/branch.foo.CopyProp.panic-unwind.diff
@@ -16,13 +16,13 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = val() -> bb1;
+          _1 = val() -> [return: bb1, unwind continue];
       }
   
       bb1: {
           StorageLive(_2);
           StorageLive(_3);
-          _3 = cond() -> bb2;
+          _3 = cond() -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -36,7 +36,7 @@
   
       bb4: {
           StorageLive(_4);
-          _4 = val() -> bb5;
+          _4 = val() -> [return: bb5, unwind continue];
       }
   
       bb5: {
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-unwind.diff
index 95c1c12ee6920..ef9c343a264d8 100644
--- a/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.panic-unwind.diff
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = _1;
-          _2 = dummy(move _3) -> bb1;
+          _2 = dummy(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-unwind.diff
index e16d6220ef2c6..769089e16f34c 100644
--- a/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.panic-unwind.diff
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = _1;
-          _2 = dummy(move _3) -> bb1;
+          _2 = dummy(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-unwind.diff
index 2d7e34f2d6e3c..eb40183c1c954 100644
--- a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.panic-unwind.diff
@@ -8,14 +8,14 @@
   
       bb0: {
 -         _2 = _1;
--         _0 = opaque::<NotCopy>(move _1) -> bb1;
-+         _0 = opaque::<NotCopy>(_1) -> bb1;
+-         _0 = opaque::<NotCopy>(move _1) -> [return: bb1, unwind continue];
++         _0 = opaque::<NotCopy>(_1) -> [return: bb1, unwind continue];
       }
   
       bb1: {
 -         _3 = move _2;
--         _0 = opaque::<NotCopy>(_3) -> bb2;
-+         _0 = opaque::<NotCopy>(_1) -> bb2;
+-         _0 = opaque::<NotCopy>(_3) -> [return: bb2, unwind continue];
++         _0 = opaque::<NotCopy>(_1) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-unwind.diff
index bf9e941c7b653..e343b78924ab1 100644
--- a/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/cycle.main.CopyProp.panic-unwind.diff
@@ -22,7 +22,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = val() -> bb1;
+          _1 = val() -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -38,7 +38,7 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = _1;
-          _5 = std::mem::drop::<i32>(move _6) -> bb2;
+          _5 = std::mem::drop::<i32>(move _6) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-unwind.mir b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-unwind.mir
index 617e57d884bfa..f8c285ff3843b 100644
--- a/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-unwind.mir
+++ b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.panic-unwind.mir
@@ -16,7 +16,7 @@ fn f(_1: usize) -> usize {
         _1 = _2;
         StorageLive(_4);
         _4 = _1;
-        _0 = id::<usize>(move _4) -> bb1;
+        _0 = id::<usize>(move _4) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir
index 617e57d884bfa..f8c285ff3843b 100644
--- a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir
+++ b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir
@@ -16,7 +16,7 @@ fn f(_1: usize) -> usize {
         _1 = _2;
         StorageLive(_4);
         _4 = _1;
-        _0 = id::<usize>(move _4) -> bb1;
+        _0 = id::<usize>(move _4) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
index 69f399bf1fa19..c2d892be35dc8 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
@@ -49,14 +49,14 @@
           _7 = &_2;
           _6 = move _7 as &[i32] (Pointer(Unsize));
           StorageDead(_7);
-          _5 = core::slice::<impl [i32]>::len(move _6) -> bb1;
+          _5 = core::slice::<impl [i32]>::len(move _6) -> [return: bb1, unwind continue];
       }
   
       bb1: {
           StorageDead(_6);
           _4 = std::ops::Range::<usize> { start: const 0_usize, end: move _5 };
           StorageDead(_5);
-          _3 = <std::ops::Range<usize> as IntoIterator>::into_iter(move _4) -> bb2;
+          _3 = <std::ops::Range<usize> as IntoIterator>::into_iter(move _4) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -73,7 +73,7 @@
           StorageLive(_13);
           _13 = &mut _8;
           _12 = &mut (*_13);
-          _11 = <std::ops::Range<usize> as Iterator>::next(move _12) -> bb4;
+          _11 = <std::ops::Range<usize> as Iterator>::next(move _12) -> [return: bb4, unwind continue];
       }
   
       bb4: {
@@ -90,9 +90,9 @@
 -         _18 = _16;
           _19 = Len(_2);
 -         _20 = Lt(_18, _19);
--         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _18) -> bb8;
+-         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _18) -> [success: bb8, unwind continue];
 +         _20 = Lt(_16, _19);
-+         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> bb8;
++         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> [success: bb8, unwind continue];
       }
   
       bb6: {
diff --git a/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-unwind.diff
index cbbf6686b0492..0c6a3c6d5c954 100644
--- a/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.panic-unwind.diff
@@ -21,8 +21,8 @@
 -         _4 = _1;
 -         StorageLive(_5);
 -         _5 = _2;
--         _3 = g::<T>(move _4, move _5) -> bb1;
-+         _3 = g::<T>(_1, _1) -> bb1;
+-         _3 = g::<T>(move _4, move _5) -> [return: bb1, unwind continue];
++         _3 = g::<T>(_1, _1) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-unwind.diff
index 3ebee0ed80d42..ad3889639e0cf 100644
--- a/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/move_projection.f.CopyProp.panic-unwind.diff
@@ -9,13 +9,13 @@
       bb0: {
 -         _2 = _1;
 -         _3 = move (_2.0: u8);
--         _0 = opaque::<Foo>(move _1) -> bb1;
+-         _0 = opaque::<Foo>(move _1) -> [return: bb1, unwind continue];
 +         _3 = (_1.0: u8);
-+         _0 = opaque::<Foo>(_1) -> bb1;
++         _0 = opaque::<Foo>(_1) -> [return: bb1, unwind continue];
       }
   
       bb1: {
-          _0 = opaque::<u8>(move _3) -> bb2;
+          _0 = opaque::<u8>(move _3) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
index 0f14b53e9ade7..66a0f49cfb9d8 100644
--- a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
@@ -36,8 +36,8 @@
           StorageLive(_6);
 -         StorageLive(_7);
 -         _7 = _5;
--         _6 = opaque::<*mut u8>(move _7) -> bb1;
-+         _6 = opaque::<*mut u8>(_2) -> bb1;
+-         _6 = opaque::<*mut u8>(move _7) -> [return: bb1, unwind continue];
++         _6 = opaque::<*mut u8>(_2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
index ba6e09fa95c6f..f5a512b899551 100644
--- a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
@@ -32,8 +32,8 @@
           StorageLive(_5);
 -         StorageLive(_6);
 -         _6 = _4;
--         _5 = opaque::<*mut u8>(move _6) -> bb1;
-+         _5 = opaque::<*mut u8>(_2) -> bb1;
+-         _5 = opaque::<*mut u8>(move _6) -> [return: bb1, unwind continue];
++         _5 = opaque::<*mut u8>(_2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff
index 4379aa06385e9..67763fdce6676 100644
--- a/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff
@@ -30,8 +30,8 @@
           StorageLive(_5);
 -         StorageLive(_6);
 -         _6 = move _4;
--         _5 = opaque::<&mut u8>(move _6) -> bb1;
-+         _5 = opaque::<&mut u8>(move _2) -> bb1;
+-         _5 = opaque::<&mut u8>(move _6) -> [return: bb1, unwind continue];
++         _5 = opaque::<&mut u8>(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-unwind.diff
index 53332f8161eae..becc425632104 100644
--- a/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-unwind.diff
@@ -30,8 +30,8 @@
           StorageLive(_5);
 -         StorageLive(_6);
 -         _6 = move _4;
--         _5 = opaque::<&mut u8>(move _6) -> bb1;
-+         _5 = opaque::<&mut u8>(move _2) -> bb1;
+-         _5 = opaque::<&mut u8>(move _6) -> [return: bb1, unwind continue];
++         _5 = opaque::<&mut u8>(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff
index 784841eacbfad..0d8a9aca3d8c5 100644
--- a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff
@@ -41,10 +41,10 @@
           StorageLive(_5);
 -         _5 = _2;
 -         _6 = CheckedAdd(_4, _5);
--         assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> bb1;
+-         assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind continue];
 +         _5 = const 2_i32;
 +         _6 = CheckedAdd(const 1_i32, const 2_i32);
-+         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> bb1;
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -58,10 +58,10 @@
           StorageLive(_9);
 -         _9 = _7;
 -         _10 = CheckedAdd(_9, const 1_i32);
--         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2;
+-         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> [success: bb2, unwind continue];
 +         _9 = const i32::MAX;
 +         _10 = CheckedAdd(const i32::MAX, const 1_i32);
-+         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2;
++         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff
index d79a2da1ddb78..c1d281ab788f0 100644
--- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff
@@ -21,9 +21,9 @@
           StorageLive(_3);
           _3 = const 1_u8;
 -         _4 = CheckedAdd(_2, _3);
--         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1;
+-         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
 +         _4 = CheckedAdd(const u8::MAX, const 1_u8);
-+         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1;
++         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff
index 83d2f78323e76..4e1d26acfa3fc 100644
--- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff
@@ -24,7 +24,7 @@
           StorageLive(_4);
           _4 = &_1;
           _3 = &(*_4);
-          _2 = escape::<i32>(move _3) -> bb1;
+          _2 = escape::<i32>(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -33,7 +33,7 @@
           StorageDead(_2);
           _1 = const 1_i32;
           StorageLive(_5);
-          _5 = some_function() -> bb2;
+          _5 = some_function() -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
index 927ca0124bbce..ebeb8619d7300 100644
--- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
@@ -30,7 +30,7 @@
           StorageLive(_4);
           StorageLive(_5);
           _5 = _3;
-          _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1;
+          _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-unwind.diff
index f9723a0498304..395620fec524a 100644
--- a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.panic-unwind.diff
@@ -22,8 +22,8 @@
 +         _4 = const 1_i32;
 +         _3 = const 2_i32;
           StorageDead(_4);
--         _2 = foo(move _3) -> bb1;
-+         _2 = foo(const 2_i32) -> bb1;
+-         _2 = foo(move _3) -> [return: bb1, unwind continue];
++         _2 = foo(const 2_i32) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff
index 80a4dd371839c..4b922e05e105b 100644
--- a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff
+++ b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff
@@ -28,9 +28,9 @@
   
       bb1: {
 -         StorageLive(_5);
--         _5 = cond() -> bb2;
+-         _5 = cond() -> [return: bb2, unwind continue];
 +         StorageLive(_4);
-+         _4 = cond() -> bb2;
++         _4 = cond() -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
index 66396d28e704e..3d9aa829052dd 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
@@ -17,7 +17,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
-          _2 = core::str::<impl str>::as_bytes(move _3) -> bb1;
+          _2 = core::str::<impl str>::as_bytes(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff
index 62085341d378c..da4cc188cfa6f 100644
--- a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff
+++ b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff
@@ -30,7 +30,7 @@
           StorageLive(_2);
           _14 = const _;
           _2 = &(*_14);
-          _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> bb1;
+          _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -47,7 +47,7 @@
           StorageLive(_9);
           _9 = &mut _4;
           _8 = &mut (*_9);
-          _7 = <std::slice::Iter<'_, i32> as Iterator>::next(move _8) -> bb3;
+          _7 = <std::slice::Iter<'_, i32> as Iterator>::next(move _8) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -63,7 +63,7 @@
 +         _12 = (*_15);
           StorageLive(_13);
           _13 = _12;
-          _6 = std::mem::drop::<i32>(move _13) -> bb7;
+          _6 = std::mem::drop::<i32>(move _13) -> [return: bb7, unwind continue];
       }
   
       bb5: {
diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff
index 50683837097ac..2ada087b4bd6e 100644
--- a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff
+++ b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_1);
           StorageLive(_2);
-          _2 = f() -> bb1;
+          _2 = f() -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -18,7 +18,7 @@
   
       bb2: {
           StorageDead(_2);
-          drop(_1) -> bb3;
+          drop(_1) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff
index 59168eda2f3e7..19b26c901cbfc 100644
--- a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff
+++ b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff
@@ -30,12 +30,12 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = foo() -> bb1;
+          _1 = foo() -> [return: bb1, unwind continue];
       }
   
       bb1: {
           StorageLive(_2);
-          _2 = foo() -> bb2;
+          _2 = foo() -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-unwind.diff
index e0734f47de2a0..759c1cabf45e7 100644
--- a/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.panic-unwind.diff
@@ -18,16 +18,16 @@
   
       bb0: {
 -         StorageLive(_1);
--         _1 = val() -> bb1;
+-         _1 = val() -> [return: bb1, unwind continue];
 +         nop;
-+         _0 = val() -> bb1;
++         _0 = val() -> [return: bb1, unwind continue];
       }
   
       bb1: {
 -         StorageLive(_2);
 +         nop;
           StorageLive(_3);
-          _3 = cond() -> bb2;
+          _3 = cond() -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -42,7 +42,7 @@
   
       bb4: {
           StorageLive(_4);
-          _4 = val() -> bb5;
+          _4 = val() -> [return: bb5, unwind continue];
       }
   
       bb5: {
diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-unwind.diff
index b181066df0470..8b2835c8ced2a 100644
--- a/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.panic-unwind.diff
@@ -11,10 +11,10 @@
           StorageLive(_2);
 -         StorageLive(_3);
 -         _3 = _1;
--         _2 = dummy(move _3) -> bb1;
+-         _2 = dummy(move _3) -> [return: bb1, unwind continue];
 +         nop;
 +         nop;
-+         _2 = dummy(move _1) -> bb1;
++         _2 = dummy(move _1) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff
index f19728669368e..b4c8a89278b9b 100644
--- a/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff
@@ -12,8 +12,8 @@
 +         nop;
           StorageLive(_3);
           _3 = _1;
--         _2 = dummy(move _3) -> bb1;
-+         _1 = dummy(move _3) -> bb1;
+-         _2 = dummy(move _3) -> [return: bb1, unwind continue];
++         _1 = dummy(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-unwind.diff
index 0dc7de31cc47b..6f6e01d37b1a6 100644
--- a/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.panic-unwind.diff
@@ -24,9 +24,9 @@
   
       bb0: {
 -         StorageLive(_1);
--         _1 = val() -> bb1;
+-         _1 = val() -> [return: bb1, unwind continue];
 +         nop;
-+         _6 = val() -> bb1;
++         _6 = val() -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -51,7 +51,7 @@
 -         _6 = _1;
 +         nop;
 +         nop;
-          _5 = std::mem::drop::<i32>(move _6) -> bb2;
+          _5 = std::mem::drop::<i32>(move _6) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-unwind.mir b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-unwind.mir
index bf515d328aef8..9147de2ec473b 100644
--- a/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-unwind.mir
+++ b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.panic-unwind.mir
@@ -20,7 +20,7 @@ fn f(_1: usize) -> usize {
         nop;
         nop;
         nop;
-        _0 = id::<usize>(move _1) -> bb1;
+        _0 = id::<usize>(move _1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir
index 038bd4b6da9d4..185feb4b41816 100644
--- a/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir
+++ b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir
@@ -19,7 +19,7 @@ fn f(_1: usize) -> usize {
         nop;
         nop;
         nop;
-        _0 = id::<usize>(move _1) -> bb1;
+        _0 = id::<usize>(move _1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff
index 4e32823c1ee91..9c3cbef38d698 100644
--- a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff
@@ -25,8 +25,8 @@
           StorageLive(_6);
           _6 = &mut _2;
           _5 = &mut (*_6);
--         _3 = move _4(move _5) -> bb1;
-+         _3 = move _1(move _5) -> bb1;
+-         _3 = move _4(move _5) -> [return: bb1, unwind continue];
++         _3 = move _1(move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
index 8d1297d029963..d2eef90582d54 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
@@ -18,7 +18,7 @@
       bb0: {
           StorageLive(_1);
           StorageLive(_2);
-          _2 = val() -> bb1;
+          _2 = val() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-unwind.diff
index e46a318f51ab7..7f730a77b06ab 100644
--- a/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.panic-unwind.diff
@@ -34,7 +34,7 @@
 -         _5 = _1;
 -         StorageLive(_6);
 -         _6 = _2;
--         _4 = g::<T>(move _5, move _6) -> bb2;
+-         _4 = g::<T>(move _5, move _6) -> [return: bb2, unwind continue];
 -     }
 - 
 -     bb2: {
@@ -53,9 +53,9 @@
 +         nop;
           StorageLive(_9);
 -         _9 = _2;
--         _7 = g::<T>(move _8, move _9) -> bb4;
+-         _7 = g::<T>(move _8, move _9) -> [return: bb4, unwind continue];
 +         _9 = _1;
-+         _7 = g::<T>(move _1, move _9) -> bb2;
++         _7 = g::<T>(move _1, move _9) -> [return: bb2, unwind continue];
       }
   
 -     bb4: {
diff --git a/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
index 4fe11435fab96..b15a634256f64 100644
--- a/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
@@ -4,7 +4,7 @@ fn std::ops::Fn::call(_1: *const fn(), _2: ()) -> <fn() as FnOnce<()>>::Output {
     let mut _0: <fn() as std::ops::FnOnce<()>>::Output;
 
     bb0: {
-        _0 = move (*_1)() -> bb1;
+        _0 = move (*_1)() -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff
index 513ff03c4261a..8a3dcfab44bd2 100644
--- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff
@@ -38,7 +38,7 @@
           StorageLive(_4);
           StorageLive(_5);
           _5 = &(*_1);
-          _4 = Formatter::<'_>::sign_plus(move _5) -> bb1;
+          _4 = Formatter::<'_>::sign_plus(move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -63,7 +63,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = &(*_1);
-          _7 = Formatter::<'_>::precision(move _8) -> bb5;
+          _7 = Formatter::<'_>::precision(move _8) -> [return: bb5, unwind continue];
       }
   
       bb5: {
@@ -81,7 +81,7 @@
           _15 = _10 as u32 (IntToInt);
           _14 = Add(move _15, const 1_u32);
           StorageDead(_15);
-          _0 = float_to_exponential_common_exact::<T>(_1, _2, move _13, move _14, _3) -> bb7;
+          _0 = float_to_exponential_common_exact::<T>(_1, _2, move _13, move _14, _3) -> [return: bb7, unwind continue];
       }
   
       bb7: {
@@ -93,7 +93,7 @@
       bb8: {
           StorageLive(_20);
           _20 = _6;
-          _0 = float_to_exponential_common_shortest::<T>(_1, _2, move _20, _3) -> bb9;
+          _0 = float_to_exponential_common_shortest::<T>(_1, _2, move _20, _3) -> [return: bb9, unwind continue];
       }
   
       bb9: {
diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
index af67723d9371c..684211b53b337 100644
--- a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
@@ -15,7 +15,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = foo() -> bb1;
+-         _1 = foo() -> [return: bb1, unwind continue];
 +         StorageLive(_2);
 +         asm!("", options(MAY_UNWIND)) -> [return: bb2, unwind: bb3];
       }
@@ -28,7 +28,7 @@
 +     }
 + 
 +     bb2: {
-+         drop(_2) -> bb1;
++         drop(_2) -> [return: bb1, unwind continue];
 +     }
 + 
 +     bb3 (cleanup): {
diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.panic-unwind.diff b/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.panic-unwind.diff
index 67f16833435de..d4427b2a8076e 100644
--- a/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.panic-unwind.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = bar::<T>() -> bb1;
+          _1 = bar::<T>() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
index 2bdb942379ca6..3ce8d9acf3681 100644
--- a/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
@@ -16,7 +16,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = f::<fn() {main}>(main) -> bb1;
+-         _1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
 +         StorageLive(_2);
 +         _2 = main;
 +         StorageLive(_4);
@@ -46,7 +46,7 @@
 +     bb4: {
 +         StorageDead(_5);
 +         StorageDead(_3);
-+         drop(_2) -> bb1;
++         drop(_2) -> [return: bb1, unwind continue];
       }
   }
   
diff --git a/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
index c4f97d75308fb..198a232261840 100644
--- a/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
@@ -24,7 +24,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = f::<fn() {g}>(g) -> bb1;
+-         _1 = f::<fn() {g}>(g) -> [return: bb1, unwind continue];
 +         StorageLive(_2);
 +         _2 = g;
 +         StorageLive(_4);
@@ -56,7 +56,7 @@
 +         StorageDead(_6);
 +         StorageDead(_5);
 +         StorageDead(_3);
-+         drop(_2) -> bb1;
++         drop(_2) -> [return: bb1, unwind continue];
       }
   }
   
diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff
index ca772cf438397..941ba24605cd5 100644
--- a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff
@@ -22,17 +22,17 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
-          _2 = <Q as Query>::cache::<T>(move _3) -> bb1;
+          _2 = <Q as Query>::cache::<T>(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
           StorageDead(_3);
           StorageLive(_4);
           _4 = &(*_2);
--         _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2;
+-         _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind continue];
 +         StorageLive(_5);
 +         _5 = _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize));
-+         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(_5) -> bb2;
++         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(_5) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-unwind.diff
index 12b539fc250c6..7b1cf895a8737 100644
--- a/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.panic-unwind.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = &(*_1);
-          _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> bb1;
+          _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff
index 9bcd73e1c8ba5..5e30da400d294 100644
--- a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff
@@ -16,8 +16,8 @@
           _3 = &(*_1);
           _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize));
           StorageDead(_3);
--         _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1;
-+         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(_2) -> bb1;
+-         _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind continue];
++         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(_2) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff
index b87e164e471a1..0a4ce40c529d9 100644
--- a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff
@@ -37,7 +37,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = <() as G>::call() -> bb1;
+-         _1 = <() as G>::call() -> [return: bb1, unwind continue];
 +         StorageLive(_2);
 +         StorageLive(_3);
 +         StorageLive(_4);
@@ -56,7 +56,7 @@
 +         StorageLive(_17);
 +         StorageLive(_18);
 +         StorageLive(_19);
-+         _17 = <() as A>::call() -> bb12;
++         _17 = <() as A>::call() -> [return: bb12, unwind continue];
       }
   
       bb1: {
@@ -72,63 +72,63 @@
 +         StorageDead(_7);
 +         StorageDead(_6);
 +         StorageDead(_5);
-+         _3 = <() as F>::call() -> bb3;
++         _3 = <() as F>::call() -> [return: bb3, unwind continue];
 +     }
 + 
 +     bb3: {
-+         _4 = <() as F>::call() -> bb1;
++         _4 = <() as F>::call() -> [return: bb1, unwind continue];
 +     }
 + 
 +     bb4: {
 +         StorageDead(_10);
 +         StorageDead(_9);
 +         StorageDead(_8);
-+         _6 = <() as E>::call() -> bb5;
++         _6 = <() as E>::call() -> [return: bb5, unwind continue];
 +     }
 + 
 +     bb5: {
-+         _7 = <() as E>::call() -> bb2;
++         _7 = <() as E>::call() -> [return: bb2, unwind continue];
 +     }
 + 
 +     bb6: {
 +         StorageDead(_13);
 +         StorageDead(_12);
 +         StorageDead(_11);
-+         _9 = <() as D>::call() -> bb7;
++         _9 = <() as D>::call() -> [return: bb7, unwind continue];
 +     }
 + 
 +     bb7: {
-+         _10 = <() as D>::call() -> bb4;
++         _10 = <() as D>::call() -> [return: bb4, unwind continue];
 +     }
 + 
 +     bb8: {
 +         StorageDead(_16);
 +         StorageDead(_15);
 +         StorageDead(_14);
-+         _12 = <() as C>::call() -> bb9;
++         _12 = <() as C>::call() -> [return: bb9, unwind continue];
 +     }
 + 
 +     bb9: {
-+         _13 = <() as C>::call() -> bb6;
++         _13 = <() as C>::call() -> [return: bb6, unwind continue];
 +     }
 + 
 +     bb10: {
 +         StorageDead(_19);
 +         StorageDead(_18);
 +         StorageDead(_17);
-+         _15 = <() as B>::call() -> bb11;
++         _15 = <() as B>::call() -> [return: bb11, unwind continue];
 +     }
 + 
 +     bb11: {
-+         _16 = <() as B>::call() -> bb8;
++         _16 = <() as B>::call() -> [return: bb8, unwind continue];
 +     }
 + 
 +     bb12: {
-+         _18 = <() as A>::call() -> bb13;
++         _18 = <() as A>::call() -> [return: bb13, unwind continue];
 +     }
 + 
 +     bb13: {
-+         _19 = <() as A>::call() -> bb10;
++         _19 = <() as A>::call() -> [return: bb10, unwind continue];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff
index 10e0f0efcbcfd..eba5ad9cf2694 100644
--- a/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.panic-unwind.diff
@@ -9,7 +9,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = no_sanitize() -> bb1;
+-         _1 = no_sanitize() -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff
index b854e93d9b794..24457819b2c10 100644
--- a/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.panic-unwind.diff
@@ -9,7 +9,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = target_feature() -> bb1;
+-         _1 = target_feature() -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff
index d9e7177e6278c..364acab6d9361 100644
--- a/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.panic-unwind.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1;
+          _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff
index 7d9b1d847b021..965b7ddca3201 100644
--- a/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.panic-unwind.diff
@@ -7,7 +7,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = no_sanitize() -> bb1;
+          _1 = no_sanitize() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff
index 5bee586528380..bcdbd6e33140f 100644
--- a/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.panic-unwind.diff
@@ -7,7 +7,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = target_feature() -> bb1;
+          _1 = target_feature() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_cycle.one.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle.one.Inline.panic-unwind.diff
index 66d25162cb1b8..75ac40bea61fb 100644
--- a/tests/mir-opt/inline/inline_cycle.one.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle.one.Inline.panic-unwind.diff
@@ -13,7 +13,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = <C as Call>::call() -> bb1;
+          _1 = <C as Call>::call() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
index d3bd412d95328..a08662959dd8e 100644
--- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
@@ -23,14 +23,14 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = call::<fn() {f}>(f) -> bb1;
+-         _1 = call::<fn() {f}>(f) -> [return: bb1, unwind continue];
 +         StorageLive(_2);
 +         _2 = f;
 +         StorageLive(_3);
 +         StorageLive(_4);
 +         _4 = const ();
 +         StorageLive(_5);
-+         _5 = f() -> bb1;
++         _5 = f() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
index 2a4002f0499c3..8314526ee0431 100644
--- a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
@@ -13,8 +13,8 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = <C as Call>::call() -> bb1;
-+         _1 = <B<C> as Call>::call() -> bb1;
+-         _1 = <C as Call>::call() -> [return: bb1, unwind continue];
++         _1 = <B<C> as Call>::call() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_diverging.f.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.f.Inline.panic-unwind.diff
index 76bb3356f50f5..b799189925347 100644
--- a/tests/mir-opt/inline/inline_diverging.f.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.f.Inline.panic-unwind.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_2);
--         _2 = sleep();
+-         _2 = sleep() -> unwind continue;
 +         goto -> bb1;
 +     }
 + 
diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff
index d65efa43a7b1d..5663b4624001a 100644
--- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff
@@ -33,9 +33,9 @@
   
       bb2: {
           StorageLive(_6);
--         _6 = panic();
+-         _6 = panic() -> unwind continue;
 +         StorageLive(_7);
-+         _7 = begin_panic::<&str>(const "explicit panic");
++         _7 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
index f7e0e1c55f8bf..dfc12db12a888 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
@@ -27,7 +27,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = call_twice::<!, fn() -> ! {sleep}>(sleep);
+-         _1 = call_twice::<!, fn() -> ! {sleep}>(sleep) -> unwind continue;
 +         StorageLive(_2);
 +         _2 = sleep;
 +         StorageLive(_6);
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
index 588f04048d67d..fedcf04231d7b 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
@@ -35,7 +35,7 @@
           StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
--         _4 = g() -> bb1;
+-         _4 = g() -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
index 4615a3f98267b..0b643b3c7a921 100644
--- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
@@ -117,7 +117,7 @@
       bb0: {
           StorageLive(_1);
           StorageLive(_2);
--         _2 = Vec::<u32>::new() -> bb1;
+-         _2 = Vec::<u32>::new() -> [return: bb1, unwind continue];
 +         StorageLive(_3);
 +         _3 = const _;
 +         _2 = Vec::<u32> { buf: move _3, len: const 0_usize };
diff --git a/tests/mir-opt/inline/inline_options.main.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_options.main.Inline.after.panic-unwind.mir
index d006c73f95420..df0cab513eca7 100644
--- a/tests/mir-opt/inline/inline_options.main.Inline.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/inline_options.main.Inline.after.panic-unwind.mir
@@ -12,7 +12,7 @@ fn main() -> () {
 
     bb0: {
         StorageLive(_1);
-        _1 = not_inlined() -> bb1;
+        _1 = not_inlined() -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -21,7 +21,7 @@ fn main() -> () {
         StorageLive(_3);
         StorageLive(_4);
         StorageLive(_5);
-        _3 = g() -> bb3;
+        _3 = g() -> [return: bb3, unwind continue];
     }
 
     bb2: {
@@ -34,10 +34,10 @@ fn main() -> () {
     }
 
     bb3: {
-        _4 = g() -> bb4;
+        _4 = g() -> [return: bb4, unwind continue];
     }
 
     bb4: {
-        _5 = g() -> bb2;
+        _5 = g() -> [return: bb2, unwind continue];
     }
 }
diff --git a/tests/mir-opt/inline/inline_shims.clone.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_shims.clone.Inline.panic-unwind.diff
index 9897ed78edff0..00e92a0f5e5af 100644
--- a/tests/mir-opt/inline/inline_shims.clone.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_shims.clone.Inline.panic-unwind.diff
@@ -11,7 +11,7 @@
       bb0: {
           StorageLive(_2);
           _2 = &_1;
--         _0 = <fn(A, B) as Clone>::clone(move _2) -> bb1;
+-         _0 = <fn(A, B) as Clone>::clone(move _2) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
index 1d24756e1d22c..4270ae00b668e 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
@@ -21,7 +21,7 @@
           StorageLive(_3);
           StorageLive(_4);
           _4 = _1;
-          _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> bb1;
+          _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -29,7 +29,7 @@
           StorageDead(_3);
           StorageLive(_5);
           _5 = _2;
--         _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> bb2;
+-         _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind continue];
 +         StorageLive(_6);
 +         StorageLive(_7);
 +         _6 = discriminant((*_5));
@@ -44,7 +44,7 @@
 +     }
 + 
 +     bb3: {
-+         drop((((*_5) as Some).0: B)) -> bb2;
++         drop((((*_5) as Some).0: B)) -> [return: bb2, unwind continue];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_specialization.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_specialization.main.Inline.panic-unwind.diff
index 0f7b1909f8dd2..bc841101df739 100644
--- a/tests/mir-opt/inline/inline_specialization.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_specialization.main.Inline.panic-unwind.diff
@@ -12,7 +12,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = <Vec<()> as Foo>::bar() -> bb1;
+-         _1 = <Vec<()> as Foo>::bar() -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-unwind.mir
index 9550fdea1920f..da18a5adc376b 100644
--- a/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.panic-unwind.mir
@@ -8,7 +8,7 @@ fn test(_1: &dyn X) -> u32 {
     bb0: {
         StorageLive(_2);
         _2 = &(*_1);
-        _0 = <dyn X as X>::y(move _2) -> bb1;
+        _0 = <dyn X as X>::y(move _2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir
index ffc16bfe6709a..5d4979680a48b 100644
--- a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir
@@ -15,7 +15,7 @@ fn test2(_1: &dyn X) -> bool {
         _3 = &(*_1);
         _2 = move _3 as &dyn X (Pointer(Unsize));
         StorageDead(_3);
-        _0 = <dyn X as X>::y(_2) -> bb1;
+        _0 = <dyn X as X>::y(_2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff
index 1e407f07d0969..16a19f4a3569a 100644
--- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff
@@ -16,16 +16,16 @@
 +     }
   
       bb0: {
--         _0 = inner() -> bb1;
+-         _0 = inner() -> [return: bb1, unwind continue];
 +         StorageLive(_1);
 +         _1 = const _;
-+         _0 = index() -> bb1;
++         _0 = index() -> [return: bb1, unwind continue];
       }
   
       bb1: {
 +         StorageLive(_3);
 +         _2 = Lt(_0, const 1_usize);
-+         assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, _0) -> bb2;
++         assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, _0) -> [success: bb2, unwind continue];
 +     }
 + 
 +     bb2: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_bigger.Inline.panic-unwind.diff
index 577fc8bee66fa..d71b5c4a626ef 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_bigger.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_bigger.Inline.panic-unwind.diff
@@ -20,7 +20,7 @@
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl u64>::unchecked_shl(move _3, move _4) -> bb1;
+-         _0 = core::num::<impl u64>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
index ba159c063b3b0..cae25759cd8eb 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
@@ -22,7 +22,7 @@
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> bb1;
+-         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
index d7ff104b92e9a..6aafb61dc557d 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
@@ -20,7 +20,7 @@
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> bb1;
+-         _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff
index 3d398e00fc890..fe53312148666 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff
@@ -22,7 +22,7 @@
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> bb1;
+-         _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff b/tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff
index fbfb8f1fd4e6b..a6bd29e1c9d15 100644
--- a/tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff
@@ -45,10 +45,10 @@
           StorageLive(_8);
 -         _10 = const 8_i32 as u32 (IntToInt);
 -         _11 = Lt(move _10, const 32_u32);
--         assert(move _11, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1;
+-         assert(move _11, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> [success: bb1, unwind continue];
 +         _10 = const 8_u32;
 +         _11 = const true;
-+         assert(const true, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1;
++         assert(const true, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -57,10 +57,10 @@
           StorageDead(_8);
 -         _12 = const 1_i32 as u32 (IntToInt);
 -         _13 = Lt(move _12, const 32_u32);
--         assert(move _13, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2;
+-         assert(move _13, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> [success: bb2, unwind continue];
 +         _12 = const 1_u32;
 +         _13 = const true;
-+         assert(const true, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2;
++         assert(const true, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
index 8ffd46311dc55..1851747f0a623 100644
--- a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
+++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
@@ -11,6 +11,6 @@ fn main() -> () {
         StorageLive(_1);
         StorageLive(_2);
         _2 = ();
-        _1 = const_eval_select::<(), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}, !>(move _2, ow_ct, ow_ct);
+        _1 = const_eval_select::<(), fn() -> ! {ow_ct}, fn() -> ! {ow_ct}, !>(move _2, ow_ct, ow_ct) -> unwind continue;
     }
 }
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff
index b33d8fc52b401..254658c810dbb 100644
--- a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff
@@ -58,7 +58,7 @@
   
       bb5: {
           StorageDead(_2);
--         drop(_1) -> bb6;
+-         drop(_1) -> [return: bb6, unwind continue];
 +         goto -> bb6;
       }
   
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
index 04071c72555e8..4ef3650cdea3a 100644
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
@@ -85,7 +85,7 @@
   
       bb9: {
           StorageDead(_2);
--         drop(_1) -> bb10;
+-         drop(_1) -> [return: bb10, unwind continue];
 +         goto -> bb19;
       }
   
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
index 4bbfe47299c86..7ecdc428e59e7 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
@@ -31,7 +31,7 @@ fn test() -> Option<Box<u32>> {
         StorageLive(_1);
         _2 = SizeOf(u32);
         _3 = AlignOf(u32);
-        _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1;
+        _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -73,13 +73,13 @@ fn test() -> Option<Box<u32>> {
     bb6: {
         StorageDead(_11);
         StorageDead(_9);
-        drop(_5) -> bb9;
+        drop(_5) -> [return: bb9, unwind continue];
     }
 
     bb7: {
         StorageDead(_5);
         _0 = Option::<Box<u32>>::Some(move _1);
-        drop(_1) -> bb8;
+        drop(_1) -> [return: bb8, unwind continue];
     }
 
     bb8: {
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
index 761673ca546bc..25df839c2db9d 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
@@ -42,7 +42,7 @@
       }
   
       bb1: {
-          _15 = core::panicking::panic(const "internal error: entered unreachable code");
+          _15 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue;
       }
   
       bb2: {
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
index e7c1be7e6e653..43a1a1eed20da 100644
--- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
@@ -26,7 +26,7 @@ fn num_to_digit(_1: char) -> u32 {
     bb0: {
         StorageLive(_3);
         StorageLive(_2);
-        _2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> bb1;
+        _2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -39,7 +39,7 @@ fn num_to_digit(_1: char) -> u32 {
 
     bb2: {
         StorageLive(_5);
-        _5 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> bb3;
+        _5 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb3, unwind continue];
     }
 
     bb3: {
@@ -48,7 +48,7 @@ fn num_to_digit(_1: char) -> u32 {
     }
 
     bb4: {
-        _7 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value");
+        _7 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value") -> unwind continue;
     }
 
     bb5: {
diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
index 35a1e51a3ac94..1cba0f27afaab 100644
--- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
@@ -42,7 +42,7 @@
           _8 = _1;
           _9 = Len((*_2));
           _10 = Lt(_8, _9);
-          assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3;
+          assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
index 3c6f373462464..6c450067cc4a3 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
@@ -45,7 +45,7 @@
           _8 = _1;
           _9 = Len((*_2));
           _10 = Lt(_8, _9);
-          assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3;
+          assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue];
       }
   
       bb3: {
@@ -59,7 +59,7 @@
           _11 = const 0_usize;
           _12 = Len((*_2));
           _13 = Lt(_11, _12);
-          assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb5;
+          assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue];
       }
   
       bb5: {
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
index d90f3dddf58ee..310b3b26ac563 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
@@ -20,7 +20,7 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = &(*_2);
--         _5 = core::slice::<impl [u8]>::len(move _6) -> bb1;
+-         _5 = core::slice::<impl [u8]>::len(move _6) -> [return: bb1, unwind continue];
 +         _5 = Len((*_6));
 +         goto -> bb1;
       }
@@ -38,7 +38,7 @@
           _7 = _1;
           _8 = Len((*_2));
           _9 = Lt(_7, _8);
-          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb3;
+          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir
index 568ad441cbcd6..6fb107929e6bb 100644
--- a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir
@@ -14,7 +14,7 @@ fn main() -> () {
         StorageLive(_4);
         _4 = const "";
         _3 = &(*_4);
-        _2 = <str as ToString>::to_string(move _3) -> bb1;
+        _2 = <str as ToString>::to_string(move _3) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff
index b17675ec1edf0..3df8e567f1fe0 100644
--- a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff
+++ b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff
@@ -26,7 +26,7 @@
 -         _6 = &mut _2;
 +         _6 = &mut _0;
           _5 = &mut (*_6);
-          _3 = move _4(move _5) -> bb1;
+          _3 = move _4(move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir
index 46c078cea0d61..98c267e8e71ee 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir
@@ -31,7 +31,7 @@ fn step_forward(_1: u32, _2: usize) -> u32 {
         StorageLive(_7);
         StorageLive(_4);
         StorageLive(_3);
-        _3 = <u32 as Step>::forward_checked(_1, _2) -> bb1;
+        _3 = <u32 as Step>::forward_checked(_1, _2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -47,7 +47,7 @@ fn step_forward(_1: u32, _2: usize) -> u32 {
     }
 
     bb2: {
-        assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> bb3;
+        assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb3, unwind continue];
     }
 
     bb3: {
diff --git a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
index b8b2d91adb691..3b49cb711b773 100644
--- a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
@@ -30,7 +30,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
     bb0: {
         StorageLive(_4);
         StorageLive(_3);
-        _3 = <impl Iterator<Item = T> as Iterator>::filter_map::<U, impl Fn(T) -> Option<U>>(move _1, move _2) -> bb1;
+        _3 = <impl Iterator<Item = T> as Iterator>::filter_map::<U, impl Fn(T) -> Option<U>>(move _1, move _2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -60,7 +60,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
 
     bb4: {
         StorageDead(_9);
-        drop(_5) -> bb5;
+        drop(_5) -> [return: bb5, unwind continue];
     }
 
     bb5: {
diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
index 609555c8c43ee..40bb3a37c5858 100644
--- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
@@ -79,7 +79,7 @@ fn int_range(_1: usize, _2: usize) -> () {
     bb3: {
         _12 = ((*_5).0: usize);
         StorageLive(_13);
-        _13 = <usize as Step>::forward_unchecked(_12, const 1_usize) -> bb4;
+        _13 = <usize as Step>::forward_unchecked(_12, const 1_usize) -> [return: bb4, unwind continue];
     }
 
     bb4: {
@@ -104,7 +104,7 @@ fn int_range(_1: usize, _2: usize) -> () {
 
     bb7: {
         _15 = ((_11 as Some).0: usize);
-        _16 = opaque::<usize>(_15) -> bb8;
+        _16 = opaque::<usize>(_15) -> [return: bb8, unwind continue];
     }
 
     bb8: {
diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
index f756f34b7d662..e4e1d052e733c 100644
--- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
@@ -25,7 +25,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
     bb0: {
         StorageLive(_4);
         StorageLive(_3);
-        _3 = <impl Iterator<Item = T> as Iterator>::map::<U, impl Fn(T) -> U>(move _1, move _2) -> bb1;
+        _3 = <impl Iterator<Item = T> as Iterator>::map::<U, impl Fn(T) -> U>(move _1, move _2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -49,7 +49,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
 
     bb4: {
         StorageDead(_7);
-        drop(_5) -> bb5;
+        drop(_5) -> [return: bb5, unwind continue];
     }
 
     bb5: {
diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir
index 604cb773da571..1b5f2a0884b01 100644
--- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir
@@ -19,7 +19,7 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
 
     bb0: {
         StorageLive(_2);
-        _2 = <Vec<impl Sized> as IntoIterator>::into_iter(move _1) -> bb1;
+        _2 = <Vec<impl Sized> as IntoIterator>::into_iter(move _1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -41,7 +41,7 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
 
     bb4: {
         StorageDead(_5);
-        drop(_3) -> bb5;
+        drop(_3) -> [return: bb5, unwind continue];
     }
 
     bb5: {
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff
index a57ce86bc25a0..b6929f3f93c6c 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff
@@ -25,9 +25,9 @@
       bb0: {
           StorageLive(_1);
 -         _2 = CheckedAdd(const 2_i32, const 2_i32);
--         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1;
+-         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
 +         _2 = const (4_i32, false);
-+         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1;
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -40,9 +40,9 @@
           _5 = const 3_usize;
           _6 = const 6_usize;
 -         _7 = Lt(_5, _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2;
+-         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind continue];
 +         _7 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff
index a57ce86bc25a0..b6929f3f93c6c 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff
@@ -25,9 +25,9 @@
       bb0: {
           StorageLive(_1);
 -         _2 = CheckedAdd(const 2_i32, const 2_i32);
--         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1;
+-         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
 +         _2 = const (4_i32, false);
-+         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1;
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -40,9 +40,9 @@
           _5 = const 3_usize;
           _6 = const 6_usize;
 -         _7 = Lt(_5, _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2;
+-         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind continue];
 +         _7 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
index 1a5617c7639be..e987969d313a2 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
@@ -27,7 +27,7 @@
       bb0: {
           StorageLive(_1);
           _2 = CheckedAdd(const 2_i32, const 2_i32);
-          assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1;
+          assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -39,7 +39,7 @@
           _5 = const 3_usize;
           _6 = Len(_4);
           _7 = Lt(_5, _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2;
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
index 1a5617c7639be..e987969d313a2 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
@@ -27,7 +27,7 @@
       bb0: {
           StorageLive(_1);
           _2 = CheckedAdd(const 2_i32, const 2_i32);
-          assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1;
+          assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -39,7 +39,7 @@
           _5 = const 3_usize;
           _6 = Len(_4);
           _7 = Lt(_5, _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2;
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index cf98f2022c5a5..fbe16dc3cd476 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -102,7 +102,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     bb6: {
         StorageDead(_12);
         StorageDead(_5);
-        drop(_3) -> bb7;
+        drop(_3) -> [return: bb7, unwind continue];
     }
 
     bb7: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
index a7525b8b9a818..04d6da1d9bd4f 100644
--- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
@@ -52,7 +52,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     bb3: {
         StorageDead(_7);
         StorageDead(_5);
-        drop(_3) -> bb4;
+        drop(_3) -> [return: bb4, unwind continue];
     }
 
     bb4: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir
index af775b454a7ff..fd565fe75ec39 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir
@@ -8,7 +8,7 @@ fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> {
     }
 
     bb0: {
-        _0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_1) -> bb1;
+        _0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
index 33752e970d1a1..65870f693c062 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
@@ -53,7 +53,7 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
     bb2: {
         _7 = ((*_1).0: u32);
         StorageLive(_8);
-        _8 = <u32 as Step>::forward_unchecked(_7, const 1_usize) -> bb3;
+        _8 = <u32 as Step>::forward_unchecked(_7, const 1_usize) -> [return: bb3, unwind continue];
     }
 
     bb3: {
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
index 9f7fca639f75d..a6b931d2c2440 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
@@ -12,7 +12,7 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
 
     bb0: {
         StorageLive(_3);
-        _3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, _1) -> bb1;
+        _3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, _1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
index 13bd84f9596ca..d576520a8d56b 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
@@ -10,7 +10,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     bb0: {
         _3 = Len((*_1));
         _4 = Lt(_2, _3);
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> bb1;
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 71162df4bd066..8294a5cb6dc50 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -164,7 +164,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     bb6: {
         StorageDead(_17);
         StorageDead(_15);
-        drop(_2) -> bb7;
+        drop(_2) -> [return: bb7, unwind continue];
     }
 
     bb7: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index 08d829d52cce1..ff40e450968a5 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -152,7 +152,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     bb6: {
         StorageDead(_16);
         StorageDead(_14);
-        drop(_2) -> bb7;
+        drop(_2) -> [return: bb7, unwind continue];
     }
 
     bb7: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index 5ce8143d98b3d..3423c5d865dee 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -111,7 +111,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     bb6: {
         StorageDead(_12);
         StorageDead(_5);
-        drop(_2) -> bb7;
+        drop(_2) -> [return: bb7, unwind continue];
     }
 
     bb7: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index 14ca6004dfe26..b40d9209d2538 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -169,7 +169,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     bb6: {
         StorageDead(_18);
         StorageDead(_15);
-        drop(_2) -> bb7;
+        drop(_2) -> [return: bb7, unwind continue];
     }
 
     bb7: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir
index f9253a321f9cc..386f3a9edcd6a 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir
@@ -5,7 +5,7 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
     let mut _0: std::option::Option<&mut T>;
 
     bb0: {
-        _0 = <std::slice::IterMut<'_, T> as DoubleEndedIterator>::next_back(_1) -> bb1;
+        _0 = <std::slice::IterMut<'_, T> as DoubleEndedIterator>::next_back(_1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir
index 207fc8c752f32..e76ec00391cc5 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir
@@ -5,7 +5,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
     let mut _0: std::option::Option<&T>;
 
     bb0: {
-        _0 = <std::slice::Iter<'_, T> as Iterator>::next(_1) -> bb1;
+        _0 = <std::slice::Iter<'_, T> as Iterator>::next(_1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir
index 52e85809735e5..1e20b1be56b9a 100644
--- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir
@@ -7,7 +7,7 @@ fn outer(_1: u8) -> u8 {
 
     bb0: {
         _2 = &_1;                        // scope 0 at $DIR/spans.rs:11:11: 11:13
-        _0 = inner(_2) -> bb1;           // scope 0 at $DIR/spans.rs:11:5: 11:14
+        _0 = inner(_2) -> [return: bb1, unwind continue]; // scope 0 at $DIR/spans.rs:11:5: 11:14
                                          // mir::Constant
                                          // + span: $DIR/spans.rs:11:5: 11:10
                                          // + literal: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(<ZST>) }
diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
index 6732f8b4bb3f0..132f66a1ad3ca 100644
--- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
@@ -104,7 +104,7 @@
           _13 = &(*_26);
           StorageLive(_15);
           _15 = RangeFull;
-          _12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> bb5;
+          _12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> [return: bb5, unwind continue];
       }
   
       bb5: {
diff --git a/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
index 3baa565f03e49..012efa9693ec3 100644
--- a/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
@@ -22,7 +22,7 @@
   
       bb2: {
           _5 = (*_2);
-          _0 = opaque::<i32>(_5) -> bb3;
+          _0 = opaque::<i32>(_5) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
index 9ceb5a7634dda..c6bd6c2121092 100644
--- a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
@@ -27,17 +27,17 @@
       bb1: {
           StorageDead(_2);
           StorageDead(_3);
-          _0 = opaque::<i32>(_6) -> bb2;
+          _0 = opaque::<i32>(_6) -> [return: bb2, unwind continue];
       }
   
       bb2: {
           _7 = (*_4);
-          _0 = opaque::<i32>(_7) -> bb3;
+          _0 = opaque::<i32>(_7) -> [return: bb3, unwind continue];
       }
   
       bb3: {
           _8 = (*_5);
-          _0 = opaque::<i32>(_8) -> bb4;
+          _0 = opaque::<i32>(_8) -> [return: bb4, unwind continue];
       }
   
       bb4: {
diff --git a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
index 03add12654509..0fd74155aa30a 100644
--- a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
@@ -14,7 +14,7 @@
           StorageDead(_1);
           StorageLive(_1);
           _3 = (*_2);
-          _0 = opaque::<i32>(_3) -> bb1;
+          _0 = opaque::<i32>(_3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
index 43292dd7249a3..f1f77cffd200a 100644
--- a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
@@ -201,7 +201,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = ();
-          _7 = opaque::<()>(move _8) -> bb1;
+          _7 = opaque::<()>(move _8) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -232,7 +232,7 @@
           StorageLive(_16);
           StorageLive(_17);
           _17 = ();
-          _16 = opaque::<()>(move _17) -> bb2;
+          _16 = opaque::<()>(move _17) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -256,7 +256,7 @@
           StorageLive(_23);
           StorageLive(_24);
           _24 = _21;
-          _23 = opaque::<&&usize>(move _24) -> bb3;
+          _23 = opaque::<&&usize>(move _24) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -280,7 +280,7 @@
           StorageLive(_30);
           StorageLive(_31);
           _31 = _28;
-          _30 = opaque::<*mut &usize>(move _31) -> bb4;
+          _30 = opaque::<*mut &usize>(move _31) -> [return: bb4, unwind continue];
       }
   
       bb4: {
@@ -303,7 +303,7 @@
           StorageLive(_36);
           StorageLive(_37);
           _37 = _34;
-          _36 = opaque::<&usize>(move _37) -> bb5;
+          _36 = opaque::<&usize>(move _37) -> [return: bb5, unwind continue];
       }
   
       bb5: {
@@ -332,7 +332,7 @@
           StorageLive(_45);
           StorageLive(_46);
           _46 = _44;
-          _45 = opaque::<&usize>(move _46) -> bb6;
+          _45 = opaque::<&usize>(move _46) -> [return: bb6, unwind continue];
       }
   
       bb6: {
@@ -355,7 +355,7 @@
           StorageLive(_50);
           StorageLive(_51);
           _51 = ();
-          _50 = opaque::<()>(move _51) -> bb7;
+          _50 = opaque::<()>(move _51) -> [return: bb7, unwind continue];
       }
   
       bb7: {
@@ -381,7 +381,7 @@
           StorageLive(_57);
           StorageLive(_58);
           _58 = ();
-          _57 = opaque::<()>(move _58) -> bb8;
+          _57 = opaque::<()>(move _58) -> [return: bb8, unwind continue];
       }
   
       bb8: {
@@ -404,7 +404,7 @@
           StorageLive(_64);
           StorageLive(_65);
           _65 = ();
-          _64 = opaque::<()>(move _65) -> bb9;
+          _64 = opaque::<()>(move _65) -> [return: bb9, unwind continue];
       }
   
       bb9: {
@@ -428,7 +428,7 @@
           StorageLive(_70);
           StorageLive(_71);
           _71 = ();
-          _70 = opaque::<()>(move _71) -> bb10;
+          _70 = opaque::<()>(move _71) -> [return: bb10, unwind continue];
       }
   
       bb10: {
diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
index 3a317853bdb74..05eab7989dfb5 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
@@ -242,7 +242,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = ();
-          _7 = opaque::<()>(move _8) -> bb1;
+          _7 = opaque::<()>(move _8) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -269,7 +269,7 @@
           StorageLive(_15);
           StorageLive(_16);
           _16 = ();
-          _15 = opaque::<()>(move _16) -> bb2;
+          _15 = opaque::<()>(move _16) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -293,7 +293,7 @@
           StorageLive(_22);
           StorageLive(_23);
           _23 = _20;
-          _22 = opaque::<&*const usize>(move _23) -> bb3;
+          _22 = opaque::<&*const usize>(move _23) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -317,7 +317,7 @@
           StorageLive(_29);
           StorageLive(_30);
           _30 = _27;
-          _29 = opaque::<*mut *const usize>(move _30) -> bb4;
+          _29 = opaque::<*mut *const usize>(move _30) -> [return: bb4, unwind continue];
       }
   
       bb4: {
@@ -340,7 +340,7 @@
           StorageLive(_35);
           StorageLive(_36);
           _36 = _33;
-          _35 = opaque::<*const usize>(move _36) -> bb5;
+          _35 = opaque::<*const usize>(move _36) -> [return: bb5, unwind continue];
       }
   
       bb5: {
@@ -369,7 +369,7 @@
           StorageLive(_44);
           StorageLive(_45);
           _45 = _43;
-          _44 = opaque::<*const usize>(move _45) -> bb6;
+          _44 = opaque::<*const usize>(move _45) -> [return: bb6, unwind continue];
       }
   
       bb6: {
@@ -392,7 +392,7 @@
           StorageLive(_49);
           StorageLive(_50);
           _50 = ();
-          _49 = opaque::<()>(move _50) -> bb7;
+          _49 = opaque::<()>(move _50) -> [return: bb7, unwind continue];
       }
   
       bb7: {
@@ -414,7 +414,7 @@
           StorageLive(_55);
           StorageLive(_56);
           _56 = ();
-          _55 = opaque::<()>(move _56) -> bb8;
+          _55 = opaque::<()>(move _56) -> [return: bb8, unwind continue];
       }
   
       bb8: {
@@ -437,7 +437,7 @@
           StorageLive(_62);
           StorageLive(_63);
           _63 = ();
-          _62 = opaque::<()>(move _63) -> bb9;
+          _62 = opaque::<()>(move _63) -> [return: bb9, unwind continue];
       }
   
       bb9: {
@@ -462,7 +462,7 @@
           StorageLive(_69);
           StorageLive(_70);
           _70 = ();
-          _69 = opaque::<()>(move _70) -> bb10;
+          _69 = opaque::<()>(move _70) -> [return: bb10, unwind continue];
       }
   
       bb10: {
@@ -486,7 +486,7 @@
           StorageLive(_75);
           StorageLive(_76);
           _76 = ();
-          _75 = opaque::<()>(move _76) -> bb11;
+          _75 = opaque::<()>(move _76) -> [return: bb11, unwind continue];
       }
   
       bb11: {
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
index 91c6b2b632207..ee680fdb3f218 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
@@ -201,7 +201,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = ();
-          _7 = opaque::<()>(move _8) -> bb1;
+          _7 = opaque::<()>(move _8) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -232,7 +232,7 @@
           StorageLive(_16);
           StorageLive(_17);
           _17 = ();
-          _16 = opaque::<()>(move _17) -> bb2;
+          _16 = opaque::<()>(move _17) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -256,7 +256,7 @@
           StorageLive(_23);
           StorageLive(_24);
           _24 = _21;
-          _23 = opaque::<&&mut usize>(move _24) -> bb3;
+          _23 = opaque::<&&mut usize>(move _24) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -280,7 +280,7 @@
           StorageLive(_30);
           StorageLive(_31);
           _31 = _28;
-          _30 = opaque::<*mut &mut usize>(move _31) -> bb4;
+          _30 = opaque::<*mut &mut usize>(move _31) -> [return: bb4, unwind continue];
       }
   
       bb4: {
@@ -302,7 +302,7 @@
           StorageLive(_36);
           StorageLive(_37);
           _37 = move _34;
-          _36 = opaque::<&mut usize>(move _37) -> bb5;
+          _36 = opaque::<&mut usize>(move _37) -> [return: bb5, unwind continue];
       }
   
       bb5: {
@@ -329,7 +329,7 @@
           StorageLive(_45);
           StorageLive(_46);
           _46 = move _44;
-          _45 = opaque::<&mut usize>(move _46) -> bb6;
+          _45 = opaque::<&mut usize>(move _46) -> [return: bb6, unwind continue];
       }
   
       bb6: {
@@ -352,7 +352,7 @@
           StorageLive(_50);
           StorageLive(_51);
           _51 = ();
-          _50 = opaque::<()>(move _51) -> bb7;
+          _50 = opaque::<()>(move _51) -> [return: bb7, unwind continue];
       }
   
       bb7: {
@@ -378,7 +378,7 @@
           StorageLive(_57);
           StorageLive(_58);
           _58 = ();
-          _57 = opaque::<()>(move _58) -> bb8;
+          _57 = opaque::<()>(move _58) -> [return: bb8, unwind continue];
       }
   
       bb8: {
@@ -401,7 +401,7 @@
           StorageLive(_64);
           StorageLive(_65);
           _65 = ();
-          _64 = opaque::<()>(move _65) -> bb9;
+          _64 = opaque::<()>(move _65) -> [return: bb9, unwind continue];
       }
   
       bb9: {
@@ -425,7 +425,7 @@
           StorageLive(_70);
           StorageLive(_71);
           _71 = ();
-          _70 = opaque::<()>(move _71) -> bb10;
+          _70 = opaque::<()>(move _71) -> [return: bb10, unwind continue];
       }
   
       bb10: {
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
index 8c669644c48aa..fb0ef3184f00e 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
@@ -219,7 +219,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = ();
-          _7 = opaque::<()>(move _8) -> bb1;
+          _7 = opaque::<()>(move _8) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -246,7 +246,7 @@
           StorageLive(_15);
           StorageLive(_16);
           _16 = ();
-          _15 = opaque::<()>(move _16) -> bb2;
+          _15 = opaque::<()>(move _16) -> [return: bb2, unwind continue];
       }
   
       bb2: {
@@ -270,7 +270,7 @@
           StorageLive(_22);
           StorageLive(_23);
           _23 = _20;
-          _22 = opaque::<&*mut usize>(move _23) -> bb3;
+          _22 = opaque::<&*mut usize>(move _23) -> [return: bb3, unwind continue];
       }
   
       bb3: {
@@ -294,7 +294,7 @@
           StorageLive(_29);
           StorageLive(_30);
           _30 = _27;
-          _29 = opaque::<*mut *mut usize>(move _30) -> bb4;
+          _29 = opaque::<*mut *mut usize>(move _30) -> [return: bb4, unwind continue];
       }
   
       bb4: {
@@ -316,7 +316,7 @@
           StorageLive(_35);
           StorageLive(_36);
           _36 = _33;
-          _35 = opaque::<*mut usize>(move _36) -> bb5;
+          _35 = opaque::<*mut usize>(move _36) -> [return: bb5, unwind continue];
       }
   
       bb5: {
@@ -343,7 +343,7 @@
           StorageLive(_44);
           StorageLive(_45);
           _45 = _43;
-          _44 = opaque::<*mut usize>(move _45) -> bb6;
+          _44 = opaque::<*mut usize>(move _45) -> [return: bb6, unwind continue];
       }
   
       bb6: {
@@ -366,7 +366,7 @@
           StorageLive(_49);
           StorageLive(_50);
           _50 = ();
-          _49 = opaque::<()>(move _50) -> bb7;
+          _49 = opaque::<()>(move _50) -> [return: bb7, unwind continue];
       }
   
       bb7: {
@@ -388,7 +388,7 @@
           StorageLive(_55);
           StorageLive(_56);
           _56 = ();
-          _55 = opaque::<()>(move _56) -> bb8;
+          _55 = opaque::<()>(move _56) -> [return: bb8, unwind continue];
       }
   
       bb8: {
@@ -411,7 +411,7 @@
           StorageLive(_62);
           StorageLive(_63);
           _63 = ();
-          _62 = opaque::<()>(move _63) -> bb9;
+          _62 = opaque::<()>(move _63) -> [return: bb9, unwind continue];
       }
   
       bb9: {
@@ -435,7 +435,7 @@
           StorageLive(_68);
           StorageLive(_69);
           _69 = ();
-          _68 = opaque::<()>(move _69) -> bb10;
+          _68 = opaque::<()>(move _69) -> [return: bb10, unwind continue];
       }
   
       bb10: {
diff --git a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
index b4c34c07022b0..b4912a918ba42 100644
--- a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
@@ -34,7 +34,7 @@
           StorageLive(_4);
           StorageLive(_5);
           _5 = (*_3);
-          _4 = opaque::<i32>(move _5) -> bb1;
+          _4 = opaque::<i32>(move _5) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -47,7 +47,7 @@
           StorageLive(_7);
 -         _7 = (*_1);
 +         _7 = (*_3);
-          _6 = opaque::<i32>(move _7) -> bb2;
+          _6 = opaque::<i32>(move _7) -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff
index d7f867e31dde7..faaebc300efa2 100644
--- a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff
+++ b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff
@@ -32,7 +32,7 @@
 -         StorageLive(_2);
 -         StorageLive(_3);
           _3 = std::ops::Range::<i32> { start: const 0_i32, end: const 10_i32 };
-          _2 = <std::ops::Range<i32> as IntoIterator>::into_iter(move _3) -> bb1;
+          _2 = <std::ops::Range<i32> as IntoIterator>::into_iter(move _3) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -49,7 +49,7 @@
 -         StorageLive(_9);
           _9 = &mut _4;
           _8 = &mut (*_9);
-          _7 = <std::ops::Range<i32> as Iterator>::next(move _8) -> bb3;
+          _7 = <std::ops::Range<i32> as Iterator>::next(move _8) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff
index 8cb773e48076f..a335e8853f38f 100644
--- a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff
+++ b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff
@@ -14,7 +14,7 @@
 -         nop;
           StorageLive(_3);
           _3 = _1;
--         drop(_3) -> bb1;
+-         drop(_3) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff
index d189e5879820a..1f7a6f9ad59fc 100644
--- a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff
+++ b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff
@@ -14,7 +14,7 @@
 -         nop;
           StorageLive(_3);
           _3 = _1;
--         drop(_3) -> bb1;
+-         drop(_3) -> [return: bb1, unwind continue];
 -     }
 - 
 -     bb1: {
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index 18eb21d6542e0..93f14af29b4e9 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -76,7 +76,7 @@ fn array_casts() -> () {
         StorageLive(_6);
         StorageLive(_7);
         _7 = _2;
-        _6 = ptr::mut_ptr::<impl *mut usize>::add(move _7, const 1_usize) -> bb1;
+        _6 = ptr::mut_ptr::<impl *mut usize>::add(move _7, const 1_usize) -> [return: bb1, unwind continue];
     }
 
     bb1: {
@@ -102,7 +102,7 @@ fn array_casts() -> () {
         StorageLive(_16);
         StorageLive(_17);
         _17 = _9;
-        _16 = ptr::const_ptr::<impl *const usize>::add(move _17, const 1_usize) -> bb2;
+        _16 = ptr::const_ptr::<impl *const usize>::add(move _17, const 1_usize) -> [return: bb2, unwind continue];
     }
 
     bb2: {
@@ -154,7 +154,7 @@ fn array_casts() -> () {
         StorageLive(_34);
         _34 = Option::<Arguments<'_>>::None;
         Retag(_34);
-        _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34);
+        _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34) -> unwind continue;
     }
 
     bb4: {
diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir
index 96d2abf98b4fd..70c53bafa3737 100644
--- a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir
@@ -10,7 +10,7 @@ fn std::ptr::drop_in_place(_1: *mut Test) -> () {
         _2 = &mut (*_1);
         Retag([fn entry] _2);
         _3 = &mut (*_2);
-        _4 = <Test as Drop>::drop(move _3) -> bb1;
+        _4 = <Test as Drop>::drop(move _3) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index 483485f2942e6..4503494632874 100644
--- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -114,7 +114,7 @@ fn main() -> () {
         StorageLive(_18);
         _18 = &_1;
         _17 = &(*_18);
-        _15 = move _16(move _17) -> bb3;
+        _15 = move _16(move _17) -> [return: bb3, unwind continue];
     }
 
     bb3: {
@@ -153,7 +153,7 @@ fn main() -> () {
         _25 = _26;
         StorageDead(_26);
         StorageLive(_27);
-        _27 = array_casts() -> bb6;
+        _27 = array_casts() -> [return: bb6, unwind continue];
     }
 
     bb6: {
diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff
index 2a841f72ba39d..81903c64dbd4b 100644
--- a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff
+++ b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff
@@ -14,7 +14,7 @@
       }
   
       bb1: {
-          _2 = noop() -> bb2;
+          _2 = noop() -> [return: bb2, unwind continue];
       }
   
       bb2: {
diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
index ef3a923fd6969..ba5262b0ee143 100644
--- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
+++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
@@ -39,7 +39,7 @@
       }
   
       bb3: {
-          drop(_1) -> bb4;
+          drop(_1) -> [return: bb4, unwind continue];
       }
   
       bb4: {
diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-unwind.diff b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-unwind.diff
index dca5160202146..a5d9bbc49af0a 100644
--- a/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-unwind.diff
+++ b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.panic-unwind.diff
@@ -36,7 +36,7 @@
 +         _2 = (move _3, move _4);
 +         StorageDead(_4);
           StorageDead(_3);
-+         _1 = use_zst(move _2) -> bb1;
++         _1 = use_zst(move _2) -> [return: bb1, unwind continue];
 +     }
 + 
 +     bb1: {
@@ -55,8 +55,8 @@
 +         _6 = Add(move _7, const 2_u8);
           StorageDead(_7);
 -         StorageDead(_6);
--         _4 = use_zst(move _5) -> bb1;
-+         _5 = use_u8(move _6) -> bb2;
+-         _4 = use_zst(move _5) -> [return: bb1, unwind continue];
++         _5 = use_u8(move _6) -> [return: bb2, unwind continue];
       }
   
 -     bb1: {
@@ -70,7 +70,7 @@
 -         _10 = (_11.0: u8);
 -         _9 = Add(move _10, const 2_u8);
 -         StorageDead(_10);
--         _8 = use_u8(move _9) -> bb2;
+-         _8 = use_u8(move _9) -> [return: bb2, unwind continue];
 -     }
 - 
       bb2: {
diff --git a/tests/mir-opt/simplify_match.main.ConstProp.panic-unwind.diff b/tests/mir-opt/simplify_match.main.ConstProp.panic-unwind.diff
index dc2f75ec9b28e..c881dec28c77d 100644
--- a/tests/mir-opt/simplify_match.main.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/simplify_match.main.ConstProp.panic-unwind.diff
@@ -20,7 +20,7 @@
       }
   
       bb2: {
-          _0 = noop() -> bb3;
+          _0 = noop() -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff
index 19ea846bf2ce2..906dce9819fdc 100644
--- a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff
+++ b/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff
@@ -19,7 +19,7 @@
   
       bb0: {
           StorageLive(_1);
-          _1 = empty() -> bb1;
+          _1 = empty() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-unwind.diff
index 9d54a2f234b1d..a0479fb91304b 100644
--- a/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.panic-unwind.diff
@@ -21,7 +21,7 @@
           StorageLive(_1);
           _1 = const true;
           StorageLive(_2);
-          _2 = empty() -> bb1;
+          _2 = empty() -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -39,7 +39,7 @@
       }
   
       bb3: {
-          _5 = loop_forever() -> bb5;
+          _5 = loop_forever() -> [return: bb5, unwind continue];
       }
   
       bb4: {
diff --git a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir
index ec4782e5f3c7b..7dc4f7ab1a87c 100644
--- a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir
@@ -12,7 +12,7 @@ fn while_loop(_1: bool) -> () {
 
     bb1: {
         StorageLive(_2);
-        _2 = get_bool(_1) -> bb2;
+        _2 = get_bool(_1) -> [return: bb2, unwind continue];
     }
 
     bb2: {
@@ -21,7 +21,7 @@ fn while_loop(_1: bool) -> () {
 
     bb3: {
         StorageLive(_3);
-        _3 = get_bool(_1) -> bb4;
+        _3 = get_bool(_1) -> [return: bb4, unwind continue];
     }
 
     bb4: {
diff --git a/tests/run-make/const_fn_mir/dump.mir b/tests/run-make/const_fn_mir/dump.mir
index 25ac0c7e852a9..ced170bbeee2f 100644
--- a/tests/run-make/const_fn_mir/dump.mir
+++ b/tests/run-make/const_fn_mir/dump.mir
@@ -6,7 +6,7 @@ fn foo() -> i32 {
 
     bb0: {
         _1 = CheckedAdd(const 5_i32, const 6_i32);
-        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 5_i32, const 6_i32) -> bb1;
+        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 5_i32, const 6_i32) -> [success: bb1, unwind continue];
     }
 
     bb1: {
@@ -22,7 +22,7 @@ fn foo() -> i32 {
 
     bb0: {
         _1 = CheckedAdd(const 5_i32, const 6_i32);
-        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 5_i32, const 6_i32) -> bb1;
+        assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 5_i32, const 6_i32) -> [success: bb1, unwind continue];
     }
 
     bb1: {
@@ -36,7 +36,7 @@ fn main() -> () {
     let _1: i32;
 
     bb0: {
-        _1 = foo() -> bb1;
+        _1 = foo() -> [return: bb1, unwind continue];
     }
 
     bb1: {

From ef05533c39a8c2009540366731b7459a770f8a8b Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Tue, 27 Jun 2023 07:40:47 +0000
Subject: [PATCH 08/11] Simplify some conditions

---
 compiler/rustc_ast_passes/src/ast_validation.rs |  7 +++----
 compiler/rustc_expand/src/config.rs             |  2 +-
 .../src/coherence/inherent_impls_overlap.rs     | 10 +++++-----
 compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs |  4 ++--
 compiler/rustc_middle/src/lint.rs               |  7 ++++---
 .../rustc_mir_transform/src/coverage/graph.rs   |  2 +-
 .../rustc_mir_transform/src/coverage/spans.rs   |  7 ++++---
 compiler/rustc_parse/src/parser/attr.rs         | 17 +++++++----------
 compiler/rustc_parse/src/parser/attr_wrapper.rs | 10 +++++-----
 compiler/rustc_resolve/src/late/diagnostics.rs  |  7 +++----
 compiler/rustc_session/src/parse.rs             |  7 -------
 11 files changed, 35 insertions(+), 45 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a0979bbda5452..096cea945b029 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -623,13 +623,12 @@ impl<'a> AstValidator<'a> {
     fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId) {
         // FIXME(davidtwco): This is a hack to detect macros which produce spans of the
         // call site which do not have a macro backtrace. See #61963.
-        let is_macro_callsite = self
+        if self
             .session
             .source_map()
             .span_to_snippet(span)
-            .map(|snippet| snippet.starts_with("#["))
-            .unwrap_or(true);
-        if !is_macro_callsite {
+            .is_ok_and(|snippet| !snippet.starts_with("#["))
+        {
             self.lint_buffer.buffer_lint_with_diagnostic(
                 MISSING_ABI,
                 id,
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index bcfa5313bde3a..3e43eae006fdd 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -445,7 +445,7 @@ impl<'a> StripUnconfigured<'a> {
     /// If attributes are not allowed on expressions, emit an error for `attr`
     #[instrument(level = "trace", skip(self))]
     pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
-        if !self.features.map_or(true, |features| features.stmt_expr_attributes) {
+        if self.features.is_some_and(|features| !features.stmt_expr_attributes) {
             let mut err = feature_err(
                 &self.sess.parse_sess,
                 sym::stmt_expr_attributes,
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index bd6252344b2c2..3bd2931265c73 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -140,7 +140,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
         impl1_def_id: DefId,
         impl2_def_id: DefId,
     ) {
-        traits::overlapping_impls(
+        let maybe_overlap = traits::overlapping_impls(
             self.tcx,
             impl1_def_id,
             impl2_def_id,
@@ -148,11 +148,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
             // inherent impls without warning.
             SkipLeakCheck::Yes,
             overlap_mode,
-        )
-        .map_or(true, |overlap| {
+        );
+
+        if let Some(overlap) = maybe_overlap {
             self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
-            false
-        });
+        }
     }
 
     fn check_item(&mut self, id: hir::ItemId) {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index f294ff0051df5..5bd069fc275d2 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -955,9 +955,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         //   - f(0, 1,)
                         //   + f()
                         if only_extras_so_far
-                            && errors
+                            && !errors
                                 .peek()
-                                .map_or(true, |next_error| !matches!(next_error, Error::Extra(_)))
+                                .is_some_and(|next_error| matches!(next_error, Error::Extra(_)))
                         {
                             let next = provided_arg_tys
                                 .get(arg_idx + 1)
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index caf3fc26039a0..81c1ae4f6300e 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -388,10 +388,11 @@ pub fn struct_lint_level(
             // it'll become a hard error, so we have to emit *something*. Also,
             // if this lint occurs in the expansion of a macro from an external crate,
             // allow individual lints to opt-out from being reported.
-            let not_future_incompatible =
-                future_incompatible.map(|f| f.reason.edition().is_some()).unwrap_or(true);
-            if not_future_incompatible && !lint.report_in_external_macro {
+            let incompatible = future_incompatible.is_some_and(|f| f.reason.edition().is_none());
+
+            if !incompatible && !lint.report_in_external_macro {
                 err.cancel();
+
                 // Don't continue further, since we don't want to have
                 // `diag_span_note_once` called for a diagnostic that isn't emitted.
                 return;
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index ea1223fbca642..d2a854b26756d 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -387,7 +387,7 @@ impl BasicCoverageBlockData {
             // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
             // have an expression (to be injected into an existing `BasicBlock` represented by this
             // `BasicCoverageBlock`).
-            if !self.counter_kind.as_ref().map_or(true, |c| c.is_expression()) {
+            if self.counter_kind.as_ref().is_some_and(|c| !c.is_expression()) {
                 return Error::from_string(format!(
                     "attempt to add an incoming edge counter from {:?} when the target BCB already \
                     has a `Counter`",
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index d27200419e2cb..35cf9ea5f91cd 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -480,9 +480,10 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
 
     fn check_invoked_macro_name_span(&mut self) {
         if let Some(visible_macro) = self.curr().visible_macro(self.body_span) {
-            if self.prev_expn_span.map_or(true, |prev_expn_span| {
-                self.curr().expn_span.ctxt() != prev_expn_span.ctxt()
-            }) {
+            if !self
+                .prev_expn_span
+                .is_some_and(|prev_expn_span| self.curr().expn_span.ctxt() == prev_expn_span.ctxt())
+            {
                 let merged_prefix_len = self.curr_original_span.lo() - self.curr().span.lo();
                 let after_macro_bang =
                     merged_prefix_len + BytePos(visible_macro.as_str().len() as u32 + 1);
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index e1db19557cfe2..ee0abba1c1753 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -422,15 +422,12 @@ impl<'a> Parser<'a> {
     }
 }
 
-pub fn maybe_needs_tokens(attrs: &[ast::Attribute]) -> bool {
-    // One of the attributes may either itself be a macro,
-    // or expand to macro attributes (`cfg_attr`).
-    attrs.iter().any(|attr| {
-        if attr.is_doc_comment() {
-            return false;
-        }
-        attr.ident().map_or(true, |ident| {
-            ident.name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(ident.name)
-        })
+/// The attributes are complete if all attributes are either a doc comment or a builtin attribute other than `cfg_attr`
+pub fn is_complete(attrs: &[ast::Attribute]) -> bool {
+    attrs.iter().all(|attr| {
+        attr.is_doc_comment()
+            || attr.ident().is_some_and(|ident| {
+                ident.name != sym::cfg_attr && rustc_feature::is_builtin_attr_name(ident.name)
+            })
     })
 }
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 1e6ac54964f99..b579da098d8a1 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -61,8 +61,8 @@ impl AttrWrapper {
         self.attrs.is_empty()
     }
 
-    pub fn maybe_needs_tokens(&self) -> bool {
-        crate::parser::attr::maybe_needs_tokens(&self.attrs)
+    pub fn is_complete(&self) -> bool {
+        crate::parser::attr::is_complete(&self.attrs)
     }
 }
 
@@ -201,7 +201,7 @@ impl<'a> Parser<'a> {
         //    by definition
         if matches!(force_collect, ForceCollect::No)
             // None of our outer attributes can require tokens (e.g. a proc-macro)
-            && !attrs.maybe_needs_tokens()
+            && attrs.is_complete()
             // If our target supports custom inner attributes, then we cannot bail
             // out early, since we may need to capture tokens for a custom inner attribute
             // invocation.
@@ -244,9 +244,9 @@ impl<'a> Parser<'a> {
         // Now that we've parsed an AST node, we have more information available.
         if matches!(force_collect, ForceCollect::No)
             // We now have inner attributes available, so this check is more precise
-            // than `attrs.maybe_needs_tokens()` at the start of the function.
+            // than `attrs.is_complete()` at the start of the function.
             // As a result, we don't need to check `R::SUPPORTS_CUSTOM_INNER_ATTRS`
-            && !crate::parser::attr::maybe_needs_tokens(ret.attrs())
+            && crate::parser::attr::is_complete(ret.attrs())
             // Subtle: We call `has_cfg_or_cfg_attr` with the attrs from `ret`.
             // This ensures that we consider inner attributes (e.g. `#![cfg]`),
             // which require us to have tokens available
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 7284b33f09d8e..0d62825b1c545 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2182,10 +2182,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 None => {
                     debug!(?param.ident, ?param.ident.span);
                     let deletion_span = deletion_span();
-                    // the give lifetime originates from expanded code so we won't be able to remove it #104432
-                    let lifetime_only_in_expanded_code =
-                        deletion_span.map(|sp| sp.in_derive_expansion()).unwrap_or(true);
-                    if !lifetime_only_in_expanded_code {
+
+                    // if the lifetime originates from expanded code, we won't be able to remove it #104432
+                    if deletion_span.is_some_and(|sp| !sp.in_derive_expansion()) {
                         self.r.lint_buffer.buffer_lint_with_diagnostic(
                             lint::builtin::UNUSED_LIFETIMES,
                             param.id,
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index a433e2371c9d4..194f7201ff357 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -51,13 +51,6 @@ impl GatedSpans {
         debug_assert_eq!(span, removed_span);
     }
 
-    /// Is the provided `feature` gate ungated currently?
-    ///
-    /// Using this is discouraged unless you have a really good reason to.
-    pub fn is_ungated(&self, feature: Symbol) -> bool {
-        self.spans.borrow().get(&feature).map_or(true, |spans| spans.is_empty())
-    }
-
     /// Prepend the given set of `spans` onto the set in `self`.
     pub fn merge(&self, mut spans: FxHashMap<Symbol, Vec<Span>>) {
         let mut inner = self.spans.borrow_mut();

From 09f05489e34f54f3e1f89350651bbcbd564dbbf7 Mon Sep 17 00:00:00 2001
From: Anthony Kalaitzis <anthony.kalaitzis@gmail.com>
Date: Tue, 27 Jun 2023 17:52:26 +0930
Subject: [PATCH 09/11] Add passing & failing test for bultin dyn trait
 generation

---
 .../ui/traits/ice-with-dyn-pointee-errors.rs  | 15 +++++++++++++++
 .../traits/ice-with-dyn-pointee-errors.stderr | 19 +++++++++++++++++++
 tests/ui/traits/ice-with-dyn-pointee.rs       | 11 +++++++++++
 3 files changed, 45 insertions(+)
 create mode 100644 tests/ui/traits/ice-with-dyn-pointee-errors.rs
 create mode 100644 tests/ui/traits/ice-with-dyn-pointee-errors.stderr
 create mode 100644 tests/ui/traits/ice-with-dyn-pointee.rs

diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.rs b/tests/ui/traits/ice-with-dyn-pointee-errors.rs
new file mode 100644
index 0000000000000..46cef2c8bc094
--- /dev/null
+++ b/tests/ui/traits/ice-with-dyn-pointee-errors.rs
@@ -0,0 +1,15 @@
+#![feature(ptr_metadata)]
+// Address issue #112737 -- ICE with dyn Pointee
+extern crate core;
+use core::ptr::Pointee;
+
+fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
+
+fn raw_pointer_in(x: &dyn Pointee<Metadata = ()>) {
+    unknown_sized_object_ptr_in(x)
+    //~^ ERROR type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::Metadata == ()`
+}
+
+fn main() {
+    raw_pointer_in(&42)
+}
diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
new file mode 100644
index 0000000000000..8ad11c3344a14
--- /dev/null
+++ b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
@@ -0,0 +1,19 @@
+error[E0271]: type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::Metadata == ()`
+  --> $DIR/ice-with-dyn-pointee-errors.rs:9:33
+   |
+LL |     unknown_sized_object_ptr_in(x)
+   |     --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ...>>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected unit type `()`
+                 found struct `DynMetadata<dyn Pointee<Metadata = ()>>`
+note: required by a bound in `unknown_sized_object_ptr_in`
+  --> $DIR/ice-with-dyn-pointee-errors.rs:6:50
+   |
+LL | fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
+   |                                                  ^^^^^^^^^^^^^ required by this bound in `unknown_sized_object_ptr_in`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/ice-with-dyn-pointee.rs b/tests/ui/traits/ice-with-dyn-pointee.rs
new file mode 100644
index 0000000000000..9b3b9c8cddf19
--- /dev/null
+++ b/tests/ui/traits/ice-with-dyn-pointee.rs
@@ -0,0 +1,11 @@
+// run-pass
+#![feature(ptr_metadata)]
+// Address issue #112737 -- ICE with dyn Pointee
+extern crate core;
+use core::ptr::Pointee;
+
+fn raw_pointer_in(_: &dyn Pointee<Metadata = ()>) {}
+
+fn main() {
+    raw_pointer_in(&42)
+}

From cef812bd958d5037224aebe3721f3ffc9c80965e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?=
 <jieyouxu@outlook.com>
Date: Fri, 23 Jun 2023 05:56:09 +0800
Subject: [PATCH 10/11] Provide more context for `rustc +nightly
 -Zunstable-options` on stable

---
 .../src/pretty_clif.rs                        |   4 +-
 compiler/rustc_driver_impl/src/args.rs        |   9 +-
 compiler/rustc_driver_impl/src/lib.rs         | 128 +++---
 compiler/rustc_interface/src/interface.rs     |  33 +-
 compiler/rustc_interface/src/tests.rs         |  95 +++--
 compiler/rustc_interface/src/util.rs          |  45 +-
 compiler/rustc_session/src/config.rs          | 400 ++++++++----------
 compiler/rustc_session/src/options.rs         |  17 +-
 compiler/rustc_session/src/search_paths.rs    |   6 +-
 compiler/rustc_session/src/session.rs         |  99 +++--
 src/librustdoc/config.rs                      |  36 +-
 src/librustdoc/core.rs                        |   7 +-
 src/librustdoc/doctest.rs                     |  11 +-
 src/librustdoc/lib.rs                         |  54 ++-
 src/tools/clippy/src/driver.rs                |   6 +-
 src/tools/error_index_generator/main.rs       |   5 +-
 src/tools/miri/src/bin/miri.rs                |  25 +-
 .../obtain-borrowck/driver.rs                 |   3 +-
 tests/ui-fulldeps/stable-mir/crate-info.rs    |   3 +
 19 files changed, 512 insertions(+), 474 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
index 1007b33eca42d..5a4f9e804453f 100644
--- a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
+++ b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
@@ -225,10 +225,10 @@ pub(crate) fn write_ir_file(
     let res = std::fs::File::create(clif_file_name).and_then(|mut file| write(&mut file));
     if let Err(err) = res {
         // Using early_warn as no Session is available here
-        rustc_session::early_warn(
+        let handler = rustc_session::EarlyErrorHandler::new(
             rustc_session::config::ErrorOutputType::default(),
-            format!("error writing ir file: {}", err),
         );
+        handler.early_warn(format!("error writing ir file: {}", err));
     }
 }
 
diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs
index eb92ccc17b20f..654d7636da200 100644
--- a/compiler/rustc_driver_impl/src/args.rs
+++ b/compiler/rustc_driver_impl/src/args.rs
@@ -3,6 +3,8 @@ use std::fmt;
 use std::fs;
 use std::io;
 
+use rustc_session::EarlyErrorHandler;
+
 fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
     if let Some(path) = arg.strip_prefix('@') {
         let file = match fs::read_to_string(path) {
@@ -21,15 +23,12 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
 /// **Note:** This function doesn't interpret argument 0 in any special way.
 /// If this function is intended to be used with command line arguments,
 /// `argv[0]` must be removed prior to calling it manually.
-pub fn arg_expand_all(at_args: &[String]) -> Vec<String> {
+pub fn arg_expand_all(handler: &EarlyErrorHandler, at_args: &[String]) -> Vec<String> {
     let mut args = Vec::new();
     for arg in at_args {
         match arg_expand(arg.clone()) {
             Ok(arg) => args.extend(arg),
-            Err(err) => rustc_session::early_error(
-                rustc_session::config::ErrorOutputType::default(),
-                format!("Failed to load argument file: {err}"),
-            ),
+            Err(err) => handler.early_error(format!("Failed to load argument file: {err}")),
         }
     }
     args
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 984cc1557a49b..4b4573ec2eba3 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -40,8 +40,7 @@ use rustc_session::config::{
 use rustc_session::cstore::MetadataLoader;
 use rustc_session::getopts::{self, Matches};
 use rustc_session::lint::{Lint, LintId};
-use rustc_session::{config, Session};
-use rustc_session::{early_error, early_error_no_abort, early_warn};
+use rustc_session::{config, EarlyErrorHandler, Session};
 use rustc_span::source_map::{FileLoader, FileName};
 use rustc_span::symbol::sym;
 use rustc_target::json::ToJson;
@@ -174,6 +173,7 @@ pub trait Callbacks {
     /// continue the compilation afterwards (defaults to `Compilation::Continue`)
     fn after_analysis<'tcx>(
         &mut self,
+        _handler: &EarlyErrorHandler,
         _compiler: &interface::Compiler,
         _queries: &'tcx Queries<'tcx>,
     ) -> Compilation {
@@ -260,6 +260,8 @@ fn run_compiler(
         Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
     >,
 ) -> interface::Result<()> {
+    let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
     // Throw away the first argument, the name of the binary.
     // In case of at_args being empty, as might be the case by
     // passing empty argument array to execve under some platforms,
@@ -270,22 +272,22 @@ fn run_compiler(
     // the compiler with @empty_file as argv[0] and no more arguments.
     let at_args = at_args.get(1..).unwrap_or_default();
 
-    let args = args::arg_expand_all(at_args);
+    let args = args::arg_expand_all(&early_error_handler, at_args);
 
-    let Some(matches) = handle_options(&args) else { return Ok(()) };
+    let Some(matches) = handle_options(&early_error_handler, &args) else { return Ok(()) };
 
-    let sopts = config::build_session_options(&matches);
+    let sopts = config::build_session_options(&mut early_error_handler, &matches);
 
     // Set parallel mode before thread pool creation, which will create `Lock`s.
     interface::set_thread_safe_mode(&sopts.unstable_opts);
 
     if let Some(ref code) = matches.opt_str("explain") {
-        handle_explain(diagnostics_registry(), code, sopts.error_format);
+        handle_explain(&early_error_handler, diagnostics_registry(), code);
         return Ok(());
     }
 
-    let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
-    let check_cfg = interface::parse_check_cfg(matches.opt_strs("check-cfg"));
+    let cfg = interface::parse_cfgspecs(&early_error_handler, matches.opt_strs("cfg"));
+    let check_cfg = interface::parse_check_cfg(&early_error_handler, matches.opt_strs("check-cfg"));
     let (odir, ofile) = make_output(&matches);
     let mut config = interface::Config {
         opts: sopts,
@@ -304,7 +306,7 @@ fn run_compiler(
         registry: diagnostics_registry(),
     };
 
-    match make_input(config.opts.error_format, &matches.free) {
+    match make_input(&early_error_handler, &matches.free) {
         Err(reported) => return Err(reported),
         Ok(Some(input)) => {
             config.input = input;
@@ -314,8 +316,13 @@ fn run_compiler(
         Ok(None) => match matches.free.len() {
             0 => {
                 callbacks.config(&mut config);
+
+                early_error_handler.abort_if_errors();
+
                 interface::run_compiler(config, |compiler| {
                     let sopts = &compiler.session().opts;
+                    let handler = EarlyErrorHandler::new(sopts.error_format);
+
                     if sopts.describe_lints {
                         let mut lint_store =
                             rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
@@ -329,31 +336,38 @@ fn run_compiler(
                         describe_lints(compiler.session(), &lint_store, registered_lints);
                         return;
                     }
-                    let should_stop =
-                        print_crate_info(&**compiler.codegen_backend(), compiler.session(), false);
+                    let should_stop = print_crate_info(
+                        &handler,
+                        &**compiler.codegen_backend(),
+                        compiler.session(),
+                        false,
+                    );
 
                     if should_stop == Compilation::Stop {
                         return;
                     }
-                    early_error(sopts.error_format, "no input filename given")
+                    handler.early_error("no input filename given")
                 });
                 return Ok(());
             }
             1 => panic!("make_input should have provided valid inputs"),
-            _ => early_error(
-                config.opts.error_format,
-                format!(
-                    "multiple input filenames provided (first two filenames are `{}` and `{}`)",
-                    matches.free[0], matches.free[1],
-                ),
-            ),
+            _ => early_error_handler.early_error(format!(
+                "multiple input filenames provided (first two filenames are `{}` and `{}`)",
+                matches.free[0], matches.free[1],
+            )),
         },
     };
 
+    early_error_handler.abort_if_errors();
+
     interface::run_compiler(config, |compiler| {
         let sess = compiler.session();
-        let should_stop = print_crate_info(&**compiler.codegen_backend(), sess, true)
-            .and_then(|| list_metadata(sess, &*compiler.codegen_backend().metadata_loader()))
+        let handler = EarlyErrorHandler::new(sess.opts.error_format);
+
+        let should_stop = print_crate_info(&handler, &**compiler.codegen_backend(), sess, true)
+            .and_then(|| {
+                list_metadata(&handler, sess, &*compiler.codegen_backend().metadata_loader())
+            })
             .and_then(|| try_process_rlink(sess, compiler));
 
         if should_stop == Compilation::Stop {
@@ -421,7 +435,7 @@ fn run_compiler(
 
             queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?;
 
-            if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
+            if callbacks.after_analysis(&handler, compiler, queries) == Compilation::Stop {
                 return early_exit();
             }
 
@@ -475,7 +489,7 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileNa
 
 // Extract input (string or file and optional path) from matches.
 fn make_input(
-    error_format: ErrorOutputType,
+    handler: &EarlyErrorHandler,
     free_matches: &[String],
 ) -> Result<Option<Input>, ErrorGuaranteed> {
     if free_matches.len() == 1 {
@@ -485,8 +499,7 @@ fn make_input(
             if io::stdin().read_to_string(&mut src).is_err() {
                 // Immediately stop compilation if there was an issue reading
                 // the input (for example if the input stream is not UTF-8).
-                let reported = early_error_no_abort(
-                    error_format,
+                let reported = handler.early_error_no_abort(
                     "couldn't read from stdin, as it did not contain valid UTF-8",
                 );
                 return Err(reported);
@@ -527,7 +540,7 @@ impl Compilation {
     }
 }
 
-fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
+fn handle_explain(handler: &EarlyErrorHandler, registry: Registry, code: &str) {
     let upper_cased_code = code.to_ascii_uppercase();
     let normalised =
         if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
@@ -557,7 +570,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
             }
         }
         Err(InvalidErrorCode) => {
-            early_error(output, format!("{code} is not a valid error code"));
+            handler.early_error(format!("{code} is not a valid error code"));
         }
     }
 }
@@ -636,7 +649,11 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp
     }
 }
 
-pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Compilation {
+pub fn list_metadata(
+    handler: &EarlyErrorHandler,
+    sess: &Session,
+    metadata_loader: &dyn MetadataLoader,
+) -> Compilation {
     if sess.opts.unstable_opts.ls {
         match sess.io.input {
             Input::File(ref ifile) => {
@@ -646,7 +663,7 @@ pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Co
                 safe_println!("{}", String::from_utf8(v).unwrap());
             }
             Input::Str { .. } => {
-                early_error(ErrorOutputType::default(), "cannot list metadata for stdin");
+                handler.early_error("cannot list metadata for stdin");
             }
         }
         return Compilation::Stop;
@@ -656,6 +673,7 @@ pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Co
 }
 
 fn print_crate_info(
+    handler: &EarlyErrorHandler,
     codegen_backend: &dyn CodegenBackend,
     sess: &Session,
     parse_attrs: bool,
@@ -787,10 +805,8 @@ fn print_crate_info(
                             .expect("unknown Apple target OS")
                     )
                 } else {
-                    early_error(
-                        ErrorOutputType::default(),
-                        "only Apple targets currently support deployment version info",
-                    )
+                    handler
+                        .early_error("only Apple targets currently support deployment version info")
                 }
             }
         }
@@ -801,11 +817,12 @@ fn print_crate_info(
 /// Prints version information
 ///
 /// NOTE: this is a macro to support drivers built at a different time than the main `rustc_driver` crate.
-pub macro version($binary: literal, $matches: expr) {
+pub macro version($handler: expr, $binary: literal, $matches: expr) {
     fn unw(x: Option<&str>) -> &str {
         x.unwrap_or("unknown")
     }
     $crate::version_at_macro_invocation(
+        $handler,
         $binary,
         $matches,
         unw(option_env!("CFG_VERSION")),
@@ -817,6 +834,7 @@ pub macro version($binary: literal, $matches: expr) {
 
 #[doc(hidden)] // use the macro instead
 pub fn version_at_macro_invocation(
+    handler: &EarlyErrorHandler,
     binary: &str,
     matches: &getopts::Matches,
     version: &str,
@@ -837,7 +855,7 @@ pub fn version_at_macro_invocation(
 
         let debug_flags = matches.opt_strs("Z");
         let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
-        get_codegen_backend(&None, backend_name).print_version();
+        get_codegen_backend(handler, &None, backend_name).print_version();
     }
 }
 
@@ -1014,7 +1032,7 @@ Available lint options:
 /// Show help for flag categories shared between rustdoc and rustc.
 ///
 /// Returns whether a help option was printed.
-pub fn describe_flag_categories(matches: &Matches) -> bool {
+pub fn describe_flag_categories(handler: &EarlyErrorHandler, matches: &Matches) -> bool {
     // Handle the special case of -Wall.
     let wall = matches.opt_strs("W");
     if wall.iter().any(|x| *x == "all") {
@@ -1036,15 +1054,12 @@ pub fn describe_flag_categories(matches: &Matches) -> bool {
     }
 
     if cg_flags.iter().any(|x| *x == "no-stack-check") {
-        early_warn(
-            ErrorOutputType::default(),
-            "the --no-stack-check flag is deprecated and does nothing",
-        );
+        handler.early_warn("the --no-stack-check flag is deprecated and does nothing");
     }
 
     if cg_flags.iter().any(|x| *x == "passes=list") {
         let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
-        get_codegen_backend(&None, backend_name).print_passes();
+        get_codegen_backend(handler, &None, backend_name).print_passes();
         return true;
     }
 
@@ -1101,7 +1116,7 @@ fn print_flag_list<T>(
 ///
 /// So with all that in mind, the comments below have some more detail about the
 /// contortions done here to get things to work out correctly.
-pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
+pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option<getopts::Matches> {
     if args.is_empty() {
         // user did not write `-v` nor `-Z unstable-options`, so do not
         // include that extra information.
@@ -1127,7 +1142,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
                 .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
             _ => None,
         };
-        early_error(ErrorOutputType::default(), msg.unwrap_or_else(|| e.to_string()));
+        handler.early_error(msg.unwrap_or_else(|| e.to_string()));
     });
 
     // For all options we just parsed, we check a few aspects:
@@ -1141,7 +1156,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
     //   we're good to go.
     // * Otherwise, if we're an unstable option then we generate an error
     //   (unstable option being used on stable)
-    nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
+    nightly_options::check_nightly_options(handler, &matches, &config::rustc_optgroups());
 
     if matches.opt_present("h") || matches.opt_present("help") {
         // Only show unstable options in --help if we accept unstable options.
@@ -1151,12 +1166,12 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
         return None;
     }
 
-    if describe_flag_categories(&matches) {
+    if describe_flag_categories(handler, &matches) {
         return None;
     }
 
     if matches.opt_present("version") {
-        version!("rustc", &matches);
+        version!(handler, "rustc", &matches);
         return None;
     }
 
@@ -1276,7 +1291,8 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
         if let Some(msg) = info.payload().downcast_ref::<String>() {
             if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") {
                 // the error code is already going to be reported when the panic unwinds up the stack
-                let _ = early_error_no_abort(ErrorOutputType::default(), msg.clone());
+                let handler = EarlyErrorHandler::new(ErrorOutputType::default());
+                let _ = handler.early_error_no_abort(msg.clone());
                 return;
             }
         };
@@ -1359,16 +1375,16 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info:
 
 /// This allows tools to enable rust logging without having to magically match rustc's
 /// tracing crate version.
-pub fn init_rustc_env_logger() {
-    init_env_logger("RUSTC_LOG");
+pub fn init_rustc_env_logger(handler: &EarlyErrorHandler) {
+    init_env_logger(handler, "RUSTC_LOG");
 }
 
 /// This allows tools to enable rust logging without having to magically match rustc's
 /// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var
 /// other than `RUSTC_LOG`.
-pub fn init_env_logger(env: &str) {
+pub fn init_env_logger(handler: &EarlyErrorHandler, env: &str) {
     if let Err(error) = rustc_log::init_env_logger(env) {
-        early_error(ErrorOutputType::default(), error.to_string());
+        handler.early_error(error.to_string());
     }
 }
 
@@ -1424,7 +1440,10 @@ mod signal_handler {
 pub fn main() -> ! {
     let start_time = Instant::now();
     let start_rss = get_resident_set_size();
-    init_rustc_env_logger();
+
+    let handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
+    init_rustc_env_logger(&handler);
     signal_handler::install();
     let mut callbacks = TimePassesCallbacks::default();
     install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
@@ -1433,10 +1452,7 @@ pub fn main() -> ! {
             .enumerate()
             .map(|(i, arg)| {
                 arg.into_string().unwrap_or_else(|arg| {
-                    early_error(
-                        ErrorOutputType::default(),
-                        format!("argument {i} is not valid Unicode: {arg:?}"),
-                    )
+                    handler.early_error(format!("argument {i} is not valid Unicode: {arg:?}"))
                 })
             })
             .collect::<Vec<_>>();
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 54dabb757643a..ab5f64b383da0 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -14,12 +14,11 @@ use rustc_middle::{bug, ty};
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
-use rustc_session::config::{self, ErrorOutputType, Input, OutFileName, OutputFilenames};
-use rustc_session::config::{CheckCfg, ExpectedValues};
-use rustc_session::lint;
+use rustc_session::config::{self, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames};
 use rustc_session::parse::{CrateConfig, ParseSess};
+use rustc_session::CompilerIO;
 use rustc_session::Session;
-use rustc_session::{early_error, CompilerIO};
+use rustc_session::{lint, EarlyErrorHandler};
 use rustc_span::source_map::{FileLoader, FileName};
 use rustc_span::symbol::sym;
 use std::path::PathBuf;
@@ -66,7 +65,10 @@ pub fn set_thread_safe_mode(sopts: &config::UnstableOptions) {
 }
 
 /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
-pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
+pub fn parse_cfgspecs(
+    handler: &EarlyErrorHandler,
+    cfgspecs: Vec<String>,
+) -> FxHashSet<(String, Option<String>)> {
     rustc_span::create_default_session_if_not_set_then(move |_| {
         let cfg = cfgspecs
             .into_iter()
@@ -78,10 +80,10 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
 
                 macro_rules! error {
                     ($reason: expr) => {
-                        early_error(
-                            ErrorOutputType::default(),
-                            format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s),
-                        );
+                        handler.early_error(format!(
+                            concat!("invalid `--cfg` argument: `{}` (", $reason, ")"),
+                            s
+                        ));
                     };
                 }
 
@@ -125,7 +127,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
 }
 
 /// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
-pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
+pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg {
     rustc_span::create_default_session_if_not_set_then(move |_| {
         let mut check_cfg = CheckCfg::default();
 
@@ -137,10 +139,10 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
 
             macro_rules! error {
                 ($reason: expr) => {
-                    early_error(
-                        ErrorOutputType::default(),
-                        format!(concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s),
-                    )
+                    handler.early_error(format!(
+                        concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
+                        s
+                    ))
                 };
             }
 
@@ -294,8 +296,11 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
 
             let registry = &config.registry;
 
+            let handler = EarlyErrorHandler::new(config.opts.error_format);
+
             let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
             let (mut sess, codegen_backend) = util::create_session(
+                &handler,
                 config.opts,
                 config.crate_cfg,
                 config.crate_check_cfg,
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 9d0c9ec974231..6054b48b0b53a 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -21,8 +21,8 @@ use rustc_session::config::{InstrumentCoverage, Passes};
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
 use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
-use rustc_session::CompilerIO;
 use rustc_session::{build_session, getopts, Session};
+use rustc_session::{CompilerIO, EarlyErrorHandler};
 use rustc_span::edition::{Edition, DEFAULT_EDITION};
 use rustc_span::symbol::sym;
 use rustc_span::FileName;
@@ -36,15 +36,18 @@ use std::path::{Path, PathBuf};
 
 type CfgSpecs = FxHashSet<(String, Option<String>)>;
 
-fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options, CfgSpecs) {
-    let sessopts = build_session_options(&matches);
-    let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
+fn build_session_options_and_crate_config(
+    handler: &mut EarlyErrorHandler,
+    matches: getopts::Matches,
+) -> (Options, CfgSpecs) {
+    let sessopts = build_session_options(handler, &matches);
+    let cfg = parse_cfgspecs(handler, matches.opt_strs("cfg"));
     (sessopts, cfg)
 }
 
-fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
+fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, CfgSpecs) {
     let registry = registry::Registry::new(&[]);
-    let (sessopts, cfg) = build_session_options_and_crate_config(matches);
+    let (sessopts, cfg) = build_session_options_and_crate_config(handler, matches);
     let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
     let io = CompilerIO {
         input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
@@ -52,8 +55,18 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
         output_file: None,
         temps_dir,
     };
-    let sess =
-        build_session(sessopts, io, None, registry, vec![], Default::default(), None, None, "");
+    let sess = build_session(
+        handler,
+        sessopts,
+        io,
+        None,
+        registry,
+        vec![],
+        Default::default(),
+        None,
+        None,
+        "",
+    );
     (sess, cfg)
 }
 
@@ -120,7 +133,8 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) {
 fn test_switch_implies_cfg_test() {
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["--test".to_string()]).unwrap();
-        let (sess, cfg) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, cfg) = mk_session(&mut handler, matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
         assert!(cfg.contains(&(sym::test, None)));
     });
@@ -131,7 +145,8 @@ fn test_switch_implies_cfg_test() {
 fn test_switch_implies_cfg_test_unless_cfg_test() {
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
-        let (sess, cfg) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, cfg) = mk_session(&mut handler, matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
         let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
         assert!(test_items.next().is_some());
@@ -143,20 +158,23 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
 fn test_can_print_warnings() {
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
-        let (sess, _) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, _) = mk_session(&mut handler, matches);
         assert!(!sess.diagnostic().can_emit_warnings());
     });
 
     rustc_span::create_default_session_globals_then(|| {
         let matches =
             optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
-        let (sess, _) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, _) = mk_session(&mut handler, matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
-        let (sess, _) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, _) = mk_session(&mut handler, matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 }
@@ -302,35 +320,36 @@ fn test_search_paths_tracking_hash_different_order() {
     let mut v3 = Options::default();
     let mut v4 = Options::default();
 
+    let handler = EarlyErrorHandler::new(JSON);
     const JSON: ErrorOutputType = ErrorOutputType::Json {
         pretty: false,
         json_rendered: HumanReadableErrorType::Default(ColorConfig::Never),
     };
 
     // Reference
-    v1.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-
-    v2.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-
-    v3.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-
-    v4.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
 
     assert_same_hash(&v1, &v2);
     assert_same_hash(&v1, &v3);
@@ -851,7 +870,9 @@ fn test_edition_parsing() {
     let options = Options::default();
     assert!(options.edition == DEFAULT_EDITION);
 
+    let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
     let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
-    let (sessopts, _) = build_session_options_and_crate_config(matches);
+    let (sessopts, _) = build_session_options_and_crate_config(&mut handler, matches);
     assert!(sessopts.edition == Edition::Edition2018)
 }
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 87252fefb1e2c..035ea2414f767 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -11,16 +11,16 @@ use rustc_parse::validate_attr;
 use rustc_session as session;
 use rustc_session::config::CheckCfg;
 use rustc_session::config::{self, CrateType};
-use rustc_session::config::{ErrorOutputType, OutFileName, OutputFilenames, OutputTypes};
+use rustc_session::config::{OutFileName, OutputFilenames, OutputTypes};
 use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::parse::CrateConfig;
-use rustc_session::{early_error, filesearch, output, Session};
+use rustc_session::{filesearch, output, Session};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::FileLoader;
 use rustc_span::symbol::{sym, Symbol};
-use session::CompilerIO;
+use session::{CompilerIO, EarlyErrorHandler};
 use std::env;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::mem;
@@ -58,6 +58,7 @@ pub fn add_configuration(
 }
 
 pub fn create_session(
+    handler: &EarlyErrorHandler,
     sopts: config::Options,
     cfg: FxHashSet<(String, Option<String>)>,
     check_cfg: CheckCfg,
@@ -73,7 +74,11 @@ pub fn create_session(
     let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
         make_codegen_backend(&sopts)
     } else {
-        get_codegen_backend(&sopts.maybe_sysroot, sopts.unstable_opts.codegen_backend.as_deref())
+        get_codegen_backend(
+            handler,
+            &sopts.maybe_sysroot,
+            sopts.unstable_opts.codegen_backend.as_deref(),
+        )
     };
 
     // target_override is documented to be called before init(), so this is okay
@@ -88,7 +93,7 @@ pub fn create_session(
     ) {
         Ok(bundle) => bundle,
         Err(e) => {
-            early_error(sopts.error_format, format!("failed to load fluent bundle: {e}"));
+            handler.early_error(format!("failed to load fluent bundle: {e}"));
         }
     };
 
@@ -96,6 +101,7 @@ pub fn create_session(
     locale_resources.push(codegen_backend.locale_resource());
 
     let mut sess = session::build_session(
+        handler,
         sopts,
         io,
         bundle,
@@ -218,16 +224,16 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
     })
 }
 
-fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
+fn load_backend_from_dylib(handler: &EarlyErrorHandler, path: &Path) -> MakeBackendFn {
     let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
         let err = format!("couldn't load codegen backend {path:?}: {err}");
-        early_error(ErrorOutputType::default(), err);
+        handler.early_error(err);
     });
 
     let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
         .unwrap_or_else(|e| {
             let err = format!("couldn't load codegen backend: {e}");
-            early_error(ErrorOutputType::default(), err);
+            handler.early_error(err);
         });
 
     // Intentionally leak the dynamic library. We can't ever unload it
@@ -242,6 +248,7 @@ fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
 ///
 /// A name of `None` indicates that the default backend should be used.
 pub fn get_codegen_backend(
+    handler: &EarlyErrorHandler,
     maybe_sysroot: &Option<PathBuf>,
     backend_name: Option<&str>,
 ) -> Box<dyn CodegenBackend> {
@@ -251,10 +258,12 @@ pub fn get_codegen_backend(
         let default_codegen_backend = option_env!("CFG_DEFAULT_CODEGEN_BACKEND").unwrap_or("llvm");
 
         match backend_name.unwrap_or(default_codegen_backend) {
-            filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
+            filename if filename.contains('.') => {
+                load_backend_from_dylib(handler, filename.as_ref())
+            }
             #[cfg(feature = "llvm")]
             "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
-            backend_name => get_codegen_sysroot(maybe_sysroot, backend_name),
+            backend_name => get_codegen_sysroot(handler, maybe_sysroot, backend_name),
         }
     });
 
@@ -286,7 +295,11 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
     })
 }
 
-fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
+fn get_codegen_sysroot(
+    handler: &EarlyErrorHandler,
+    maybe_sysroot: &Option<PathBuf>,
+    backend_name: &str,
+) -> MakeBackendFn {
     // For now we only allow this function to be called once as it'll dlopen a
     // few things, which seems to work best if we only do that once. In
     // general this assertion never trips due to the once guard in `get_codegen_backend`,
@@ -321,7 +334,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
             "failed to find a `codegen-backends` folder \
                            in the sysroot candidates:\n* {candidates}"
         );
-        early_error(ErrorOutputType::default(), err);
+        handler.early_error(err);
     });
     info!("probing {} for a codegen backend", sysroot.display());
 
@@ -332,7 +345,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
             sysroot.display(),
             e
         );
-        early_error(ErrorOutputType::default(), err);
+        handler.early_error(err);
     });
 
     let mut file: Option<PathBuf> = None;
@@ -360,16 +373,16 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
                 prev.display(),
                 path.display()
             );
-            early_error(ErrorOutputType::default(), err);
+            handler.early_error(err);
         }
         file = Some(path.clone());
     }
 
     match file {
-        Some(ref s) => load_backend_from_dylib(s),
+        Some(ref s) => load_backend_from_dylib(handler, s),
         None => {
             let err = format!("unsupported builtin codegen backend `{backend_name}`");
-            early_error(ErrorOutputType::default(), err);
+            handler.early_error(err);
         }
     }
 }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index a9668ae482894..480d2478e8174 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -5,8 +5,8 @@ pub use crate::options::*;
 
 use crate::search_paths::SearchPath;
 use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
-use crate::{early_error, early_warn, Session};
 use crate::{lint, HashStableContext};
+use crate::{EarlyErrorHandler, Session};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 
@@ -1389,6 +1389,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
 }
 
 pub(super) fn build_target_config(
+    handler: &EarlyErrorHandler,
     opts: &Options,
     target_override: Option<Target>,
     sysroot: &Path,
@@ -1398,27 +1399,21 @@ pub(super) fn build_target_config(
         |t| Ok((t, TargetWarnings::empty())),
     );
     let (target, target_warnings) = target_result.unwrap_or_else(|e| {
-        early_error(
-            opts.error_format,
-            format!(
-                "Error loading target specification: {}. \
+        handler.early_error(format!(
+            "Error loading target specification: {}. \
                  Run `rustc --print target-list` for a list of built-in targets",
-                e
-            ),
-        )
+            e
+        ))
     });
     for warning in target_warnings.warning_messages() {
-        early_warn(opts.error_format, warning)
+        handler.early_warn(warning)
     }
 
     if !matches!(target.pointer_width, 16 | 32 | 64) {
-        early_error(
-            opts.error_format,
-            format!(
-                "target specification was invalid: unrecognized target-pointer-width {}",
-                target.pointer_width
-            ),
-        )
+        handler.early_error(format!(
+            "target specification was invalid: unrecognized target-pointer-width {}",
+            target.pointer_width
+        ))
     }
 
     target
@@ -1654,8 +1649,8 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
 }
 
 pub fn get_cmd_lint_options(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
-    error_format: ErrorOutputType,
 ) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
     let mut lint_opts_with_position = vec![];
     let mut describe_lints = false;
@@ -1679,14 +1674,14 @@ pub fn get_cmd_lint_options(
 
     let lint_cap = matches.opt_str("cap-lints").map(|cap| {
         lint::Level::from_str(&cap)
-            .unwrap_or_else(|| early_error(error_format, format!("unknown lint level: `{cap}`")))
+            .unwrap_or_else(|| handler.early_error(format!("unknown lint level: `{cap}`")))
     });
 
     (lint_opts, describe_lints, lint_cap)
 }
 
 /// Parses the `--color` flag.
-pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
+pub fn parse_color(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> ColorConfig {
     match matches.opt_str("color").as_deref() {
         Some("auto") => ColorConfig::Auto,
         Some("always") => ColorConfig::Always,
@@ -1694,13 +1689,10 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
 
         None => ColorConfig::Auto,
 
-        Some(arg) => early_error(
-            ErrorOutputType::default(),
-            format!(
-                "argument for `--color` must be auto, \
+        Some(arg) => handler.early_error(format!(
+            "argument for `--color` must be auto, \
                  always or never (instead was `{arg}`)"
-            ),
-        ),
+        )),
     }
 }
 
@@ -1743,7 +1735,7 @@ impl JsonUnusedExterns {
 ///
 /// The first value returned is how to render JSON diagnostics, and the second
 /// is whether or not artifact notifications are enabled.
-pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
+pub fn parse_json(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> JsonConfig {
     let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType =
         HumanReadableErrorType::Default;
     let mut json_color = ColorConfig::Never;
@@ -1755,10 +1747,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
         // won't actually be emitting any colors and anything colorized is
         // embedded in a diagnostic message anyway.
         if matches.opt_str("color").is_some() {
-            early_error(
-                ErrorOutputType::default(),
-                "cannot specify the `--color` option with `--json`",
-            );
+            handler.early_error("cannot specify the `--color` option with `--json`");
         }
 
         for sub_option in option.split(',') {
@@ -1769,10 +1758,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
                 "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
                 "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
                 "future-incompat" => json_future_incompat = true,
-                s => early_error(
-                    ErrorOutputType::default(),
-                    format!("unknown `--json` option `{s}`"),
-                ),
+                s => handler.early_error(format!("unknown `--json` option `{s}`")),
             }
         }
     }
@@ -1787,6 +1773,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
 
 /// Parses the `--error-format` flag.
 pub fn parse_error_format(
+    handler: &mut EarlyErrorHandler,
     matches: &getopts::Matches,
     color: ColorConfig,
     json_rendered: HumanReadableErrorType,
@@ -1807,13 +1794,15 @@ pub fn parse_error_format(
             Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered },
             Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),
 
-            Some(arg) => early_error(
-                ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
-                format!(
+            Some(arg) => {
+                handler.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable(
+                    HumanReadableErrorType::Default(color),
+                ));
+                handler.early_error(format!(
                     "argument for `--error-format` must be `human`, `json` or \
                      `short` (instead was `{arg}`)"
-                ),
-            ),
+                ))
+            }
         }
     } else {
         ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color))
@@ -1826,10 +1815,7 @@ pub fn parse_error_format(
         // `--error-format=json`. This means that `--json` is specified we
         // should actually be emitting JSON blobs.
         _ if !matches.opt_strs("json").is_empty() => {
-            early_error(
-                ErrorOutputType::default(),
-                "using `--json` requires also using `--error-format=json`",
-            );
+            handler.early_error("using `--json` requires also using `--error-format=json`");
         }
 
         _ => {}
@@ -1838,16 +1824,13 @@ pub fn parse_error_format(
     error_format
 }
 
-pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
+pub fn parse_crate_edition(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> Edition {
     let edition = match matches.opt_str("edition") {
         Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
-            early_error(
-                ErrorOutputType::default(),
-                format!(
-                    "argument for `--edition` must be one of: \
+            handler.early_error(format!(
+                "argument for `--edition` must be one of: \
                      {EDITION_NAME_LIST}. (instead was `{arg}`)"
-                ),
-            )
+            ))
         }),
         None => DEFAULT_EDITION,
     };
@@ -1862,39 +1845,42 @@ pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
         } else {
             format!("edition {edition} is unstable and only available with -Z unstable-options")
         };
-        early_error(ErrorOutputType::default(), msg)
+        handler.early_error(msg)
     }
 
     edition
 }
 
 fn check_error_format_stability(
+    handler: &mut EarlyErrorHandler,
     unstable_opts: &UnstableOptions,
     error_format: ErrorOutputType,
     json_rendered: HumanReadableErrorType,
 ) {
     if !unstable_opts.unstable_options {
         if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
-            early_error(
-                ErrorOutputType::Json { pretty: false, json_rendered },
-                "`--error-format=pretty-json` is unstable",
-            );
+            handler.abort_if_error_and_set_error_format(ErrorOutputType::Json {
+                pretty: false,
+                json_rendered,
+            });
+            handler.early_error("`--error-format=pretty-json` is unstable");
         }
         if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
             error_format
         {
-            early_error(
-                ErrorOutputType::Json { pretty: false, json_rendered },
-                "`--error-format=human-annotate-rs` is unstable",
-            );
+            handler.abort_if_error_and_set_error_format(ErrorOutputType::Json {
+                pretty: false,
+                json_rendered,
+            });
+            handler.early_error("`--error-format=human-annotate-rs` is unstable");
         }
     }
 }
 
 fn parse_output_types(
+    handler: &EarlyErrorHandler,
     unstable_opts: &UnstableOptions,
     matches: &getopts::Matches,
-    error_format: ErrorOutputType,
 ) -> OutputTypes {
     let mut output_types = BTreeMap::new();
     if !unstable_opts.parse_only {
@@ -1908,13 +1894,10 @@ fn parse_output_types(
                     }
                 };
                 let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
-                    early_error(
-                        error_format,
-                        format!(
-                            "unknown emission type: `{shorthand}` - expected one of: {display}",
-                            display = OutputType::shorthands_display(),
-                        ),
-                    )
+                    handler.early_error(format!(
+                        "unknown emission type: `{shorthand}` - expected one of: {display}",
+                        display = OutputType::shorthands_display(),
+                    ))
                 });
                 output_types.insert(output_type, path);
             }
@@ -1927,9 +1910,9 @@ fn parse_output_types(
 }
 
 fn should_override_cgus_and_disable_thinlto(
+    handler: &EarlyErrorHandler,
     output_types: &OutputTypes,
     matches: &getopts::Matches,
-    error_format: ErrorOutputType,
     mut codegen_units: Option<usize>,
 ) -> (bool, Option<usize>) {
     let mut disable_local_thinlto = false;
@@ -1947,15 +1930,12 @@ fn should_override_cgus_and_disable_thinlto(
             Some(n) if n > 1 => {
                 if matches.opt_present("o") {
                     for ot in &incompatible {
-                        early_warn(
-                            error_format,
-                            format!(
-                                "`--emit={ot}` with `-o` incompatible with \
+                        handler.early_warn(format!(
+                            "`--emit={ot}` with `-o` incompatible with \
                                  `-C codegen-units=N` for N > 1",
-                            ),
-                        );
+                        ));
                     }
-                    early_warn(error_format, "resetting to default -C codegen-units=1");
+                    handler.early_warn("resetting to default -C codegen-units=1");
                     codegen_units = Some(1);
                     disable_local_thinlto = true;
                 }
@@ -1968,27 +1948,27 @@ fn should_override_cgus_and_disable_thinlto(
     }
 
     if codegen_units == Some(0) {
-        early_error(error_format, "value for codegen units must be a positive non-zero integer");
+        handler.early_error("value for codegen units must be a positive non-zero integer");
     }
 
     (disable_local_thinlto, codegen_units)
 }
 
-fn check_thread_count(unstable_opts: &UnstableOptions, error_format: ErrorOutputType) {
+fn check_thread_count(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) {
     if unstable_opts.threads == 0 {
-        early_error(error_format, "value for threads must be a positive non-zero integer");
+        handler.early_error("value for threads must be a positive non-zero integer");
     }
 
     if unstable_opts.threads > 1 && unstable_opts.fuel.is_some() {
-        early_error(error_format, "optimization fuel is incompatible with multiple threads");
+        handler.early_error("optimization fuel is incompatible with multiple threads");
     }
 }
 
 fn collect_print_requests(
+    handler: &EarlyErrorHandler,
     cg: &mut CodegenOptions,
     unstable_opts: &mut UnstableOptions,
     matches: &getopts::Matches,
-    error_format: ErrorOutputType,
 ) -> Vec<PrintRequest> {
     let mut prints = Vec::<PrintRequest>::new();
     if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
@@ -2028,8 +2008,7 @@ fn collect_print_requests(
                 if unstable_opts.unstable_options {
                     PrintRequest::TargetSpec
                 } else {
-                    early_error(
-                        error_format,
+                    handler.early_error(
                         "the `-Z unstable-options` flag must also be passed to \
                          enable the target-spec-json print option",
                     );
@@ -2039,8 +2018,7 @@ fn collect_print_requests(
                 if unstable_opts.unstable_options {
                     PrintRequest::AllTargetSpecs
                 } else {
-                    early_error(
-                        error_format,
+                    handler.early_error(
                         "the `-Z unstable-options` flag must also be passed to \
                          enable the all-target-specs-json print option",
                     );
@@ -2051,10 +2029,9 @@ fn collect_print_requests(
                 let prints =
                     PRINT_REQUESTS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
                 let prints = prints.join(", ");
-                early_error(
-                    error_format,
-                    format!("unknown print request `{req}`. Valid print requests are: {prints}"),
-                );
+                handler.early_error(format!(
+                    "unknown print request `{req}`. Valid print requests are: {prints}"
+                ));
             }
         }
     }));
@@ -2063,14 +2040,14 @@ fn collect_print_requests(
 }
 
 pub fn parse_target_triple(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
-    error_format: ErrorOutputType,
 ) -> TargetTriple {
     match matches.opt_str("target") {
         Some(target) if target.ends_with(".json") => {
             let path = Path::new(&target);
             TargetTriple::from_path(path).unwrap_or_else(|_| {
-                early_error(error_format, format!("target file {path:?} does not exist"))
+                handler.early_error(format!("target file {path:?} does not exist"))
             })
         }
         Some(target) => TargetTriple::TargetTriple(target),
@@ -2079,9 +2056,9 @@ pub fn parse_target_triple(
 }
 
 fn parse_opt_level(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
     cg: &CodegenOptions,
-    error_format: ErrorOutputType,
 ) -> OptLevel {
     // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
     // to use them interchangeably. However, because they're technically different flags,
@@ -2109,13 +2086,10 @@ fn parse_opt_level(
             "s" => OptLevel::Size,
             "z" => OptLevel::SizeMin,
             arg => {
-                early_error(
-                    error_format,
-                    format!(
-                        "optimization level needs to be \
+                handler.early_error(format!(
+                    "optimization level needs to be \
                             between 0-3, s or z (instead was `{arg}`)"
-                    ),
-                );
+                ));
             }
         }
     }
@@ -2135,23 +2109,23 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf
 }
 
 pub(crate) fn parse_assert_incr_state(
+    handler: &EarlyErrorHandler,
     opt_assertion: &Option<String>,
-    error_format: ErrorOutputType,
 ) -> Option<IncrementalStateAssertion> {
     match opt_assertion {
         Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
         Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
         Some(s) => {
-            early_error(error_format, format!("unexpected incremental state assertion value: {s}"))
+            handler.early_error(format!("unexpected incremental state assertion value: {s}"))
         }
         None => None,
     }
 }
 
 fn parse_native_lib_kind(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
     kind: &str,
-    error_format: ErrorOutputType,
 ) -> (NativeLibKind, Option<bool>) {
     let (kind, modifiers) = match kind.split_once(':') {
         None => (kind, None),
@@ -2169,35 +2143,31 @@ fn parse_native_lib_kind(
                 } else {
                     ", the `-Z unstable-options` flag must also be passed to use it"
                 };
-                early_error(error_format, format!("library kind `link-arg` is unstable{why}"))
+                handler.early_error(format!("library kind `link-arg` is unstable{why}"))
             }
             NativeLibKind::LinkArg
         }
-        _ => early_error(
-            error_format,
-            format!(
-                "unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
-            ),
-        ),
+        _ => handler.early_error(format!(
+            "unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
+        )),
     };
     match modifiers {
         None => (kind, None),
-        Some(modifiers) => parse_native_lib_modifiers(kind, modifiers, error_format, matches),
+        Some(modifiers) => parse_native_lib_modifiers(handler, kind, modifiers, matches),
     }
 }
 
 fn parse_native_lib_modifiers(
+    handler: &EarlyErrorHandler,
     mut kind: NativeLibKind,
     modifiers: &str,
-    error_format: ErrorOutputType,
     matches: &getopts::Matches,
 ) -> (NativeLibKind, Option<bool>) {
     let mut verbatim = None;
     for modifier in modifiers.split(',') {
         let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
             Some(m) => (m, modifier.starts_with('+')),
-            None => early_error(
-                error_format,
+            None => handler.early_error(
                 "invalid linking modifier syntax, expected '+' or '-' prefix \
                  before one of: bundle, verbatim, whole-archive, as-needed",
             ),
@@ -2210,21 +2180,20 @@ fn parse_native_lib_modifiers(
                 } else {
                     ", the `-Z unstable-options` flag must also be passed to use it"
                 };
-                early_error(error_format, format!("linking modifier `{modifier}` is unstable{why}"))
+                handler.early_error(format!("linking modifier `{modifier}` is unstable{why}"))
             }
         };
         let assign_modifier = |dst: &mut Option<bool>| {
             if dst.is_some() {
                 let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
-                early_error(error_format, msg)
+                handler.early_error(msg)
             } else {
                 *dst = Some(value);
             }
         };
         match (modifier, &mut kind) {
             ("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle),
-            ("bundle", _) => early_error(
-                error_format,
+            ("bundle", _) => handler.early_error(
                 "linking modifier `bundle` is only compatible with `static` linking kind",
             ),
 
@@ -2233,8 +2202,7 @@ fn parse_native_lib_modifiers(
             ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
                 assign_modifier(whole_archive)
             }
-            ("whole-archive", _) => early_error(
-                error_format,
+            ("whole-archive", _) => handler.early_error(
                 "linking modifier `whole-archive` is only compatible with `static` linking kind",
             ),
 
@@ -2243,28 +2211,24 @@ fn parse_native_lib_modifiers(
                 report_unstable_modifier();
                 assign_modifier(as_needed)
             }
-            ("as-needed", _) => early_error(
-                error_format,
+            ("as-needed", _) => handler.early_error(
                 "linking modifier `as-needed` is only compatible with \
                  `dylib` and `framework` linking kinds",
             ),
 
             // Note: this error also excludes the case with empty modifier
             // string, like `modifiers = ""`.
-            _ => early_error(
-                error_format,
-                format!(
-                    "unknown linking modifier `{modifier}`, expected one \
+            _ => handler.early_error(format!(
+                "unknown linking modifier `{modifier}`, expected one \
                      of: bundle, verbatim, whole-archive, as-needed"
-                ),
-            ),
+            )),
         }
     }
 
     (kind, verbatim)
 }
 
-fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<NativeLib> {
+fn parse_libs(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> Vec<NativeLib> {
     matches
         .opt_strs("l")
         .into_iter()
@@ -2278,7 +2242,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
             let (name, kind, verbatim) = match s.split_once('=') {
                 None => (s, NativeLibKind::Unspecified, None),
                 Some((kind, name)) => {
-                    let (kind, verbatim) = parse_native_lib_kind(matches, kind, error_format);
+                    let (kind, verbatim) = parse_native_lib_kind(handler, matches, kind);
                     (name.to_string(), kind, verbatim)
                 }
             };
@@ -2288,7 +2252,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
                 Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
             };
             if name.is_empty() {
-                early_error(error_format, "library name must not be empty");
+                handler.early_error("library name must not be empty");
             }
             NativeLib { name, new_name, kind, verbatim }
         })
@@ -2296,9 +2260,9 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
 }
 
 pub fn parse_externs(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
     unstable_opts: &UnstableOptions,
-    error_format: ErrorOutputType,
 ) -> Externs {
     let is_unstable_enabled = unstable_opts.unstable_options;
     let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
@@ -2362,8 +2326,7 @@ pub fn parse_externs(
         let mut force = false;
         if let Some(opts) = options {
             if !is_unstable_enabled {
-                early_error(
-                    error_format,
+                handler.early_error(
                     "the `-Z unstable-options` flag must also be passed to \
                      enable `--extern` options",
                 );
@@ -2375,15 +2338,14 @@ pub fn parse_externs(
                         if let ExternLocation::ExactPaths(_) = &entry.location {
                             add_prelude = false;
                         } else {
-                            early_error(
-                                error_format,
+                            handler.early_error(
                                 "the `noprelude` --extern option requires a file path",
                             );
                         }
                     }
                     "nounused" => nounused_dep = true,
                     "force" => force = true,
-                    _ => early_error(error_format, format!("unknown --extern option `{opt}`")),
+                    _ => handler.early_error(format!("unknown --extern option `{opt}`")),
                 }
             }
         }
@@ -2402,18 +2364,15 @@ pub fn parse_externs(
 }
 
 fn parse_remap_path_prefix(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
     unstable_opts: &UnstableOptions,
-    error_format: ErrorOutputType,
 ) -> Vec<(PathBuf, PathBuf)> {
     let mut mapping: Vec<(PathBuf, PathBuf)> = matches
         .opt_strs("remap-path-prefix")
         .into_iter()
         .map(|remap| match remap.rsplit_once('=') {
-            None => early_error(
-                error_format,
-                "--remap-path-prefix must contain '=' between FROM and TO",
-            ),
+            None => handler.early_error("--remap-path-prefix must contain '=' between FROM and TO"),
             Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
         })
         .collect();
@@ -2429,86 +2388,75 @@ fn parse_remap_path_prefix(
 
 // JUSTIFICATION: before wrapper fn is available
 #[allow(rustc::bad_opt_access)]
-pub fn build_session_options(matches: &getopts::Matches) -> Options {
-    let color = parse_color(matches);
+pub fn build_session_options(
+    handler: &mut EarlyErrorHandler,
+    matches: &getopts::Matches,
+) -> Options {
+    let color = parse_color(handler, matches);
 
-    let edition = parse_crate_edition(matches);
+    let edition = parse_crate_edition(handler, matches);
 
     let JsonConfig {
         json_rendered,
         json_artifact_notifications,
         json_unused_externs,
         json_future_incompat,
-    } = parse_json(matches);
+    } = parse_json(handler, matches);
 
-    let error_format = parse_error_format(matches, color, json_rendered);
+    let error_format = parse_error_format(handler, matches, color, json_rendered);
 
     let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
-        early_error(error_format, "`--diagnostic-width` must be an positive integer");
+        handler.early_error("`--diagnostic-width` must be an positive integer");
     });
 
     let unparsed_crate_types = matches.opt_strs("crate-type");
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
-        .unwrap_or_else(|e| early_error(error_format, e));
+        .unwrap_or_else(|e| handler.early_error(e));
 
-    let mut unstable_opts = UnstableOptions::build(matches, error_format);
-    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
+    let mut unstable_opts = UnstableOptions::build(handler, matches);
+    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(handler, matches);
 
-    check_error_format_stability(&unstable_opts, error_format, json_rendered);
+    check_error_format_stability(handler, &unstable_opts, error_format, json_rendered);
 
     if !unstable_opts.unstable_options && json_unused_externs.is_enabled() {
-        early_error(
-            error_format,
+        handler.early_error(
             "the `-Z unstable-options` flag must also be passed to enable \
             the flag `--json=unused-externs`",
         );
     }
 
-    let output_types = parse_output_types(&unstable_opts, matches, error_format);
+    let output_types = parse_output_types(handler, &unstable_opts, matches);
 
-    let mut cg = CodegenOptions::build(matches, error_format);
-    let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
-        &output_types,
-        matches,
-        error_format,
-        cg.codegen_units,
-    );
+    let mut cg = CodegenOptions::build(handler, matches);
+    let (disable_local_thinlto, mut codegen_units) =
+        should_override_cgus_and_disable_thinlto(handler, &output_types, matches, cg.codegen_units);
 
-    check_thread_count(&unstable_opts, error_format);
+    check_thread_count(handler, &unstable_opts);
 
     let incremental = cg.incremental.as_ref().map(PathBuf::from);
 
-    let assert_incr_state = parse_assert_incr_state(&unstable_opts.assert_incr_state, error_format);
+    let assert_incr_state = parse_assert_incr_state(handler, &unstable_opts.assert_incr_state);
 
     if unstable_opts.profile && incremental.is_some() {
-        early_error(
-            error_format,
-            "can't instrument with gcov profiling when compiling incrementally",
-        );
+        handler.early_error("can't instrument with gcov profiling when compiling incrementally");
     }
     if unstable_opts.profile {
         match codegen_units {
             Some(1) => {}
             None => codegen_units = Some(1),
-            Some(_) => early_error(
-                error_format,
-                "can't instrument with gcov profiling with multiple codegen units",
-            ),
+            Some(_) => handler
+                .early_error("can't instrument with gcov profiling with multiple codegen units"),
         }
     }
 
     if cg.profile_generate.enabled() && cg.profile_use.is_some() {
-        early_error(
-            error_format,
-            "options `-C profile-generate` and `-C profile-use` are exclusive",
-        );
+        handler.early_error("options `-C profile-generate` and `-C profile-use` are exclusive");
     }
 
     if unstable_opts.profile_sample_use.is_some()
         && (cg.profile_generate.enabled() || cg.profile_use.is_some())
     {
-        early_error(
-            error_format,
+        handler.early_error(
             "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
         );
     }
@@ -2517,23 +2465,19 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     // precedence.
     match (cg.symbol_mangling_version, unstable_opts.symbol_mangling_version) {
         (Some(smv_c), Some(smv_z)) if smv_c != smv_z => {
-            early_error(
-                error_format,
+            handler.early_error(
                 "incompatible values passed for `-C symbol-mangling-version` \
                 and `-Z symbol-mangling-version`",
             );
         }
         (Some(SymbolManglingVersion::V0), _) => {}
         (Some(_), _) if !unstable_opts.unstable_options => {
-            early_error(
-                error_format,
-                "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
-            );
+            handler
+                .early_error("`-C symbol-mangling-version=legacy` requires `-Z unstable-options`");
         }
         (None, None) => {}
         (None, smv) => {
-            early_warn(
-                error_format,
+            handler.early_warn(
                 "`-Z symbol-mangling-version` is deprecated; use `-C symbol-mangling-version`",
             );
             cg.symbol_mangling_version = smv;
@@ -2545,25 +2489,19 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     // precedence.
     match (cg.instrument_coverage, unstable_opts.instrument_coverage) {
         (Some(ic_c), Some(ic_z)) if ic_c != ic_z => {
-            early_error(
-                error_format,
+            handler.early_error(
                 "incompatible values passed for `-C instrument-coverage` \
                 and `-Z instrument-coverage`",
             );
         }
         (Some(InstrumentCoverage::Off | InstrumentCoverage::All), _) => {}
         (Some(_), _) if !unstable_opts.unstable_options => {
-            early_error(
-                error_format,
-                "`-C instrument-coverage=except-*` requires `-Z unstable-options`",
-            );
+            handler.early_error("`-C instrument-coverage=except-*` requires `-Z unstable-options`");
         }
         (None, None) => {}
         (None, ic) => {
-            early_warn(
-                error_format,
-                "`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`",
-            );
+            handler
+                .early_warn("`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`");
             cg.instrument_coverage = ic;
         }
         _ => {}
@@ -2571,8 +2509,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     if cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off) {
         if cg.profile_generate.enabled() || cg.profile_use.is_some() {
-            early_error(
-                error_format,
+            handler.early_error(
                 "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
                 or `-C profile-generate`",
             );
@@ -2585,8 +2522,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         match cg.symbol_mangling_version {
             None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
             Some(SymbolManglingVersion::Legacy) => {
-                early_warn(
-                    error_format,
+                handler.early_warn(
                     "-C instrument-coverage requires symbol mangling version `v0`, \
                     but `-C symbol-mangling-version=legacy` was specified",
                 );
@@ -2602,10 +2538,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     if !cg.embed_bitcode {
         match cg.lto {
             LtoCli::No | LtoCli::Unspecified => {}
-            LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => early_error(
-                error_format,
-                "options `-C embed-bitcode=no` and `-C lto` are incompatible",
-            ),
+            LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
+                handler.early_error("options `-C embed-bitcode=no` and `-C lto` are incompatible")
+            }
         }
     }
 
@@ -2618,17 +2553,17 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                  flag must also be passed to explicitly use it",
                 flavor.desc()
             );
-            early_error(error_format, msg);
+            handler.early_error(msg);
         }
     }
 
-    let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format);
+    let prints = collect_print_requests(handler, &mut cg, &mut unstable_opts, matches);
 
     let cg = cg;
 
     let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
-    let target_triple = parse_target_triple(matches, error_format);
-    let opt_level = parse_opt_level(matches, &cg, error_format);
+    let target_triple = parse_target_triple(handler, matches);
+    let opt_level = parse_opt_level(handler, matches, &cg);
     // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
     // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
     // for more details.
@@ -2637,28 +2572,28 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut search_paths = vec![];
     for s in &matches.opt_strs("L") {
-        search_paths.push(SearchPath::from_cli_opt(s, error_format));
+        search_paths.push(SearchPath::from_cli_opt(handler, s));
     }
 
-    let libs = parse_libs(matches, error_format);
+    let libs = parse_libs(handler, matches);
 
     let test = matches.opt_present("test");
 
     if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
-        early_warn(error_format, "-C remark requires \"-C debuginfo=n\" to show source locations");
+        handler.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
     }
 
-    let externs = parse_externs(matches, &unstable_opts, error_format);
+    let externs = parse_externs(handler, matches, &unstable_opts);
 
     let crate_name = matches.opt_str("crate-name");
 
-    let remap_path_prefix = parse_remap_path_prefix(matches, &unstable_opts, error_format);
+    let remap_path_prefix = parse_remap_path_prefix(handler, matches, &unstable_opts);
 
-    let pretty = parse_pretty(&unstable_opts, error_format);
+    let pretty = parse_pretty(handler, &unstable_opts);
 
     // query-dep-graph is required if dump-dep-graph is given #106736
     if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
-        early_error(error_format, "can't dump dependency graph without `-Z query-dep-graph`");
+        handler.early_error("can't dump dependency graph without `-Z query-dep-graph`");
     }
 
     // Try to find a directory containing the Rust `src`, for more details see
@@ -2690,7 +2625,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     };
 
     let working_dir = std::env::current_dir().unwrap_or_else(|e| {
-        early_error(error_format, format!("Current directory is invalid: {e}"));
+        handler.early_error(format!("Current directory is invalid: {e}"));
     });
 
     let remap = FilePathMapping::new(remap_path_prefix.clone());
@@ -2741,7 +2676,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     }
 }
 
-fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Option<PpMode> {
+fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) -> Option<PpMode> {
     use PpMode::*;
 
     let first = match unstable_opts.unpretty.as_deref()? {
@@ -2760,16 +2695,13 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
         "thir-flat" => ThirFlat,
         "mir" => Mir,
         "mir-cfg" => MirCFG,
-        name => early_error(
-            efmt,
-            format!(
-                "argument to `unpretty` must be one of `normal`, `identified`, \
+        name => handler.early_error(format!(
+            "argument to `unpretty` must be one of `normal`, `identified`, \
                             `expanded`, `expanded,identified`, `expanded,hygiene`, \
                             `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
                             `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir` or \
                             `mir-cfg`; got {name}"
-            ),
-        ),
+        )),
     };
     debug!("got unpretty option: {first:?}");
     Some(first)
@@ -2809,8 +2741,8 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
 }
 
 pub mod nightly_options {
-    use super::{ErrorOutputType, OptionStability, RustcOptGroup};
-    use crate::early_error;
+    use super::{OptionStability, RustcOptGroup};
+    use crate::EarlyErrorHandler;
     use rustc_feature::UnstableFeatures;
 
     pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
@@ -2826,7 +2758,11 @@ pub mod nightly_options {
         UnstableFeatures::from_environment(krate).is_nightly_build()
     }
 
-    pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
+    pub fn check_nightly_options(
+        handler: &EarlyErrorHandler,
+        matches: &getopts::Matches,
+        flags: &[RustcOptGroup],
+    ) {
         let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
         let really_allows_unstable_options = match_is_nightly_build(matches);
 
@@ -2838,14 +2774,11 @@ pub mod nightly_options {
                 continue;
             }
             if opt.name != "Z" && !has_z_unstable_option {
-                early_error(
-                    ErrorOutputType::default(),
-                    format!(
-                        "the `-Z unstable-options` flag must also be passed to enable \
+                handler.early_error(format!(
+                    "the `-Z unstable-options` flag must also be passed to enable \
                          the flag `{}`",
-                        opt.name
-                    ),
-                );
+                    opt.name
+                ));
             }
             if really_allows_unstable_options {
                 continue;
@@ -2856,7 +2789,12 @@ pub mod nightly_options {
                         "the option `{}` is only accepted on the nightly compiler",
                         opt.name
                     );
-                    early_error(ErrorOutputType::default(), msg);
+                    let _ = handler.early_error_no_abort(msg);
+                    handler.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
+                    handler.early_help(
+                        "consider switching to a nightly toolchain: `rustup default nightly`",
+                    );
+                    handler.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
                 }
                 OptionStability::Stable => {}
             }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 270d833160250..e5063eef47af5 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1,9 +1,8 @@
 use crate::config::*;
 
-use crate::early_error;
-use crate::lint;
 use crate::search_paths::SearchPath;
 use crate::utils::NativeLib;
+use crate::{lint, EarlyErrorHandler};
 use rustc_data_structures::profiling::TimePassesFormat;
 use rustc_errors::{LanguageIdentifier, TerminalUrl};
 use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
@@ -245,10 +244,10 @@ macro_rules! options {
 
     impl $struct_name {
         pub fn build(
+            handler: &EarlyErrorHandler,
             matches: &getopts::Matches,
-            error_format: ErrorOutputType,
         ) -> $struct_name {
-            build_options(matches, $stat, $prefix, $outputname, error_format)
+            build_options(handler, matches, $stat, $prefix, $outputname)
         }
 
         fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> u64 {
@@ -309,11 +308,11 @@ type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool;
 type OptionDescrs<O> = &'static [(&'static str, OptionSetter<O>, &'static str, &'static str)];
 
 fn build_options<O: Default>(
+    handler: &EarlyErrorHandler,
     matches: &getopts::Matches,
     descrs: OptionDescrs<O>,
     prefix: &str,
     outputname: &str,
-    error_format: ErrorOutputType,
 ) -> O {
     let mut op = O::default();
     for option in matches.opt_strs(prefix) {
@@ -327,15 +326,13 @@ fn build_options<O: Default>(
             Some((_, setter, type_desc, _)) => {
                 if !setter(&mut op, value) {
                     match value {
-                        None => early_error(
-                            error_format,
+                        None => handler.early_error(
                             format!(
                                 "{0} option `{1}` requires {2} ({3} {1}=<value>)",
                                 outputname, key, type_desc, prefix
                             ),
                         ),
-                        Some(value) => early_error(
-                            error_format,
+                        Some(value) => handler.early_error(
                             format!(
                                 "incorrect value `{value}` for {outputname} option `{key}` - {type_desc} was expected"
                             ),
@@ -343,7 +340,7 @@ fn build_options<O: Default>(
                     }
                 }
             }
-            None => early_error(error_format, format!("unknown {outputname} option: `{key}`")),
+            None => handler.early_error(format!("unknown {outputname} option: `{key}`")),
         }
     }
     return op;
diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index 56a6b6f3b03ef..07e78d1760e80 100644
--- a/compiler/rustc_session/src/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
@@ -1,5 +1,5 @@
 use crate::filesearch::make_target_lib_path;
-use crate::{config, early_error};
+use crate::EarlyErrorHandler;
 use std::path::{Path, PathBuf};
 
 #[derive(Clone, Debug)]
@@ -46,7 +46,7 @@ impl PathKind {
 }
 
 impl SearchPath {
-    pub fn from_cli_opt(path: &str, output: config::ErrorOutputType) -> Self {
+    pub fn from_cli_opt(handler: &EarlyErrorHandler, path: &str) -> Self {
         let (kind, path) = if let Some(stripped) = path.strip_prefix("native=") {
             (PathKind::Native, stripped)
         } else if let Some(stripped) = path.strip_prefix("crate=") {
@@ -61,7 +61,7 @@ impl SearchPath {
             (PathKind::All, path)
         };
         if path.is_empty() {
-            early_error(output, "empty search path given via `-L`");
+            handler.early_error("empty search path given via `-L`");
         }
 
         let dir = PathBuf::from(path);
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index ea5beb6f8bebf..5be122ffbdeb0 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1,10 +1,10 @@
 use crate::cgu_reuse_tracker::CguReuseTracker;
 use crate::code_stats::CodeStats;
 pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
-use crate::config::Input;
 use crate::config::{
     self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath,
 };
+use crate::config::{ErrorOutputType, Input};
 use crate::errors;
 use crate::parse::{add_feature_diagnostics, ParseSess};
 use crate::search_paths::{PathKind, SearchPath};
@@ -25,7 +25,7 @@ use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
 use rustc_errors::{
     error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
-    ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
+    ErrorGuaranteed, FluentBundle, Handler, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
     TerminalUrl,
 };
 use rustc_macros::HashStable_Generic;
@@ -1382,6 +1382,7 @@ fn default_emitter(
 // JUSTIFICATION: literally session construction
 #[allow(rustc::bad_opt_access)]
 pub fn build_session(
+    handler: &EarlyErrorHandler,
     sopts: config::Options,
     io: CompilerIO,
     bundle: Option<Lrc<rustc_errors::FluentBundle>>,
@@ -1408,13 +1409,12 @@ pub fn build_session(
         None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
     };
 
-    let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
+    let target_cfg = config::build_target_config(handler, &sopts, target_override, &sysroot);
     let host_triple = TargetTriple::from_triple(config::host_triple());
-    let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
-        early_error(sopts.error_format, format!("Error loading host specification: {e}"))
-    });
+    let (host, target_warnings) = Target::search(&host_triple, &sysroot)
+        .unwrap_or_else(|e| handler.early_error(format!("Error loading host specification: {e}")));
     for warning in target_warnings.warning_messages() {
-        early_warn(sopts.error_format, warning)
+        handler.early_warn(warning)
     }
 
     let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
@@ -1456,7 +1456,7 @@ pub fn build_session(
         match profiler {
             Ok(profiler) => Some(Arc::new(profiler)),
             Err(e) => {
-                early_warn(sopts.error_format, format!("failed to create profiler: {e}"));
+                handler.early_warn(format!("failed to create profiler: {e}"));
                 None
             }
         }
@@ -1723,7 +1723,64 @@ pub enum IncrCompSession {
     InvalidBecauseOfErrors { session_directory: PathBuf },
 }
 
-fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler {
+/// A wrapper around an [`Handler`] that is used for early error emissions.
+pub struct EarlyErrorHandler {
+    handler: Handler,
+}
+
+impl EarlyErrorHandler {
+    pub fn new(output: ErrorOutputType) -> Self {
+        let emitter = mk_emitter(output);
+        Self { handler: rustc_errors::Handler::with_emitter(true, None, emitter) }
+    }
+
+    pub fn abort_if_errors(&self) {
+        self.handler.abort_if_errors()
+    }
+
+    /// Swap out the underlying handler once we acquire the user's preference on error emission
+    /// format. Any errors prior to that will cause an abort and all stashed diagnostics of the
+    /// previous handler will be emitted.
+    pub fn abort_if_error_and_set_error_format(&mut self, output: ErrorOutputType) {
+        self.handler.abort_if_errors();
+
+        let emitter = mk_emitter(output);
+        self.handler = Handler::with_emitter(true, None, emitter);
+    }
+
+    #[allow(rustc::untranslatable_diagnostic)]
+    #[allow(rustc::diagnostic_outside_of_impl)]
+    pub fn early_note(&self, msg: impl Into<DiagnosticMessage>) {
+        self.handler.struct_note_without_error(msg).emit()
+    }
+
+    #[allow(rustc::untranslatable_diagnostic)]
+    #[allow(rustc::diagnostic_outside_of_impl)]
+    pub fn early_help(&self, msg: impl Into<DiagnosticMessage>) {
+        self.handler.struct_help(msg).emit()
+    }
+
+    #[allow(rustc::untranslatable_diagnostic)]
+    #[allow(rustc::diagnostic_outside_of_impl)]
+    #[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"]
+    pub fn early_error_no_abort(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
+        self.handler.struct_err(msg).emit()
+    }
+
+    #[allow(rustc::untranslatable_diagnostic)]
+    #[allow(rustc::diagnostic_outside_of_impl)]
+    pub fn early_error(&self, msg: impl Into<DiagnosticMessage>) -> ! {
+        self.handler.struct_fatal(msg).emit()
+    }
+
+    #[allow(rustc::untranslatable_diagnostic)]
+    #[allow(rustc::diagnostic_outside_of_impl)]
+    pub fn early_warn(&self, msg: impl Into<DiagnosticMessage>) {
+        self.handler.struct_warn(msg).emit()
+    }
+}
+
+fn mk_emitter(output: ErrorOutputType) -> Box<dyn Emitter + sync::Send + 'static> {
     // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will
     // need to reference every crate that might emit an early error for translation to work.
     let fallback_bundle =
@@ -1755,27 +1812,5 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
             TerminalUrl::No,
         )),
     };
-    rustc_errors::Handler::with_emitter(true, None, emitter)
-}
-
-#[allow(rustc::untranslatable_diagnostic)]
-#[allow(rustc::diagnostic_outside_of_impl)]
-#[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"]
-pub fn early_error_no_abort(
-    output: config::ErrorOutputType,
-    msg: impl Into<DiagnosticMessage>,
-) -> ErrorGuaranteed {
-    early_error_handler(output).struct_err(msg).emit()
-}
-
-#[allow(rustc::untranslatable_diagnostic)]
-#[allow(rustc::diagnostic_outside_of_impl)]
-pub fn early_error(output: config::ErrorOutputType, msg: impl Into<DiagnosticMessage>) -> ! {
-    early_error_handler(output).struct_fatal(msg).emit()
-}
-
-#[allow(rustc::untranslatable_diagnostic)]
-#[allow(rustc::diagnostic_outside_of_impl)]
-pub fn early_warn(output: config::ErrorOutputType, msg: impl Into<DiagnosticMessage>) {
-    early_error_handler(output).struct_warn(msg).emit()
+    emitter
 }
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 9f08609a6d1a6..217f1a6ee6b66 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -15,6 +15,7 @@ use rustc_session::config::{
 use rustc_session::getopts;
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
+use rustc_session::EarlyErrorHandler;
 use rustc_span::edition::Edition;
 use rustc_target::spec::TargetTriple;
 
@@ -311,32 +312,33 @@ impl Options {
     /// Parses the given command-line for options. If an error message or other early-return has
     /// been printed, returns `Err` with the exit code.
     pub(crate) fn from_matches(
+        handler: &mut EarlyErrorHandler,
         matches: &getopts::Matches,
         args: Vec<String>,
     ) -> Result<(Options, RenderOptions), i32> {
         // Check for unstable options.
-        nightly_options::check_nightly_options(matches, &opts());
+        nightly_options::check_nightly_options(handler, matches, &opts());
 
         if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
             crate::usage("rustdoc");
             return Err(0);
         } else if matches.opt_present("version") {
-            rustc_driver::version!("rustdoc", matches);
+            rustc_driver::version!(&handler, "rustdoc", matches);
             return Err(0);
         }
 
-        if rustc_driver::describe_flag_categories(&matches) {
+        if rustc_driver::describe_flag_categories(handler, &matches) {
             return Err(0);
         }
 
-        let color = config::parse_color(matches);
+        let color = config::parse_color(handler, matches);
         let config::JsonConfig { json_rendered, json_unused_externs, .. } =
-            config::parse_json(matches);
-        let error_format = config::parse_error_format(matches, color, json_rendered);
+            config::parse_json(handler, matches);
+        let error_format = config::parse_error_format(handler, matches, color, json_rendered);
         let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();
 
-        let codegen_options = CodegenOptions::build(matches, error_format);
-        let unstable_opts = UnstableOptions::build(matches, error_format);
+        let codegen_options = CodegenOptions::build(handler, matches);
+        let unstable_opts = UnstableOptions::build(handler, matches);
 
         let diag = new_handler(error_format, None, diagnostic_width, &unstable_opts);
 
@@ -393,8 +395,7 @@ impl Options {
             && !matches.opt_present("show-coverage")
             && !nightly_options::is_unstable_enabled(matches)
         {
-            rustc_session::early_error(
-                error_format,
+            handler.early_error(
                 "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
             );
         }
@@ -432,7 +433,7 @@ impl Options {
             return Err(0);
         }
 
-        let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
+        let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(handler, matches);
 
         let input = PathBuf::from(if describe_lints {
             "" // dummy, this won't be used
@@ -446,12 +447,9 @@ impl Options {
             &matches.free[0]
         });
 
-        let libs = matches
-            .opt_strs("L")
-            .iter()
-            .map(|s| SearchPath::from_cli_opt(s, error_format))
-            .collect();
-        let externs = parse_externs(matches, &unstable_opts, error_format);
+        let libs =
+            matches.opt_strs("L").iter().map(|s| SearchPath::from_cli_opt(handler, s)).collect();
+        let externs = parse_externs(handler, matches, &unstable_opts);
         let extern_html_root_urls = match parse_extern_html_roots(matches) {
             Ok(ex) => ex,
             Err(err) => {
@@ -589,7 +587,7 @@ impl Options {
             }
         }
 
-        let edition = config::parse_crate_edition(matches);
+        let edition = config::parse_crate_edition(handler, matches);
 
         let mut id_map = html::markdown::IdMap::new();
         let Some(external_html) = ExternalHtml::load(
@@ -623,7 +621,7 @@ impl Options {
             }
         }
 
-        let target = parse_target_triple(matches, error_format);
+        let target = parse_target_triple(handler, matches);
 
         let show_coverage = matches.opt_present("show-coverage");
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index e10a629777526..9687b8b18878e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -13,8 +13,8 @@ use rustc_interface::interface;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
 use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks};
-use rustc_session::lint;
 use rustc_session::Session;
+use rustc_session::{lint, EarlyErrorHandler};
 use rustc_span::symbol::sym;
 use rustc_span::{source_map, Span};
 
@@ -181,6 +181,7 @@ pub(crate) fn new_handler(
 
 /// Parse, resolve, and typecheck the given crate.
 pub(crate) fn create_config(
+    handler: &EarlyErrorHandler,
     RustdocOptions {
         input,
         crate_name,
@@ -258,8 +259,8 @@ pub(crate) fn create_config(
 
     interface::Config {
         opts: sessopts,
-        crate_cfg: interface::parse_cfgspecs(cfgs),
-        crate_check_cfg: interface::parse_check_cfg(check_cfgs),
+        crate_cfg: interface::parse_cfgspecs(handler, cfgs),
+        crate_check_cfg: interface::parse_check_cfg(handler, check_cfgs),
         input,
         output_file: None,
         output_dir: None,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index f6631b66f5b65..217257316c84f 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -12,7 +12,7 @@ use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_parse::parser::attr::InnerAttrPolicy;
 use rustc_session::config::{self, CrateType, ErrorOutputType};
 use rustc_session::parse::ParseSess;
-use rustc_session::{lint, Session};
+use rustc_session::{lint, EarlyErrorHandler, Session};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::sym;
@@ -85,13 +85,18 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
         ..config::Options::default()
     };
 
+    let early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
     let mut cfgs = options.cfgs.clone();
     cfgs.push("doc".to_owned());
     cfgs.push("doctest".to_owned());
     let config = interface::Config {
         opts: sessopts,
-        crate_cfg: interface::parse_cfgspecs(cfgs),
-        crate_check_cfg: interface::parse_check_cfg(options.check_cfgs.clone()),
+        crate_cfg: interface::parse_cfgspecs(&early_error_handler, cfgs),
+        crate_check_cfg: interface::parse_check_cfg(
+            &early_error_handler,
+            options.check_cfgs.clone(),
+        ),
         input,
         output_file: None,
         output_dir: None,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index a8cd0ec453ed7..f28deae791a41 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -79,8 +79,7 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_interface::interface;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
-use rustc_session::getopts;
-use rustc_session::{early_error, early_warn};
+use rustc_session::{getopts, EarlyErrorHandler};
 
 use crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL;
 
@@ -155,6 +154,8 @@ pub fn main() {
         }
     }
 
+    let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
     rustc_driver::install_ice_hook(
         "https://github.com/rust-lang/rust/issues/new\
     ?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md",
@@ -170,11 +171,12 @@ pub fn main() {
     // NOTE: The reason this doesn't show double logging when `download-rustc = false` and
     // `debug_logging = true` is because all rustc logging goes to its version of tracing (the one
     // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml).
-    init_logging();
-    rustc_driver::init_env_logger("RUSTDOC_LOG");
 
-    let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() {
-        Some(args) => main_args(&args),
+    init_logging(&handler);
+    rustc_driver::init_env_logger(&handler, "RUSTDOC_LOG");
+
+    let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&handler) {
+        Some(args) => main_args(&mut handler, &args),
         _ =>
         {
             #[allow(deprecated)]
@@ -184,22 +186,19 @@ pub fn main() {
     process::exit(exit_code);
 }
 
-fn init_logging() {
+fn init_logging(handler: &EarlyErrorHandler) {
     let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
         Ok("always") => true,
         Ok("never") => false,
         Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
-        Ok(value) => early_error(
-            ErrorOutputType::default(),
-            format!("invalid log color value '{}': expected one of always, never, or auto", value),
-        ),
-        Err(VarError::NotUnicode(value)) => early_error(
-            ErrorOutputType::default(),
-            format!(
-                "invalid log color value '{}': expected one of always, never, or auto",
-                value.to_string_lossy()
-            ),
-        ),
+        Ok(value) => handler.early_error(format!(
+            "invalid log color value '{}': expected one of always, never, or auto",
+            value
+        )),
+        Err(VarError::NotUnicode(value)) => handler.early_error(format!(
+            "invalid log color value '{}': expected one of always, never, or auto",
+            value.to_string_lossy()
+        )),
     };
     let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG");
     let layer = tracing_tree::HierarchicalLayer::default()
@@ -219,16 +218,13 @@ fn init_logging() {
     tracing::subscriber::set_global_default(subscriber).unwrap();
 }
 
-fn get_args() -> Option<Vec<String>> {
+fn get_args(handler: &EarlyErrorHandler) -> Option<Vec<String>> {
     env::args_os()
         .enumerate()
         .map(|(i, arg)| {
             arg.into_string()
                 .map_err(|arg| {
-                    early_warn(
-                        ErrorOutputType::default(),
-                        format!("Argument {} is not valid Unicode: {:?}", i, arg),
-                    );
+                    handler.early_warn(format!("Argument {} is not valid Unicode: {:?}", i, arg));
                 })
                 .ok()
         })
@@ -710,7 +706,7 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
     }
 }
 
-fn main_args(at_args: &[String]) -> MainResult {
+fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult {
     // Throw away the first argument, the name of the binary.
     // In case of at_args being empty, as might be the case by
     // passing empty argument array to execve under some platforms,
@@ -721,7 +717,7 @@ fn main_args(at_args: &[String]) -> MainResult {
     // the compiler with @empty_file as argv[0] and no more arguments.
     let at_args = at_args.get(1..).unwrap_or_default();
 
-    let args = rustc_driver::args::arg_expand_all(at_args);
+    let args = rustc_driver::args::arg_expand_all(handler, at_args);
 
     let mut options = getopts::Options::new();
     for option in opts() {
@@ -730,13 +726,13 @@ fn main_args(at_args: &[String]) -> MainResult {
     let matches = match options.parse(&args) {
         Ok(m) => m,
         Err(err) => {
-            early_error(ErrorOutputType::default(), err.to_string());
+            handler.early_error(err.to_string());
         }
     };
 
     // Note that we discard any distinction between different non-zero exit
     // codes from `from_matches` here.
-    let (options, render_options) = match config::Options::from_matches(&matches, args) {
+    let (options, render_options) = match config::Options::from_matches(handler, &matches, args) {
         Ok(opts) => opts,
         Err(code) => {
             return if code == 0 {
@@ -764,7 +760,7 @@ fn main_args(at_args: &[String]) -> MainResult {
         (false, true) => {
             let input = options.input.clone();
             let edition = options.edition;
-            let config = core::create_config(options, &render_options);
+            let config = core::create_config(handler, options, &render_options);
 
             // `markdown::render` can invoke `doctest::make_test`, which
             // requires session globals and a thread pool, so we use
@@ -797,7 +793,7 @@ fn main_args(at_args: &[String]) -> MainResult {
     let scrape_examples_options = options.scrape_examples_options.clone();
     let bin_crate = options.bin_crate;
 
-    let config = core::create_config(options, &render_options);
+    let config = core::create_config(handler, options, &render_options);
 
     interface::run_compiler(config, |compiler| {
         let sess = compiler.session();
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 3c5b6e12b9688..f3cc94aeff01c 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -16,6 +16,8 @@ extern crate rustc_session;
 extern crate rustc_span;
 
 use rustc_interface::interface;
+use rustc_session::EarlyErrorHandler;
+use rustc_session::config::ErrorOutputType;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::Symbol;
 
@@ -187,7 +189,9 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne
 
 #[allow(clippy::too_many_lines)]
 pub fn main() {
-    rustc_driver::init_rustc_env_logger();
+    let handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
+    rustc_driver::init_rustc_env_logger(&handler);
 
     rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| {
         // FIXME: this macro calls unwrap internally but is called in a panicking context!  It's not
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index f984275b164cc..62a58576da555 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -1,6 +1,7 @@
 #![feature(rustc_private)]
 
 extern crate rustc_driver;
+extern crate rustc_session;
 
 use std::env;
 use std::error::Error;
@@ -170,7 +171,9 @@ fn parse_args() -> (OutputFormat, PathBuf) {
 }
 
 fn main() {
-    rustc_driver::init_env_logger("RUST_LOG");
+    let handler =
+        rustc_session::EarlyErrorHandler::new(rustc_session::config::ErrorOutputType::default());
+    rustc_driver::init_env_logger(&handler, "RUST_LOG");
     let (format, dst) = parse_args();
     let result = main_with_result(format, &dst);
     if let Err(e) = result {
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 083dd4800d93e..219617b1d6858 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -31,9 +31,9 @@ use rustc_middle::{
     query::{ExternProviders, LocalCrate},
     ty::TyCtxt,
 };
-use rustc_session::config::OptLevel;
-
-use rustc_session::{config::CrateType, search_paths::PathKind, CtfeBacktrace};
+use rustc_session::{EarlyErrorHandler, CtfeBacktrace};
+use rustc_session::config::{OptLevel, CrateType, ErrorOutputType};
+use rustc_session::search_paths::PathKind;
 
 use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};
 
@@ -59,6 +59,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
 
     fn after_analysis<'tcx>(
         &mut self,
+        handler: &EarlyErrorHandler,
         _: &rustc_interface::interface::Compiler,
         queries: &'tcx rustc_interface::Queries<'tcx>,
     ) -> Compilation {
@@ -66,8 +67,8 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
             if tcx.sess.compile_status().is_err() {
                 tcx.sess.fatal("miri cannot be run on programs that fail compilation");
             }
-
-            init_late_loggers(tcx);
+;
+            init_late_loggers(handler, tcx);
             if !tcx.sess.crate_types().contains(&CrateType::Executable) {
                 tcx.sess.fatal("miri only makes sense on bin crates");
             }
@@ -181,7 +182,7 @@ macro_rules! show_error {
     ($($tt:tt)*) => { show_error(&format_args!($($tt)*)) };
 }
 
-fn init_early_loggers() {
+fn init_early_loggers(handler: &EarlyErrorHandler) {
     // Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to
     // initialize them both, and we always initialize `miri`'s first.
     let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
@@ -195,11 +196,11 @@ fn init_early_loggers() {
     // later with our custom settings, and *not* log anything for what happens before
     // `miri` gets started.
     if env::var_os("RUSTC_LOG").is_some() {
-        rustc_driver::init_rustc_env_logger();
+        rustc_driver::init_rustc_env_logger(handler);
     }
 }
 
-fn init_late_loggers(tcx: TyCtxt<'_>) {
+fn init_late_loggers(handler: &EarlyErrorHandler, tcx: TyCtxt<'_>) {
     // We initialize loggers right before we start evaluation. We overwrite the `RUSTC_LOG`
     // env var if it is not set, control it based on `MIRI_LOG`.
     // (FIXME: use `var_os`, but then we need to manually concatenate instead of `format!`.)
@@ -218,7 +219,7 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
             } else {
                 env::set_var("RUSTC_LOG", &var);
             }
-            rustc_driver::init_rustc_env_logger();
+            rustc_driver::init_rustc_env_logger(handler);
         }
     }
 
@@ -284,6 +285,8 @@ fn parse_comma_list<T: FromStr>(input: &str) -> Result<Vec<T>, T::Err> {
 }
 
 fn main() {
+    let handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
     // Snapshot a copy of the environment before `rustc` starts messing with it.
     // (`install_ice_hook` might change `RUST_BACKTRACE`.)
     let env_snapshot = env::vars_os().collect::<Vec<_>>();
@@ -292,7 +295,7 @@ fn main() {
     if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
         // Earliest rustc setup.
         rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ());
-        rustc_driver::init_rustc_env_logger();
+        rustc_driver::init_rustc_env_logger(&handler);
 
         let target_crate = if crate_kind == "target" {
             true
@@ -314,7 +317,7 @@ fn main() {
     rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| ());
 
     // Init loggers the Miri way.
-    init_early_loggers();
+    init_early_loggers(&handler);
 
     // Parse our arguments and split them across `rustc` and `miri`.
     let mut miri_config = miri::MiriConfig::default();
diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs
index b59a65a713f95..04c551cf4bb6c 100644
--- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs
+++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs
@@ -27,7 +27,7 @@ use rustc_interface::{Config, Queries};
 use rustc_middle::query::queries::mir_borrowck::ProvidedValue;
 use rustc_middle::query::{ExternProviders, Providers};
 use rustc_middle::ty::TyCtxt;
-use rustc_session::Session;
+use rustc_session::{Session, EarlyErrorHandler};
 use std::cell::RefCell;
 use std::collections::HashMap;
 use std::thread_local;
@@ -58,6 +58,7 @@ impl rustc_driver::Callbacks for CompilerCalls {
     // the result.
     fn after_analysis<'tcx>(
         &mut self,
+        _handler: &EarlyErrorHandler,
         compiler: &Compiler,
         queries: &'tcx Queries<'tcx>,
     ) -> Compilation {
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index a3db2e9ef24c4..9ef208a14b223 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -12,12 +12,14 @@ extern crate rustc_driver;
 extern crate rustc_hir;
 extern crate rustc_interface;
 extern crate rustc_middle;
+extern crate rustc_session;
 extern crate rustc_smir;
 
 use rustc_driver::{Callbacks, Compilation, RunCompiler};
 use rustc_hir::def::DefKind;
 use rustc_interface::{interface, Queries};
 use rustc_middle::ty::TyCtxt;
+use rustc_session::EarlyErrorHandler;
 use rustc_smir::{rustc_internal, stable_mir};
 use std::io::Write;
 
@@ -121,6 +123,7 @@ impl Callbacks for SMirCalls {
     /// continue the compilation afterwards (defaults to `Compilation::Continue`)
     fn after_analysis<'tcx>(
         &mut self,
+        _handler: &EarlyErrorHandler,
         _compiler: &interface::Compiler,
         queries: &'tcx Queries<'tcx>,
     ) -> Compilation {

From 6f3f8783517f939c1646eecc705872b7f18fe353 Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Tue, 27 Jun 2023 16:56:58 +0000
Subject: [PATCH 11/11] Normalize types when applying uninhabited predicate.

---
 .../ty/inhabitedness/inhabited_predicate.rs   | 13 +++++++-
 tests/ui/uninhabited/projection.rs            | 32 +++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)
 create mode 100644 tests/ui/uninhabited/projection.rs

diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index d48672b2baaee..018fa22715403 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -62,7 +62,18 @@ impl<'tcx> InhabitedPredicate<'tcx> {
                 Some(1..) => Ok(false),
             },
             Self::NotInModule(id) => in_module(id).map(|in_mod| !in_mod),
-            Self::GenericType(_) => Ok(true),
+            // `t` may be a projection, for which `inhabited_predicate` returns a `GenericType`. As
+            // we have a param_env available, we can do better.
+            Self::GenericType(t) => {
+                let normalized_pred = tcx
+                    .try_normalize_erasing_regions(param_env, t)
+                    .map_or(self, |t| t.inhabited_predicate(tcx));
+                match normalized_pred {
+                    // We don't have more information than we started with, so consider inhabited.
+                    Self::GenericType(_) => Ok(true),
+                    pred => pred.apply_inner(tcx, param_env, in_module),
+                }
+            }
             Self::And([a, b]) => try_and(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
             Self::Or([a, b]) => try_or(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
         }
diff --git a/tests/ui/uninhabited/projection.rs b/tests/ui/uninhabited/projection.rs
new file mode 100644
index 0000000000000..be0d3ff7da78f
--- /dev/null
+++ b/tests/ui/uninhabited/projection.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+#![feature(never_type, exhaustive_patterns)]
+
+trait Tag {
+    type TagType;
+}
+
+enum Keep {}
+enum Erase {}
+
+impl Tag for Keep {
+    type TagType = ();
+}
+
+impl Tag for Erase {
+    type TagType = !;
+}
+
+enum TagInt<T: Tag> {
+    Untagged(i32),
+    Tagged(T::TagType, i32)
+}
+
+fn test(keep: TagInt<Keep>, erase: TagInt<Erase>) {
+    match erase {
+        TagInt::Untagged(_) => (),
+        TagInt::Tagged(_, _) => ()
+    };
+}
+
+fn main() {}