diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 7a925705806..a58c7c43246 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1124,8 +1124,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                     err.multipart_suggestion(
                         "consider moving the expression out of the loop so it is only moved once",
                         vec![
-                            (parent.span, "value".to_string()),
                             (span.shrink_to_lo(), format!("let mut value = {value};{indent}")),
+                            (parent.span, "value".to_string()),
                         ],
                         Applicability::MaybeIncorrect,
                     );
diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs
index 9a0fd52677d..0f2c0eee27d 100644
--- a/compiler/rustc_data_structures/src/steal.rs
+++ b/compiler/rustc_data_structures/src/steal.rs
@@ -51,6 +51,15 @@ impl<T> Steal<T> {
         let value = value_ref.take();
         value.expect("attempt to steal from stolen value")
     }
+
+    /// Writers of rustc drivers often encounter stealing issues. This function makes it possible to
+    /// handle these errors gracefully.
+    ///
+    /// This should not be used within rustc as it leaks information not tracked
+    /// by the query system, breaking incremental compilation.
+    pub fn is_stolen(&self) -> bool {
+        self.value.borrow().is_none()
+    }
 }
 
 impl<CTX, T: HashStable<CTX>> HashStable<CTX> for Steal<T> {
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 67ca6d50cca..fae8b5647fc 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -920,8 +920,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
         applicability: Applicability,
         style: SuggestionStyle,
     ) -> &mut Self {
-        suggestion.sort_unstable();
-        suggestion.dedup_by(|(s1, m1), (s2, m2)| s1.source_equal(*s2) && m1 == m2);
+        let mut seen = crate::FxHashSet::default();
+        suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone())));
 
         let parts = suggestion
             .into_iter()
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index cef003e0a43..89e7227eda2 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::Session;
 use rustc_span::symbol::{kw, Ident};
-use rustc_span::{sym, BytePos, Span, DUMMY_SP};
+use rustc_span::{sym, Span, DUMMY_SP};
 use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
@@ -1140,8 +1140,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 .get(arg_idx + 1)
                                 .map(|&(_, sp)| sp)
                                 .unwrap_or_else(|| {
-                                    // Subtract one to move before `)`
-                                    call_expr.span.with_lo(call_expr.span.hi() - BytePos(1))
+                                    // Try to move before `)`. Note that `)` here is not necessarily
+                                    // the latin right paren, it could be a Unicode-confusable that
+                                    // looks like a `)`, so we must not use `- BytePos(1)`
+                                    // manipulations here.
+                                    self.tcx().sess.source_map().end_point(call_expr.span)
                                 });
 
                             // Include next comma
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index b3efb87a4a2..a3b782d651d 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -408,10 +408,14 @@ impl<'a> Parser<'a> {
     fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
         let eq_consumed = match self.token.kind {
             token::BinOpEq(..) => {
-                // Recover `let x <op>= 1` as `let x = 1`
+                // Recover `let x <op>= 1` as `let x = 1` We must not use `+ BytePos(1)` here
+                // because `<op>` can be a multi-byte lookalike that was recovered, e.g. `➖=` (the
+                // `➖` is a U+2796 Heavy Minus Sign Unicode Character) that was recovered as a
+                // `-=`.
+                let extra_op_span = self.psess.source_map().start_point(self.token.span);
                 self.dcx().emit_err(errors::CompoundAssignmentExpressionInLet {
                     span: self.token.span,
-                    suggestion: self.token.span.with_hi(self.token.span.lo() + BytePos(1)),
+                    suggestion: extra_op_span,
                 });
                 self.bump();
                 true
diff --git a/library/std/src/sys/pal/unix/process/process_unix/tests.rs b/library/std/src/sys/pal/unix/process/process_unix/tests.rs
index e5e1f956bc3..f4d6ac6b4e3 100644
--- a/library/std/src/sys/pal/unix/process/process_unix/tests.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix/tests.rs
@@ -24,7 +24,20 @@ fn exitstatus_display_tests() {
     // The purpose of this test is to test our string formatting, not our understanding of the wait
     // status magic numbers. So restrict these to Linux.
     if cfg!(target_os = "linux") {
+        #[cfg(any(target_arch = "mips", target_arch = "mips64"))]
+        t(0x0137f, "stopped (not terminated) by signal: 19 (SIGPWR)");
+
+        #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
+        t(0x0137f, "stopped (not terminated) by signal: 19 (SIGCONT)");
+
+        #[cfg(not(any(
+            target_arch = "mips",
+            target_arch = "mips64",
+            target_arch = "sparc",
+            target_arch = "sparc64"
+        )))]
         t(0x0137f, "stopped (not terminated) by signal: 19 (SIGSTOP)");
+
         t(0x0ffff, "continued (WIFCONTINUED)");
     }
 
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7d29d9a5172..0fa610eebb4 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -3,12 +3,7 @@ use crate::mem::{self, ManuallyDrop};
 use crate::num::NonZero;
 #[cfg(all(target_os = "linux", target_env = "gnu"))]
 use crate::sys::weak::dlsym;
-#[cfg(any(
-    target_os = "solaris",
-    target_os = "illumos",
-    target_os = "nto",
-    target_os = "vxworks"
-))]
+#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
 use crate::sys::weak::weak;
 use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
@@ -220,23 +215,16 @@ impl Thread {
     #[cfg(target_os = "vxworks")]
     pub fn set_name(name: &CStr) {
         // FIXME(libc): adding real STATUS, ERROR type eventually.
-        weak! {
-            fn taskNameSet(
-                libc::TASK_ID, *mut libc::c_char
-            ) -> libc::c_int
+        extern "C" {
+            fn taskNameSet(task_id: libc::TASK_ID, task_name: *mut libc::c_char) -> libc::c_int;
         }
 
-        // We can't assume taskNameSet is necessarily available.
-        // VX_TASK_NAME_LEN can be found set to 31,
-        // however older versions can be set to only 10.
-        // FIXME(vxworks): if the minimum supported VxWorks is >= 7, the maximum length can be changed to 31.
-        if let Some(f) = taskNameSet.get() {
-            const VX_TASK_NAME_LEN: usize = 10;
+        //  VX_TASK_NAME_LEN is 31 in VxWorks 7.
+        const VX_TASK_NAME_LEN: usize = 31;
 
-            let name = truncate_cstr::<{ VX_TASK_NAME_LEN }>(name);
-            let status = unsafe { f(libc::taskIdSelf(), name.as_mut_ptr()) };
-            debug_assert_eq!(res, libc::OK);
-        }
+        let mut name = truncate_cstr::<{ VX_TASK_NAME_LEN }>(name);
+        let res = unsafe { taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) };
+        debug_assert_eq!(res, libc::OK);
     }
 
     #[cfg(any(
@@ -489,9 +477,11 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
                 fn vxCpuEnabledGet() -> libc::cpuset_t;
             }
 
-            // always fetches a valid bitmask
-            let set = unsafe { vxCpuEnabledGet() };
-            Ok(NonZero::new_unchecked(set.count_ones() as usize))
+            // SAFETY: `vxCpuEnabledGet` always fetches a mask with at least one bit set
+            unsafe{
+                let set = vxCpuEnabledGet();
+                Ok(NonZero::new_unchecked(set.count_ones() as usize))
+            }
         } else {
             // FIXME: implement on Redox, l4re
             Err(io::const_io_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform"))
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 14beef20bad..f0a55830167 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1325,7 +1325,11 @@ impl Config {
         // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
         // but not if `config.toml` hasn't been created.
         let mut toml = if !using_default_path || toml_path.exists() {
-            config.config = Some(toml_path.clone());
+            config.config = Some(if cfg!(not(feature = "bootstrap-self-test")) {
+                toml_path.canonicalize().unwrap()
+            } else {
+                toml_path.clone()
+            });
             get_toml(&toml_path)
         } else {
             config.config = None;
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 453fb39327d..2062d435bfc 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -986,7 +986,8 @@ impl Build {
     }
 
     /// Execute a command and return its output.
-    /// This method should be used for all command executions in bootstrap.
+    /// Note: Ideally, you should use one of the BootstrapCommand::run* functions to
+    /// execute commands. They internally call this method.
     #[track_caller]
     fn run(
         &self,
@@ -1057,20 +1058,28 @@ Executed at: {executed_at}"#,
                 CommandOutput::did_not_start(stdout, stderr)
             }
         };
+
+        let fail = |message: &str| {
+            if self.is_verbose() {
+                println!("{message}");
+            } else {
+                println!("Command has failed. Rerun with -v to see more details.");
+            }
+            exit!(1);
+        };
+
         if !output.is_success() {
             match command.failure_behavior {
                 BehaviorOnFailure::DelayFail => {
                     if self.fail_fast {
-                        println!("{message}");
-                        exit!(1);
+                        fail(&message);
                     }
 
                     let mut failures = self.delayed_failures.borrow_mut();
                     failures.push(message);
                 }
                 BehaviorOnFailure::Exit => {
-                    println!("{message}");
-                    exit!(1);
+                    fail(&message);
                 }
                 BehaviorOnFailure::Ignore => {
                     // If failures are allowed, either the error has been printed already
diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs
index bfe2f084552..3f7f6214cf6 100644
--- a/src/bootstrap/src/utils/tarball.rs
+++ b/src/bootstrap/src/utils/tarball.rs
@@ -317,6 +317,12 @@ impl<'a> Tarball<'a> {
             channel::write_commit_hash_file(&self.overlay_dir, &info.sha);
             channel::write_commit_info_file(&self.overlay_dir, info);
         }
+
+        // Add config file if present.
+        if let Some(config) = &self.builder.config.config {
+            self.add_renamed_file(config, &self.overlay_dir, "builder-config");
+        }
+
         for file in self.overlay.legal_and_readme() {
             self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644);
         }
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 7fd1808a1f0..90e30f85bd6 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -282,7 +282,7 @@ target | std | host | notes
 [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
 `armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD
 [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
-[`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ? |  | Armv7-A for VxWorks
+[`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ |  | Armv7-A for VxWorks
 [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3
 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3, hardfloat
 [`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * |  | Bare Armv7-A, hardfloat
@@ -308,7 +308,7 @@ target | std | host | notes
 `i686-uwp-windows-gnu` | ✓ |  | [^x86_32-floats-return-ABI]
 `i686-uwp-windows-msvc` | ✓ |  | [^x86_32-floats-return-ABI]
 [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ |   | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
-[`i686-wrs-vxworks`](platform-support/vxworks.md) | ? |  | [^x86_32-floats-return-ABI]
+[`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  | [^x86_32-floats-return-ABI]
 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
 `mips-unknown-linux-musl` | ✓ |  | MIPS Linux with musl 1.2.3
@@ -334,13 +334,13 @@ target | std | host | notes
 `powerpc-unknown-linux-musl` | ? |  | PowerPC Linux with musl 1.2.3
 [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems
 [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * |  |
-[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ? |  |
-[`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ? |  |
+[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ |  |
+[`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 `powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
 `powerpc64le-unknown-freebsd` |   |   | PPC64LE FreeBSD
 `powerpc-unknown-freebsd` |   |   | PowerPC FreeBSD
 `powerpc64-unknown-linux-musl` | ? |  | 64-bit PowerPC Linux with musl 1.2.3
-`powerpc64-wrs-vxworks` | ? |  |
+[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 `powerpc64le-unknown-linux-musl` | ? |  | 64-bit PowerPC Linux with musl 1.2.3, Little Endian
 [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64
 [`powerpc64-ibm-aix`](platform-support/aix.md) | ? |  | 64-bit AIX (7.2 and newer)
@@ -383,7 +383,7 @@ target | std | host | notes
 `x86_64-uwp-windows-gnu` | ✓ |  |
 `x86_64-uwp-windows-msvc` | ✓ |  |
 [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ |   | 64-bit Windows 7 support
-[`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ? |  |
+[`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell)
 [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * |  | 64-bit Linux with no libc
 [`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * |  | Xtensa ESP32
diff --git a/src/doc/rustc/src/platform-support/vxworks.md b/src/doc/rustc/src/platform-support/vxworks.md
index 7c73ee8cfa8..f1860346c8f 100644
--- a/src/doc/rustc/src/platform-support/vxworks.md
+++ b/src/doc/rustc/src/platform-support/vxworks.md
@@ -12,6 +12,7 @@ Target triplets available:
 - `i686-wrs-vxworks`
 - `armv7-wrs-vxworks-eabihf`
 - `powerpc-wrs-vxworks`
+- `powerpc64-wrs-vxworks`
 - `powerpc-wrs-vxworks-spe`
 
 ## Target maintainers
@@ -42,6 +43,7 @@ target = [
     "i686-wrs-vxworks",
     "armv7-wrs-vxworks-eabihf",
     "powerpc-wrs-vxworks",
+    "powerpc64-wrs-vxworks",
     "powerpc-wrs-vxworks-spe",
 ]
 ```
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 97d97808b93..bb8d39aaf1d 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -924,6 +924,7 @@ pub(crate) struct TagIterator<'a, 'tcx> {
     data: &'a str,
     is_in_attribute_block: bool,
     extra: Option<&'a ExtraInfo<'tcx>>,
+    is_error: bool,
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -950,13 +951,20 @@ struct Indices {
 
 impl<'a, 'tcx> TagIterator<'a, 'tcx> {
     pub(crate) fn new(data: &'a str, extra: Option<&'a ExtraInfo<'tcx>>) -> Self {
-        Self { inner: data.char_indices().peekable(), data, is_in_attribute_block: false, extra }
+        Self {
+            inner: data.char_indices().peekable(),
+            data,
+            is_in_attribute_block: false,
+            extra,
+            is_error: false,
+        }
     }
 
-    fn emit_error(&self, err: impl Into<DiagMessage>) {
+    fn emit_error(&mut self, err: impl Into<DiagMessage>) {
         if let Some(extra) = self.extra {
             extra.error_invalid_codeblock_attr(err);
         }
+        self.is_error = true;
     }
 
     fn skip_separators(&mut self) -> Option<usize> {
@@ -1154,6 +1162,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
     type Item = LangStringToken<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
+        if self.is_error {
+            return None;
+        }
         let Some(start) = self.skip_separators() else {
             if self.is_in_attribute_block {
                 self.emit_error("unclosed attribute block (`{}`): missing `}` at the end");
@@ -1342,14 +1353,15 @@ impl LangString {
             }
         };
 
-        call(&mut TagIterator::new(string, extra));
+        let mut tag_iter = TagIterator::new(string, extra);
+        call(&mut tag_iter);
 
         // ignore-foo overrides ignore
         if !ignores.is_empty() {
             data.ignore = Ignore::Some(ignores);
         }
 
-        data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags);
+        data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags) && !tag_iter.is_error;
 
         data
     }
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index 971120d4991..e490099a92e 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -61,7 +61,7 @@ fn test_lang_string_parse() {
         ..Default::default()
     });
     // error
-    t(LangString { original: "{rust}".into(), rust: true, ..Default::default() });
+    t(LangString { original: "{rust}".into(), rust: false, ..Default::default() });
     t(LangString {
         original: "{.rust}".into(),
         rust: true,
@@ -233,7 +233,7 @@ fn test_lang_string_parse() {
         ..Default::default()
     });
     // error
-    t(LangString { original: "{class=first=second}".into(), rust: true, ..Default::default() });
+    t(LangString { original: "{class=first=second}".into(), rust: false, ..Default::default() });
     // error
     t(LangString {
         original: "{class=first.second}".into(),
@@ -261,7 +261,7 @@ fn test_lang_string_parse() {
         ..Default::default()
     });
     // error
-    t(LangString { original: r#"{class=f"irst"}"#.into(), rust: true, ..Default::default() });
+    t(LangString { original: r#"{class=f"irst"}"#.into(), rust: false, ..Default::default() });
 }
 
 #[test]
diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs
new file mode 100644
index 00000000000..571bc94e30f
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs
@@ -0,0 +1,12 @@
+//@ compile-flags:--test
+//@ check-pass
+#![allow(rustdoc::invalid_codeblock_attributes)]
+
+// https://github.com/rust-lang/rust/pull/124577#issuecomment-2276034737
+
+// Test that invalid langstrings don't get run.
+
+/// ```{rust,ignore}
+/// panic!();
+/// ```
+pub struct Foo;
diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout
new file mode 100644
index 00000000000..e5c27bebbdb
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout
@@ -0,0 +1,5 @@
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
+
diff --git a/tests/ui/parser/suggest-remove-compount-assign-let-ice.rs b/tests/ui/parser/suggest-remove-compount-assign-let-ice.rs
new file mode 100644
index 00000000000..1affee5678e
--- /dev/null
+++ b/tests/ui/parser/suggest-remove-compount-assign-let-ice.rs
@@ -0,0 +1,16 @@
+//! Previously we would try to issue a suggestion for `let x <op>= 1`, i.e. a compound assignment
+//! within a `let` binding, to remove the `<op>`. The suggestion code unfortunately incorrectly
+//! assumed that the `<op>` is an exactly-1-byte ASCII character, but this assumption is incorrect
+//! because we also recover Unicode-confusables like `➖=` as `-=`. In this example, the suggestion
+//! code used a `+ BytePos(1)` to calculate the span of the `<op>` codepoint that looks like `-` but
+//! the mult-byte Unicode look-alike would cause the suggested removal span to be inside a
+//! multi-byte codepoint boundary, triggering a codepoint boundary assertion.
+//!
+//! issue: rust-lang/rust#128845
+
+fn main() {
+    // Adapted from #128845 but with irrelevant components removed and simplified.
+    let x ➖= 1;
+    //~^ ERROR unknown start of token: \u{2796}
+    //~| ERROR: can't reassign to an uninitialized variable
+}
diff --git a/tests/ui/parser/suggest-remove-compount-assign-let-ice.stderr b/tests/ui/parser/suggest-remove-compount-assign-let-ice.stderr
new file mode 100644
index 00000000000..59716d69b50
--- /dev/null
+++ b/tests/ui/parser/suggest-remove-compount-assign-let-ice.stderr
@@ -0,0 +1,26 @@
+error: unknown start of token: \u{2796}
+  --> $DIR/suggest-remove-compount-assign-let-ice.rs:13:11
+   |
+LL |     let x ➖= 1;
+   |           ^^
+   |
+help: Unicode character '➖' (Heavy Minus Sign) looks like '-' (Minus/Hyphen), but it is not
+   |
+LL |     let x -= 1;
+   |           ~
+
+error: can't reassign to an uninitialized variable
+  --> $DIR/suggest-remove-compount-assign-let-ice.rs:13:11
+   |
+LL |     let x ➖= 1;
+   |           ^^^
+   |
+   = help: if you meant to overwrite, remove the `let` binding
+help: initialize the variable
+   |
+LL -     let x ➖= 1;
+LL +     let x = 1;
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/typeck/suggest-arg-comma-delete-ice.rs b/tests/ui/typeck/suggest-arg-comma-delete-ice.rs
new file mode 100644
index 00000000000..48d02e13eca
--- /dev/null
+++ b/tests/ui/typeck/suggest-arg-comma-delete-ice.rs
@@ -0,0 +1,19 @@
+//! Previously, we tried to remove extra arg commas when providing extra arg removal suggestions.
+//! One of the edge cases is having to account for an arg that has a closing delimiter `)`
+//! following it. However, the previous suggestion code assumed that the delimiter is in fact
+//! exactly the 1-byte `)` character. This assumption was proven incorrect, because we recover
+//! from Unicode-confusable delimiters in the parser, which means that the ending delimiter could be
+//! a multi-byte codepoint that looks *like* a `)`. Subtracing 1 byte could land us in the middle of
+//! a codepoint, triggering a codepoint boundary assertion.
+//!
+//! issue: rust-lang/rust#128717
+
+fn main() {
+    // The following example has been modified from #128717 to remove irrelevant Unicode as they do
+    // not otherwise partake in the right delimiter calculation causing the codepoint boundary
+    // assertion.
+    main(rahh);
+    //~^ ERROR unknown start of token
+    //~| ERROR this function takes 0 arguments but 1 argument was supplied
+    //~| ERROR cannot find value `rahh` in this scope
+}
diff --git a/tests/ui/typeck/suggest-arg-comma-delete-ice.stderr b/tests/ui/typeck/suggest-arg-comma-delete-ice.stderr
new file mode 100644
index 00000000000..53608391f3c
--- /dev/null
+++ b/tests/ui/typeck/suggest-arg-comma-delete-ice.stderr
@@ -0,0 +1,38 @@
+error: unknown start of token: \u{ff09}
+  --> $DIR/suggest-arg-comma-delete-ice.rs:15:14
+   |
+LL |     main(rahh);
+   |              ^^
+   |
+help: Unicode character ')' (Fullwidth Right Parenthesis) looks like ')' (Right Parenthesis), but it is not
+   |
+LL |     main(rahh);
+   |              ~
+
+error[E0425]: cannot find value `rahh` in this scope
+  --> $DIR/suggest-arg-comma-delete-ice.rs:15:10
+   |
+LL |     main(rahh);
+   |          ^^^^ not found in this scope
+
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+  --> $DIR/suggest-arg-comma-delete-ice.rs:15:5
+   |
+LL |     main(rahh);
+   |     ^^^^ ---- unexpected argument
+   |
+note: function defined here
+  --> $DIR/suggest-arg-comma-delete-ice.rs:11:4
+   |
+LL | fn main() {
+   |    ^^^^
+help: remove the extra argument
+   |
+LL -     main(rahh);
+LL +     main();
+   |
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0061, E0425.
+For more information about an error, try `rustc --explain E0061`.