From b4ca582b8986c36d23726dc292c41b06fe7f9c6b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Feb 2024 18:51:22 +0100
Subject: [PATCH 1/8] rename 'try' intrinsic to 'catch_unwind'

---
 .../src/intrinsics/mod.rs                     |  4 +--
 .../rustc_codegen_gcc/src/intrinsic/mod.rs    |  4 +--
 compiler/rustc_codegen_llvm/src/intrinsic.rs  |  8 +++---
 .../rustc_hir_analysis/src/check/intrinsic.rs |  4 +--
 compiler/rustc_span/src/symbol.rs             |  1 +
 library/core/src/intrinsics.rs                | 25 +++++++++++++------
 library/std/src/panicking.rs                  |  8 +++---
 src/tools/miri/src/shims/intrinsics/mod.rs    |  2 +-
 src/tools/miri/src/shims/panic.rs             |  2 +-
 .../fail/function_calls/check_callback_abi.rs |  2 +-
 .../function_calls/check_callback_abi.stderr  |  2 +-
 .../pass/function_calls/disable_abi_check.rs  |  2 +-
 tests/assembly/wasm_exceptions.rs             |  2 +-
 tests/codegen/wasm_exceptions.rs              |  2 +-
 .../run-make/wasm-exceptions-nostd/src/lib.rs |  2 +-
 .../interior-mutability.stderr                |  2 +-
 16 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 199d5df29e7d0..84269ec294263 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{sym, Symbol};
 
 pub(crate) use self::llvm::codegen_llvm_intrinsic_call;
 use crate::prelude::*;
@@ -1132,7 +1132,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             ret.write_cvalue(fx, val);
         }
 
-        kw::Try => {
+        sym::catch_unwind => {
             intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic);
             let f = f.load_scalar(fx);
             let data = data.load_scalar(fx);
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index f162ef831b768..d43f5d74757ae 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::ty::layout::LayoutOf;
 #[cfg(feature="master")]
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
-use rustc_span::{Span, Symbol, symbol::kw, sym};
+use rustc_span::{Span, Symbol, sym};
 use rustc_target::abi::HasDataLayout;
 use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
 use rustc_target::spec::PanicStrategy;
@@ -129,7 +129,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     let res = self.context.new_call(None, builtin, &[a]);
                     self.icmp(IntPredicate::IntEQ, res, self.const_i32(0))
                 }
-                kw::Try => {
+                sym::catch_unwind => {
                     try_intrinsic(
                         self,
                         args[0].immediate(),
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 1eac2157cac3c..e78c4d1e31de8 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -17,7 +17,7 @@ use rustc_hir as hir;
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
 use rustc_middle::ty::{self, GenericArgsRef, Ty};
 use rustc_middle::{bug, span_bug};
-use rustc_span::{sym, symbol::kw, Span, Symbol};
+use rustc_span::{sym, Span, Symbol};
 use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
 use rustc_target::spec::{HasTargetSpec, PanicStrategy};
 
@@ -133,8 +133,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             }
             sym::unlikely => self
                 .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]),
-            kw::Try => {
-                try_intrinsic(
+            sym::catch_unwind => {
+                catch_unwind_intrinsic(
                     self,
                     args[0].immediate(),
                     args[1].immediate(),
@@ -457,7 +457,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 }
 
-fn try_intrinsic<'ll>(
+fn catch_unwind_intrinsic<'ll>(
     bx: &mut Builder<'_, 'll, '_>,
     try_func: &'ll Value,
     data: &'ll Value,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index d7277b22c8410..9714a9b5ea394 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi::Abi;
 
@@ -445,7 +445,7 @@ pub fn check_intrinsic_type(
                 )
             }
 
-            kw::Try => {
+            sym::catch_unwind => {
                 let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
                 let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
                     [mut_u8],
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 609ab054da21e..a66d38e5b537c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -487,6 +487,7 @@ symbols! {
         call_once,
         caller_location,
         capture_disjoint_fields,
+        catch_unwind,
         cause,
         cdylib,
         ceilf32,
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index f9d89795a9988..6fd3895bb9c12 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -75,6 +75,9 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     unsafe { crate::ptr::drop_in_place(to_drop) }
 }
 
+#[cfg(bootstrap)]
+pub use self::r#try as catch_unwind;
+
 extern "rust-intrinsic" {
     // N.B., these intrinsics take raw pointers because they mutate aliased
     // memory, which is not valid for either `&` or `&mut`.
@@ -2382,16 +2385,24 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn variant_count<T>() -> usize;
 
-    /// Rust's "try catch" construct which invokes the function pointer `try_fn`
-    /// with the data pointer `data`.
-    ///
-    /// The third argument is a function called if a panic occurs. This function
-    /// takes the data pointer and a pointer to the target-specific exception
-    /// object that was caught. For more information see the compiler's
-    /// source as well as std's catch implementation.
+    /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
+    /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
     ///
     /// `catch_fn` must not unwind.
+    ///
+    /// The third argument is a function called if an unwind occurs (both Rust unwinds and foreign
+    /// unwinds). This function takes the data pointer and a pointer to the target-specific
+    /// exception object that was caught. For more information, see the compiler's source as well as
+    /// std's `catch_unwind` implementation.
+    ///
+    /// The stable version of this intrinsic is `std::panic::catch_unwind`.
+    #[rustc_nounwind]
+    #[cfg(not(bootstrap))]
+    pub fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
+
+    /// For bootstrap only, see `catch_unwind`.
     #[rustc_nounwind]
+    #[cfg(bootstrap)]
     pub fn r#try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
 
     /// Emits a `!nontemporal` store according to LLVM (see their docs).
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index ef701d3867a1b..464a46264cbdd 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -508,12 +508,12 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // Access to the union's fields: this is `std` and we know that the `r#try`
     // intrinsic fills in the `r` or `p` union field based on its return value.
     //
-    // The call to `intrinsics::r#try` is made safe by:
+    // The call to `intrinsics::catch_unwind` is made safe by:
     // - `do_call`, the first argument, can be called with the initial `data_ptr`.
     // - `do_catch`, the second argument, can be called with the `data_ptr` as well.
     // See their safety preconditions for more information
     unsafe {
-        return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
+        return if intrinsics::catch_unwind(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
             Ok(ManuallyDrop::into_inner(data.r))
         } else {
             Err(ManuallyDrop::into_inner(data.p))
@@ -540,7 +540,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // Its must contains a valid `f` (type: F) value that can be use to fill
     // `data.r`.
     //
-    // This function cannot be marked as `unsafe` because `intrinsics::r#try`
+    // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
     // expects normal function pointers.
     #[inline]
     fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
@@ -562,7 +562,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // Since this uses `cleanup` it also hinges on a correct implementation of
     // `__rustc_panic_cleanup`.
     //
-    // This function cannot be marked as `unsafe` because `intrinsics::r#try`
+    // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
     // expects normal function pointers.
     #[inline]
     #[rustc_nounwind] // `intrinsic::r#try` requires catch fn to be nounwind
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index 602e8b31b0103..b67d588dbc9be 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         // Some intrinsics are special and need the "ret".
         match intrinsic_name {
-            "try" => return this.handle_try(args, dest, ret),
+            "catch_unwind" => return this.handle_catch_unwind(args, dest, ret),
             _ => {}
         }
 
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 4c054d8dc8aea..54f718c46cce1 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -69,7 +69,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     }
 
     /// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`.
-    fn handle_try(
+    fn handle_catch_unwind(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
         dest: &PlaceTy<'tcx, Provenance>,
diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs b/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs
index 883d5ae8096bd..fd667fbe454c1 100644
--- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs
+++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs
@@ -8,7 +8,7 @@ fn main() {
     unsafe {
         // Make sure we check the ABI when Miri itself invokes a function
         // as part of a shim implementation.
-        std::intrinsics::r#try(
+        std::intrinsics::catch_unwind(
             //~^ ERROR: calling a function with ABI C using caller ABI Rust
             std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
             std::ptr::null_mut(),
diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr
index f948d08bdbe26..501f17c86d69c 100644
--- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr
+++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr
@@ -1,7 +1,7 @@
 error: Undefined Behavior: calling a function with ABI C using caller ABI Rust
   --> $DIR/check_callback_abi.rs:LL:CC
    |
-LL | /         std::intrinsics::r#try(
+LL | /         std::intrinsics::catch_unwind(
 LL | |
 LL | |             std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
 LL | |             std::ptr::null_mut(),
diff --git a/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs b/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs
index e6251b5355886..0f41047c60330 100644
--- a/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs
+++ b/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs
@@ -15,7 +15,7 @@ fn main() {
     unsafe {
         let _ = malloc(0);
         std::mem::transmute::<fn(), extern "C" fn()>(foo)();
-        std::intrinsics::r#try(
+        std::intrinsics::catch_unwind(
             std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
             std::ptr::null_mut(),
             |_, _| unreachable!(),
diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs
index 2ca62a786880b..45df444dca462 100644
--- a/tests/assembly/wasm_exceptions.rs
+++ b/tests/assembly/wasm_exceptions.rs
@@ -41,7 +41,7 @@ pub fn test_cleanup() {
 #[no_mangle]
 pub fn test_rtry() {
     unsafe {
-        core::intrinsics::r#try(|_| {
+        core::intrinsics::catch_unwind(|_| {
             may_panic();
         }, core::ptr::null_mut(), |data, exception| {
             log_number(data as usize);
diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs
index 48a7357bfd8d8..66d2bbed709c6 100644
--- a/tests/codegen/wasm_exceptions.rs
+++ b/tests/codegen/wasm_exceptions.rs
@@ -35,7 +35,7 @@ pub fn test_cleanup() {
 #[no_mangle]
 pub fn test_rtry() {
     unsafe {
-        core::intrinsics::r#try(|_| {
+        core::intrinsics::catch_unwind(|_| {
             may_panic();
         }, core::ptr::null_mut(), |data, exception| {
             log_number(data as usize);
diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs
index 7049d2fd9e0d1..9d336510469ca 100644
--- a/tests/run-make/wasm-exceptions-nostd/src/lib.rs
+++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs
@@ -39,7 +39,7 @@ pub extern "C" fn start() -> usize {
     let data = 0x1234usize as *mut u8; // Something to recognize
 
     unsafe {
-        core::intrinsics::r#try(|data: *mut u8| {
+        core::intrinsics::catch_unwind(|data: *mut u8| {
             let _log_on_drop = LogOnDrop;
 
             logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data));
diff --git a/tests/ui/interior-mutability/interior-mutability.stderr b/tests/ui/interior-mutability/interior-mutability.stderr
index 7b08a6454052d..29b250c1b07c2 100644
--- a/tests/ui/interior-mutability/interior-mutability.stderr
+++ b/tests/ui/interior-mutability/interior-mutability.stderr
@@ -15,7 +15,7 @@ note: required because it's used within this closure
    |
 LL |     catch_unwind(|| { x.set(23); });
    |                  ^^
-note: required by a bound in `catch_unwind`
+note: required by a bound in `std::panic::catch_unwind`
   --> $SRC_DIR/std/src/panic.rs:LL:COL
 
 error: aborting due to 1 previous error

From a3c0f3af9ca4247016eaaf476321d6ab95d5739e Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Feb 2024 18:54:41 +0100
Subject: [PATCH 2/8] =?UTF-8?q?miri:=20rename=20miri=5Fstart=5Fpanic=20?=
 =?UTF-8?q?=E2=86=92=20miri=5Fstart=5Funwind?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 library/panic_unwind/src/miri.rs                   |  6 +++---
 src/tools/miri/src/concurrency/thread.rs           |  2 +-
 src/tools/miri/src/shims/foreign_items.rs          |  6 +++---
 src/tools/miri/src/shims/panic.rs                  | 14 +++++++-------
 ...iri_start_panic.rs => bad_miri_start_unwind.rs} |  4 ++--
 ...t_panic.stderr => bad_miri_start_unwind.stderr} |  8 ++++----
 .../miri/tests/fail/panic/unwind_panic_abort.rs    |  4 ++--
 .../tests/fail/panic/unwind_panic_abort.stderr     |  4 ++--
 src/tools/miri/tests/utils/miri_extern.rs          |  2 +-
 9 files changed, 25 insertions(+), 25 deletions(-)
 rename src/tools/miri/tests/fail/panic/{bad_miri_start_panic.rs => bad_miri_start_unwind.rs} (72%)
 rename src/tools/miri/tests/fail/panic/{bad_miri_start_panic.stderr => bad_miri_start_unwind.stderr} (71%)

diff --git a/library/panic_unwind/src/miri.rs b/library/panic_unwind/src/miri.rs
index d941b73b5fac1..4d21e846010e9 100644
--- a/library/panic_unwind/src/miri.rs
+++ b/library/panic_unwind/src/miri.rs
@@ -8,14 +8,14 @@ type Payload = Box<Box<dyn Any + Send>>;
 
 extern "Rust" {
     /// Miri-provided extern function to begin unwinding.
-    fn miri_start_panic(payload: *mut u8) -> !;
+    fn miri_start_unwind(payload: *mut u8) -> !;
 }
 
 pub unsafe fn panic(payload: Box<dyn Any + Send>) -> u32 {
-    // The payload we pass to `miri_start_panic` will be exactly the argument we get
+    // The payload we pass to `miri_start_unwind` will be exactly the argument we get
     // in `cleanup` below. So we just box it up once, to get something pointer-sized.
     let payload_box: Payload = Box::new(payload);
-    miri_start_panic(Box::into_raw(payload_box) as *mut u8)
+    miri_start_unwind(Box::into_raw(payload_box) as *mut u8)
 }
 
 pub unsafe fn cleanup(payload_box: *mut u8) -> Box<dyn Any + Send> {
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 64e1f3c5b5574..822ba8bf922f8 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -143,7 +143,7 @@ pub struct Thread<'mir, 'tcx> {
     join_status: ThreadJoinStatus,
 
     /// Stack of active panic payloads for the current thread. Used for storing
-    /// the argument of the call to `miri_start_panic` (the panic payload) when unwinding.
+    /// the argument of the call to `miri_start_unwind` (the panic payload) when unwinding.
     /// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
     ///
     /// In real unwinding, the payload gets passed as an argument to the landing pad,
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 0645c1f176ef7..4ae607e98da8a 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -68,9 +68,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let ret = match ret {
             None =>
                 match link_name.as_str() {
-                    "miri_start_panic" => {
-                        // `check_shim` happens inside `handle_miri_start_panic`.
-                        this.handle_miri_start_panic(abi, link_name, args, unwind)?;
+                    "miri_start_unwind" => {
+                        // `check_shim` happens inside `handle_miri_start_unwind`.
+                        this.handle_miri_start_unwind(abi, link_name, args, unwind)?;
                         return Ok(None);
                     }
                     // This matches calls to the foreign item `panic_impl`.
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 54f718c46cce1..65b5838cd1437 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -3,9 +3,9 @@
 //! The core pieces of the runtime are:
 //! - An implementation of `__rust_maybe_catch_panic` that pushes the invoked stack frame with
 //!   some extra metadata derived from the panic-catching arguments of `__rust_maybe_catch_panic`.
-//! - A hack in `libpanic_unwind` that calls the `miri_start_panic` intrinsic instead of the
+//! - A hack in `libpanic_unwind` that calls the `miri_start_unwind` intrinsic instead of the
 //!   target-native panic runtime. (This lives in the rustc repo.)
-//! - An implementation of `miri_start_panic` that stores its argument (the panic payload), and then
+//! - An implementation of `miri_start_unwind` that stores its argument (the panic payload), and then
 //!   immediately returns, but on the *unwind* edge (not the normal return edge), thus initiating unwinding.
 //! - A hook executed each time a frame is popped, such that if the frame pushed by `__rust_maybe_catch_panic`
 //!   gets popped *during unwinding*, we take the panic payload and store it according to the extra
@@ -44,9 +44,9 @@ impl VisitProvenance for CatchUnwindData<'_> {
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    /// Handles the special `miri_start_panic` intrinsic, which is called
+    /// Handles the special `miri_start_unwind` intrinsic, which is called
     /// by libpanic_unwind to delegate the actual unwinding process to Miri.
-    fn handle_miri_start_panic(
+    fn handle_miri_start_unwind(
         &mut self,
         abi: Abi,
         link_name: Symbol,
@@ -55,7 +55,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
-        trace!("miri_start_panic: {:?}", this.frame().instance);
+        trace!("miri_start_unwind: {:?}", this.frame().instance);
 
         // Get the raw pointer stored in arg[0] (the panic payload).
         let [payload] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@@ -85,7 +85,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // what that is), and returns 1.
         // The `payload` is passed (by libstd) to `__rust_panic_cleanup`, which is then expected to
         // return a `Box<dyn Any + Send + 'static>`.
-        // In Miri, `miri_start_panic` is passed exactly that type, so we make the `payload` simply
+        // In Miri, `miri_start_unwind` is passed exactly that type, so we make the `payload` simply
         // a pointer to `Box<dyn Any + Send + 'static>`.
 
         // Get all the arguments.
@@ -141,7 +141,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // We set the return value of `try` to 1, since there was a panic.
             this.write_scalar(Scalar::from_i32(1), &catch_unwind.dest)?;
 
-            // The Thread's `panic_payload` holds what was passed to `miri_start_panic`.
+            // The Thread's `panic_payload` holds what was passed to `miri_start_unwind`.
             // This is exactly the second argument we need to pass to `catch_fn`.
             let payload = this.active_thread_mut().panic_payloads.pop().unwrap();
 
diff --git a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.rs
similarity index 72%
rename from src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs
rename to src/tools/miri/tests/fail/panic/bad_miri_start_unwind.rs
index 4b0ae60b10101..deca836a36c61 100644
--- a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs
+++ b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.rs
@@ -3,10 +3,10 @@
 #![feature(c_unwind)]
 
 extern "C" {
-    fn miri_start_panic(payload: *mut u8) -> !;
+    fn miri_start_unwind(payload: *mut u8) -> !;
 }
 
 fn main() {
-    unsafe { miri_start_panic(&mut 0) }
+    unsafe { miri_start_unwind(&mut 0) }
     //~^ ERROR: unwinding past a stack frame that does not allow unwinding
 }
diff --git a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.stderr
similarity index 71%
rename from src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr
rename to src/tools/miri/tests/fail/panic/bad_miri_start_unwind.stderr
index 2d96ae4b7de4a..6c85aac050a20 100644
--- a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.stderr
@@ -1,15 +1,15 @@
 WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
 If you have a use-case for it, please file an issue.
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
-  --> $DIR/bad_miri_start_panic.rs:LL:CC
+  --> $DIR/bad_miri_start_unwind.rs:LL:CC
    |
-LL |     unsafe { miri_start_panic(&mut 0) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
+LL |     unsafe { miri_start_unwind(&mut 0) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
-   = note: inside `main` at $DIR/bad_miri_start_panic.rs:LL:CC
+   = note: inside `main` at $DIR/bad_miri_start_unwind.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
diff --git a/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs b/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
index c21fa85a90439..88419b1395c73 100644
--- a/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
+++ b/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
@@ -3,11 +3,11 @@
 //! Unwinding despite `-C panic=abort` is an error.
 
 extern "Rust" {
-    fn miri_start_panic(payload: *mut u8) -> !;
+    fn miri_start_unwind(payload: *mut u8) -> !;
 }
 
 fn main() {
     unsafe {
-        miri_start_panic(&mut 0); //~ ERROR: unwinding past a stack frame that does not allow unwinding
+        miri_start_unwind(&mut 0); //~ ERROR: unwinding past a stack frame that does not allow unwinding
     }
 }
diff --git a/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr b/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
index 4739c7f2ac6ba..26afe8830cfc5 100644
--- a/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
+++ b/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
   --> $DIR/unwind_panic_abort.rs:LL:CC
    |
-LL |         miri_start_panic(&mut 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
+LL |         miri_start_unwind(&mut 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/utils/miri_extern.rs b/src/tools/miri/tests/utils/miri_extern.rs
index ff7990561f2c9..e2983f6c71a7e 100644
--- a/src/tools/miri/tests/utils/miri_extern.rs
+++ b/src/tools/miri/tests/utils/miri_extern.rs
@@ -56,7 +56,7 @@ extern "Rust" {
     ///
     /// This is internal and unstable and should not be used; we give it here
     /// just to be complete.
-    pub fn miri_start_panic(payload: *mut u8) -> !;
+    pub fn miri_start_unwind(payload: *mut u8) -> !;
 
     /// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
     /// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort.

From 67bd410cac0f8717630512188a16eb16e3fd5be9 Mon Sep 17 00:00:00 2001
From: rustbot <47979223+rustbot@users.noreply.github.com>
Date: Mon, 26 Feb 2024 12:00:42 -0500
Subject: [PATCH 3/8] Update books

---
 src/doc/book            | 2 +-
 src/doc/edition-guide   | 2 +-
 src/doc/reference       | 2 +-
 src/doc/rust-by-example | 2 +-
 src/doc/rustc-dev-guide | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/doc/book b/src/doc/book
index 71352deb20727..19c40bfd2d576 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 71352deb20727b4dda9ebfe8182709d5bf17dfea
+Subproject commit 19c40bfd2d57641d962f3119a1c343355f1b3c5e
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
index 76bd48a273a0e..e1eead1181a69 160000
--- a/src/doc/edition-guide
+++ b/src/doc/edition-guide
@@ -1 +1 @@
-Subproject commit 76bd48a273a0e0413a3bf22c699112d41497b99e
+Subproject commit e1eead1181a691e56299294d5f1d62fe7a26d317
diff --git a/src/doc/reference b/src/doc/reference
index 8227666de13f6..3417f866932cb 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 8227666de13f6e7bb32dea9dc42e841adb5ce4b7
+Subproject commit 3417f866932cb1c09c6be0f31d2a02ee01b4b95d
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index e188d5d466f7f..57f1e708f5d58 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit e188d5d466f7f3ff9f1d518393235f4fe951be46
+Subproject commit 57f1e708f5d5850562bc385aaf610e6af14d6ec8
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
index 1f30cc7cca9a3..7b0ef5b0bea5e 160000
--- a/src/doc/rustc-dev-guide
+++ b/src/doc/rustc-dev-guide
@@ -1 +1 @@
-Subproject commit 1f30cc7cca9a3433bc1872abdc98960b36c21ca0
+Subproject commit 7b0ef5b0bea5e3ce3b9764aa5754a60e2cc05c52

From a1b93e8fed23825ce319b8bba8158e2f8d5d5335 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: Mon, 26 Feb 2024 19:22:34 +0000
Subject: [PATCH 4/8] Rearrange `Vec::from_raw_parts{,_in}` doc argument order
 to match code argument order

---
 library/alloc/src/vec/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index b59699219eb84..7e07a793a66df 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -481,7 +481,7 @@ impl<T> Vec<T> {
         Self::with_capacity_in(capacity, Global)
     }
 
-    /// Creates a `Vec<T>` directly from a pointer, a capacity, and a length.
+    /// Creates a `Vec<T>` directly from a pointer, a length, and a capacity.
     ///
     /// # Safety
     ///
@@ -672,7 +672,7 @@ impl<T, A: Allocator> Vec<T, A> {
         Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
     }
 
-    /// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length,
+    /// Creates a `Vec<T, A>` directly from a pointer, a length, a capacity,
     /// and an allocator.
     ///
     /// # Safety

From 26bdf2900acad2091ab7e59296d3a457011ea770 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: Mon, 26 Feb 2024 19:24:49 +0000
Subject: [PATCH 5/8] Rearrange `String::from_raw_parts` doc argument order to
 match code argument order

---
 library/alloc/src/string.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 6dadbc8e36428..955438f49a103 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -896,7 +896,7 @@ impl String {
         self.vec.into_raw_parts()
     }
 
-    /// Creates a new `String` from a length, capacity, and pointer.
+    /// Creates a new `String` from a pointer, a length and a capacity.
     ///
     /// # Safety
     ///

From dd24a462d517cf2a0667adf92aaa38502b71b61c 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: Mon, 26 Feb 2024 19:26:49 +0000
Subject: [PATCH 6/8] Document args returned from
 `Vec::into_raw_parts{,_with_alloc}`

---
 library/alloc/src/vec/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 7e07a793a66df..7bd19875584a3 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -786,7 +786,7 @@ impl<T, A: Allocator> Vec<T, A> {
         unsafe { Vec { buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), len: length } }
     }
 
-    /// Decomposes a `Vec<T>` into its raw components.
+    /// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity)`.
     ///
     /// Returns the raw pointer to the underlying data, the length of
     /// the vector (in elements), and the allocated capacity of the
@@ -824,7 +824,7 @@ impl<T, A: Allocator> Vec<T, A> {
         (me.as_mut_ptr(), me.len(), me.capacity())
     }
 
-    /// Decomposes a `Vec<T>` into its raw components.
+    /// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity, allocator)`.
     ///
     /// Returns the raw pointer to the underlying data, the length of the vector (in elements),
     /// the allocated capacity of the data (in elements), and the allocator. These are the same

From bfeea294cc01c295ca5b54dcbfb59ee6953b4fc6 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: Mon, 26 Feb 2024 19:31:51 +0000
Subject: [PATCH 7/8] Document args returned from `String::into_raw_parts`

---
 library/alloc/src/string.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 955438f49a103..1d3c04f7807ab 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -864,7 +864,7 @@ impl String {
         }
     }
 
-    /// Decomposes a `String` into its raw components.
+    /// Decomposes a `String` into its raw components: `(pointer, length, capacity)`.
     ///
     /// Returns the raw pointer to the underlying data, the length of
     /// the string (in bytes), and the allocated capacity of the data

From 1658ca082a1d510480a7c228b0b6bfb83863d0e9 Mon Sep 17 00:00:00 2001
From: Lieselotte <52315535+she3py@users.noreply.github.com>
Date: Mon, 26 Feb 2024 21:47:10 +0100
Subject: [PATCH 8/8] Properly emit `expected ;` on `#[attr] expr`

---
 .../rustc_parse/src/parser/diagnostics.rs     |  6 ++---
 ...rom-trailing-outer-attribute-in-body-1.rs} |  0
 ...trailing-outer-attribute-in-body-1.stderr} |  4 +--
 ...from-trailing-outer-attribute-in-body-2.rs | 15 +++++++++++
 ...-trailing-outer-attribute-in-body-2.stderr | 26 +++++++++++++++++++
 5 files changed, 45 insertions(+), 6 deletions(-)
 rename tests/ui/parser/attribute/{properly-recover-from-trailing-outer-attribute-in-body.rs => properly-recover-from-trailing-outer-attribute-in-body-1.rs} (100%)
 rename tests/ui/parser/attribute/{properly-recover-from-trailing-outer-attribute-in-body.stderr => properly-recover-from-trailing-outer-attribute-in-body-1.stderr} (97%)
 create mode 100644 tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs
 create mode 100644 tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr

diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index cc1f7c8ac7d58..995e140b32921 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -800,9 +800,8 @@ impl<'a> Parser<'a> {
                 {
                     Ok(next_attr) => next_attr,
                     Err(inner_err) => {
-                        err.cancel();
                         inner_err.cancel();
-                        return self.dcx().span_delayed_bug(expr.span, "not a tail expression");
+                        return err.emit();
                     }
                 }
                 && let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
@@ -813,9 +812,8 @@ impl<'a> Parser<'a> {
                 let next_expr = match snapshot.parse_expr() {
                     Ok(next_expr) => next_expr,
                     Err(inner_err) => {
-                        err.cancel();
                         inner_err.cancel();
-                        return self.dcx().span_delayed_bug(expr.span, "not a tail expression");
+                        return err.emit();
                     }
                 };
                 // We have for sure
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.rs
similarity index 100%
rename from tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs
rename to tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.rs
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.stderr
similarity index 97%
rename from tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
rename to tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.stderr
index dd0081cc2dff9..dcc2e92c47ad8 100644
--- a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.stderr
@@ -1,5 +1,5 @@
 error: expected `;`, found `#`
-  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:4:47
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body-1.rs:4:47
    |
 LL |     #[cfg(feature = )]
    |     ------------------ only `;` terminated statements or tail expressions are allowed after this attribute
@@ -18,7 +18,7 @@ LL |     { [1, 2, 3].iter().map().collect::<String>() }
    |     +                                            +
 
 error: expected statement after outer attribute
-  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body-1.rs:5:5
    |
 LL |     #[attr]
    |     ^^^^^^^
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs
new file mode 100644
index 0000000000000..ad9e7ad707b53
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs
@@ -0,0 +1,15 @@
+// Issue #121647: recovery path leaving unemitted error behind
+
+macro_rules! the_macro {
+    ( $foo:stmt ; $bar:stmt ; ) => {
+        #[cfg()]
+        $foo //~ ERROR expected `;`, found `#`
+
+        #[cfg(bar)]
+        $bar
+    };
+}
+
+fn main() {
+    the_macro!( (); (); );
+}
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr
new file mode 100644
index 0000000000000..7b9b8319674e4
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr
@@ -0,0 +1,26 @@
+error: expected `;`, found `#`
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body-2.rs:6:13
+   |
+LL |         #[cfg()]
+   |         -------- only `;` terminated statements or tail expressions are allowed after this attribute
+LL |         $foo
+   |             ^ expected `;` here
+LL |
+LL |         #[cfg(bar)]
+   |         - unexpected token
+...
+LL |     the_macro!( (); (); );
+   |     --------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `the_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: add `;` here
+   |
+LL |         $foo;
+   |             +
+help: alternatively, consider surrounding the expression with a block
+   |
+LL |     the_macro!( { () }; (); );
+   |                 +    +
+
+error: aborting due to 1 previous error
+