about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast/src/ast.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock130
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml14
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs33
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0002-abi-cafe-Disable-broken-tests.patch32
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch4
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch7
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch22
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh94
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs22
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/global_asm.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/pretty_clif.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/src/trap.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs15
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/util.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp19
-rw-r--r--compiler/rustc_metadata/src/creader.rs6
-rw-r--r--compiler/rustc_metadata/src/errors.rs6
-rw-r--r--compiler/rustc_metadata/src/locator.rs16
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs21
-rw-r--r--compiler/rustc_session/src/config.rs22
-rw-r--r--compiler/rustc_session/src/config/cfg.rs4
-rw-r--r--compiler/rustc_session/src/errors.rs8
-rw-r--r--compiler/rustc_session/src/filesearch.rs4
-rw-r--r--compiler/rustc_session/src/options.rs6
-rw-r--r--compiler/rustc_session/src/search_paths.rs6
-rw-r--r--compiler/rustc_session/src/session.rs12
-rw-r--r--compiler/rustc_target/src/spec/mod.rs145
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs61
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs101
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs42
50 files changed, 524 insertions, 450 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index ec6ca70ae0a..997c44cffff 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -414,6 +414,12 @@ pub struct WhereClause {
     pub span: Span,
 }
 
+impl WhereClause {
+    pub fn is_empty(&self) -> bool {
+        !self.has_where_token && self.predicates.is_empty()
+    }
+}
+
 impl Default for WhereClause {
     fn default() -> WhereClause {
         WhereClause { has_where_token: false, predicates: ThinVec::new(), span: DUMMY_SP }
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index 1c2ca95b075..e4f77472802 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -1,6 +1,6 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "ahash"
@@ -46,24 +46,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b80c3a50b9c4c7e5b5f73c0ed746687774fc9e36ef652b110da8daebf0c6e0e6"
+checksum = "8ea5e7afe85cadb55c4c1176268a2ac046fdff8dfaeca39e18581b9dc319ca9e"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-bitset"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38778758c2ca918b05acb2199134e0c561fb577c50574259b26190b6c2d95ded"
+checksum = "8ab25ef3be935a80680e393183e1f94ef507e93a24a8369494d2c6818aedb3e3"
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58258667ad10e468bfc13a8d620f50dfcd4bb35d668123e97defa2549b9ad397"
+checksum = "900a19b84545924f1851cbfe386962edfc4ecbc3366a254825cf1ecbcda8ba08"
 dependencies = [
  "bumpalo",
  "cranelift-bforest",
@@ -74,7 +74,7 @@ dependencies = [
  "cranelift-entity",
  "cranelift-isle",
  "gimli",
- "hashbrown 0.14.5",
+ "hashbrown",
  "log",
  "regalloc2",
  "rustc-hash",
@@ -84,42 +84,42 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043f0b702e529dcb07ff92bd7d40e7d5317b5493595172c5eb0983343751ee06"
+checksum = "08c73b2395ffe9e7b4fdf7e2ebc052e7e27af13f68a964985346be4da477a5fc"
 dependencies = [
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7763578888ab53eca5ce7da141953f828e82c2bfadcffc106d10d1866094ffbb"
+checksum = "7d9ed0854e96a4ff0879bff39d078de8dea7f002721c9494c1fdb4e1baa86ccc"
 
 [[package]]
 name = "cranelift-control"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32db15f08c05df570f11e8ab33cb1ec449a64b37c8a3498377b77650bef33d8b"
+checksum = "b4aca921dd422e781409de0129c255768fec5dec1dae83239b497fb9138abb89"
 dependencies = [
  "arbitrary",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5289cdb399381a27e7bbfa1b42185916007c3d49aeef70b1d01cb4caa8010130"
+checksum = "e2d770e6605eccee15b49decdd82cd26f2b6404767802471459ea49c57379a98"
 dependencies = [
  "cranelift-bitset",
 ]
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31ba8ab24eb9470477e98ddfa3c799a649ac5a0d9a2042868c4c952133c234e8"
+checksum = "29268711cb889cb39215b10faf88b9087d4c9e1d2633581e4f722a2bf4bb4ef9"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -129,15 +129,15 @@ dependencies = [
 
 [[package]]
 name = "cranelift-isle"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b72a3c5c166a70426dcb209bdd0bb71a787c1ea76023dc0974fbabca770e8f9"
+checksum = "dc65156f010aed1985767ad1bff0eb8d186743b7b03e23d0c17604a253e3f356"
 
 [[package]]
 name = "cranelift-jit"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df32578a47582e49b4fc1f9a5786839d9be1fedaa9f00bea7612c54425663c6b"
+checksum = "40ba6b46367a4f466cfb1abe32793fa1a0f96d862251491b01a44726b8ed9445"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -150,14 +150,14 @@ dependencies = [
  "region",
  "target-lexicon",
  "wasmtime-jit-icache-coherence",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "cranelift-module"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96094a758cdb543c9143f70817cd31069fecd49f50981a0fac06820ac011dc2f"
+checksum = "007607022a4883ebdffc46c0925e2e10babf2a565ae78518034ade722aa825d2"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -166,9 +166,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46a42424c956bbc31fc5c2706073df896156c5420ae8fa2a5d48dbc7b295d71b"
+checksum = "d8bf9b361eaf5a7627647270fabf1dc910d993edbeaf272a652c107861ebe9c2"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -177,9 +177,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.111.0"
+version = "0.113.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cf5e2484ab47fe38a3150747cdd2016535f13542a925acca152b63383a6591b"
+checksum = "30ca5c38fa00c0cd943035391bdcc84ed00748f17c66c682e410f5a62f234d44"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -213,9 +213,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "gimli"
-version = "0.29.0"
+version = "0.31.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 dependencies = [
  "fallible-iterator",
  "indexmap",
@@ -224,15 +224,6 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
-dependencies = [
- "ahash",
-]
-
-[[package]]
-name = "hashbrown"
 version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
@@ -247,7 +238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
 dependencies = [
  "equivalent",
- "hashbrown 0.14.5",
+ "hashbrown",
 ]
 
 [[package]]
@@ -273,10 +264,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
 [[package]]
-name = "mach"
-version = "0.3.2"
+name = "mach2"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
+checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
 dependencies = [
  "libc",
 ]
@@ -294,7 +285,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
 dependencies = [
  "crc32fast",
- "hashbrown 0.14.5",
+ "hashbrown",
  "indexmap",
  "memchr",
 ]
@@ -325,11 +316,11 @@ dependencies = [
 
 [[package]]
 name = "regalloc2"
-version = "0.9.3"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6"
+checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
 dependencies = [
- "hashbrown 0.13.2",
+ "hashbrown",
  "log",
  "rustc-hash",
  "slice-group-by",
@@ -338,21 +329,21 @@ dependencies = [
 
 [[package]]
 name = "region"
-version = "2.2.0"
+version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0"
+checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7"
 dependencies = [
  "bitflags",
  "libc",
- "mach",
- "winapi",
+ "mach2",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
 name = "rustc-hash"
-version = "1.1.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
 
 [[package]]
 name = "rustc_codegen_cranelift"
@@ -421,43 +412,30 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "wasmtime-jit-icache-coherence"
-version = "24.0.0"
+version = "26.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d15de8429db996f0d17a4163a35eccc3f874cbfb50f29c379951ea1bbb39452e"
+checksum = "6e458e6a1a010a53f86ac8d75837c0c6b2ce3e54b7503b2f1dc5629a4a541f5a"
 dependencies = [
  "anyhow",
  "cfg-if",
  "libc",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
-name = "winapi"
-version = "0.3.9"
+name = "windows-sys"
+version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
+ "windows-targets",
 ]
 
 [[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
 name = "windows-sys"
-version = "0.52.0"
+version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
  "windows-targets",
 ]
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index 6594ffb5d66..f352ef72cb0 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,14 +8,14 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.111.0", default-features = false, features = ["std", "unwind", "all-arch"] }
-cranelift-frontend = { version = "0.111.0" }
-cranelift-module = { version = "0.111.0" }
-cranelift-native = { version = "0.111.0" }
-cranelift-jit = { version = "0.111.0", optional = true }
-cranelift-object = { version = "0.111.0" }
+cranelift-codegen = { version = "0.113.0", default-features = false, features = ["std", "unwind", "all-native-arch"] }
+cranelift-frontend = { version = "0.113.0" }
+cranelift-module = { version = "0.113.0" }
+cranelift-native = { version = "0.113.0" }
+cranelift-jit = { version = "0.113.0", optional = true }
+cranelift-object = { version = "0.113.0" }
 target-lexicon = "0.12.0"
-gimli = { version = "0.29", default-features = false, features = ["write"] }
+gimli = { version = "0.31", default-features = false, features = ["write"] }
 object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
 
 indexmap = "2.0.0"
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
index 82558999afa..f1f4489bcbc 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
@@ -102,15 +102,6 @@ pub(crate) fn build_sysroot(
         .install_into_sysroot(&dist_dir);
     }
 
-    // Copy std for the host to the lib dir. This is necessary for the jit mode to find
-    // libstd.
-    for lib in host.libs {
-        let filename = lib.file_name().unwrap().to_str().unwrap();
-        if filename.contains("std-") && !filename.contains(".rlib") {
-            try_hard_link(&lib, dist_dir.join("lib").join(lib.file_name().unwrap()));
-        }
-    }
-
     let mut target_compiler = {
         let rustc_clif = dist_dir.join(wrapper_base_name.replace("____", "rustc-clif"));
         let rustdoc_clif = dist_dir.join(wrapper_base_name.replace("____", "rustdoc-clif"));
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index 30bd7ae26a1..c6f979f0278 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -1,8 +1,8 @@
 use std::ffi::OsStr;
-use std::fs;
 use std::hash::{Hash, Hasher};
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::{fs, io};
 
 use crate::path::{Dirs, RelPath};
 use crate::utils::{copy_dir_recursively, ensure_empty_dir, spawn_and_wait};
@@ -89,6 +89,19 @@ impl GitRepo {
         }
     }
 
+    fn verify_checksum(&self, dirs: &Dirs) {
+        let download_dir = self.download_dir(dirs);
+        let actual_hash = format!("{:016x}", hash_dir(&download_dir));
+        if actual_hash != self.content_hash {
+            eprintln!(
+                "Mismatched content hash for {download_dir}: {actual_hash} != {content_hash}. Please run ./y.sh prepare again.",
+                download_dir = download_dir.display(),
+                content_hash = self.content_hash,
+            );
+            std::process::exit(1);
+        }
+    }
+
     pub(crate) fn fetch(&self, dirs: &Dirs) {
         let download_dir = self.download_dir(dirs);
 
@@ -126,18 +139,11 @@ impl GitRepo {
             assert!(target_lockfile.exists());
         }
 
-        let actual_hash = format!("{:016x}", hash_dir(&download_dir));
-        if actual_hash != self.content_hash {
-            eprintln!(
-                "Download of {download_dir} failed with mismatched content hash: {actual_hash} != {content_hash}",
-                download_dir = download_dir.display(),
-                content_hash = self.content_hash,
-            );
-            std::process::exit(1);
-        }
+        self.verify_checksum(dirs);
     }
 
     pub(crate) fn patch(&self, dirs: &Dirs) {
+        self.verify_checksum(dirs);
         apply_patches(
             dirs,
             self.patch_name,
@@ -149,6 +155,13 @@ impl GitRepo {
 
 fn clone_repo(download_dir: &Path, repo: &str, rev: &str) {
     eprintln!("[CLONE] {}", repo);
+
+    match fs::remove_dir_all(download_dir) {
+        Ok(()) => {}
+        Err(err) if err.kind() == io::ErrorKind::NotFound => {}
+        Err(err) => panic!("Failed to remove {path}: {err}", path = download_dir.display()),
+    }
+
     // Ignore exit code as the repo may already have been checked out
     git_command(None, "clone").arg(repo).arg(download_dir).spawn().unwrap().wait().unwrap();
 
diff --git a/compiler/rustc_codegen_cranelift/patches/0002-abi-cafe-Disable-broken-tests.patch b/compiler/rustc_codegen_cranelift/patches/0002-abi-cafe-Disable-broken-tests.patch
index 8a2565f1668..01b6a990b72 100644
--- a/compiler/rustc_codegen_cranelift/patches/0002-abi-cafe-Disable-broken-tests.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0002-abi-cafe-Disable-broken-tests.patch
@@ -7,11 +7,23 @@ Subject: [PATCH] Disable broken tests
  src/report.rs | 36 ++++++++++++++++++++++++++++++++++++
  1 file changed, 36 insertions(+)
 
+diff --git a/src/toolchains/rust.rs b/src/toolchains/rust.rs
+index 0c50f7a..bfde2b1 100644
+--- a/src/toolchains/rust.rs
++++ b/src/toolchains/rust.rs
+@@ -83,6 +83,7 @@ impl Toolchain for RustcToolchain {
+             .arg(out_dir)
+             .arg("--target")
+             .arg(built_info::TARGET)
++            .arg("-g")
+             .arg(format!("-Cmetadata={lib_name}"))
+             .arg(src_path);
+         if let Some(codegen_backend) = &self.codegen_backend {
 diff --git a/src/report.rs b/src/report.rs
 index 958ab43..dcf1044 100644
 --- a/src/report.rs
 +++ b/src/report.rs
-@@ -48,6 +48,58 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn Toolchain, callee: &dyn Toolc
+@@ -48,6 +48,40 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn Toolchain, callee: &dyn Toolc
      //
      // THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES
  
@@ -19,10 +31,6 @@ index 958ab43..dcf1044 100644
 +        if test.test == "F32Array" && test.options.convention == CallingConvention::C {
 +            result.check = Busted(Check);
 +        }
-+
-+        if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::C {
-+            result.check = Busted(Check);
-+        }
 +    }
 +
 +    if cfg!(all(target_arch = "aarch64", target_os = "macos")) {
@@ -39,21 +47,7 @@ index 958ab43..dcf1044 100644
 +        }
 +    }
 +
-+    if cfg!(all(target_arch = "x86_64", unix)) {
-+        if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::Rust {
-+            result.check = Busted(Run);
-+        }
-+    }
-+
 +    if cfg!(all(target_arch = "x86_64", windows)) {
-+        if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust {
-+            result.check = Busted(Check);
-+        }
-+
-+        if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust && (test.caller == "rustc" || test.options.repr == LangRepr::Rust) {
-+            result.check = Busted(Run);
-+        }
-+
 +        if test.test == "simple" && test.options.convention == CallingConvention::Rust {
 +            result.check = Busted(Check);
 +        }
diff --git a/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch b/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch
index 5117b04fd34..6ed22c5a18e 100644
--- a/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch
@@ -38,7 +38,7 @@ index 42a26ae..5ac1042 100644
 @@ -1,3 +1,4 @@
 +#![cfg(test)]
  // tidy-alphabetical-start
- #![cfg_attr(bootstrap, feature(const_mut_refs))]
- #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
+ #![cfg_attr(bootstrap, feature(strict_provenance))]
+ #![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 --
 2.21.0 (Apple Git-122)
diff --git a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
index efd721d9df8..50a42aea322 100644
--- a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
@@ -14,13 +14,14 @@ diff --git a/lib.rs b/lib.rs
 index 1e336bf..35e6f54 100644
 --- a/lib.rs
 +++ b/lib.rs
-@@ -1,6 +1,5 @@
- #![cfg(test)]
+@@ -2,7 +2,6 @@
  // tidy-alphabetical-start
- #![cfg_attr(bootstrap, feature(const_mut_refs))]
+ #![cfg_attr(bootstrap, feature(strict_provenance))]
+ #![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
  #![cfg_attr(test, feature(cfg_match))]
  #![feature(alloc_layout_extra)]
+ #![feature(array_chunks)]
 diff --git a/atomic.rs b/atomic.rs
 index b735957..ea728b6 100644
 --- a/atomic.rs
diff --git a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
index d7204add7a7..b98326c54a6 100644
--- a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch
@@ -12,7 +12,7 @@ index 8402833..84592e0 100644
 --- a/slice.rs
 +++ b/slice.rs
 @@ -1809,6 +1809,7 @@ fn sort_unstable() {
-     assert!(v == [0xDEADBEEF]);
+     }
  }
  
 +/*
@@ -43,26 +43,6 @@ index 8402833..84592e0 100644
  
  #[test]
  fn test_slice_from_ptr_range() {
-diff --git a/lazy.rs b/lazy.rs
-index 711511e..49c8d78 100644
---- a/lazy.rs
-+++ b/lazy.rs
-@@ -113,6 +113,7 @@ fn lazy_type_inference() {
-     let _ = LazyCell::new(|| ());
- }
- 
-+/*
- #[test]
- #[should_panic = "LazyCell instance has previously been poisoned"]
- fn lazy_force_mut_panic() {
-@@ -123,6 +124,7 @@ fn lazy_force_mut_panic() {
-     .unwrap_err();
-     let _ = &*lazy;
- }
-+*/
- 
- #[test]
- fn lazy_force_mut() {
 -- 
 2.26.2.7.g19db9cfb68
 
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 651770be377..2558b2b9f5d 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-09-23"
+channel = "nightly-2024-11-02"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
 profile = "minimal"
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index 93512f82c8b..a820da286f5 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -47,9 +47,6 @@ rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support
 rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support
 rm tests/ui/delegation/fn-header.rs
 
-# unsized locals
-rm -r tests/run-pass-valgrind/unsized-locals
-
 # misc unimplemented things
 rm tests/ui/target-feature/missing-plusminus.rs # error not implemented
 rm -r tests/run-make/repr128-dwarf # debuginfo test
@@ -148,6 +145,7 @@ rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # same
 rm tests/ui/process/process-panic-after-fork.rs # same
 
 cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist
+cp $(../dist/rustc-clif --print target-libdir)/libstd-*.so ../dist/lib/
 
 # prevent $(RUSTDOC) from picking up the sysroot built by x.py. It conflicts with the one used by
 # rustdoc-clif
@@ -180,92 +178,20 @@ index 9607ff02f96..b7d97caf9a2 100644
          Self { cmd }
      }
 
-diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
-index 2047345d78a..a7e9352bb1c 100644
---- a/src/bootstrap/src/core/build_steps/test.rs
-+++ b/src/bootstrap/src/core/build_steps/test.rs
-@@ -1733,11 +1733,6 @@ fn run(self, builder: &Builder<'_>) {
-
-         let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js");
-
--        if mode == "run-make" {
--            let cargo = builder.ensure(tool::Cargo { compiler, target: compiler.host });
--            cmd.arg("--cargo-path").arg(cargo);
--        }
--
-         // Avoid depending on rustdoc when we don't need it.
-         if mode == "rustdoc"
-             || mode == "run-make"
-diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
-index 414f9f3a7f1..5c18179b6fe 100644
---- a/src/tools/compiletest/src/common.rs
-+++ b/src/tools/compiletest/src/common.rs
-@@ -183,9 +183,6 @@ pub struct Config {
-     /// The rustc executable.
-     pub rustc_path: PathBuf,
-
--    /// The cargo executable.
--    pub cargo_path: Option<PathBuf>,
--
-     /// The rustdoc executable.
-     pub rustdoc_path: Option<PathBuf>,
-
-diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
-index 3339116d542..250b5084d13 100644
---- a/src/tools/compiletest/src/lib.rs
-+++ b/src/tools/compiletest/src/lib.rs
-@@ -47,7 +47,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
-     opts.reqopt("", "compile-lib-path", "path to host shared libraries", "PATH")
-         .reqopt("", "run-lib-path", "path to target shared libraries", "PATH")
-         .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH")
--        .optopt("", "cargo-path", "path to cargo to use for compiling", "PATH")
-         .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
-         .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
-         .reqopt("", "python", "path to python to use for doc tests", "PATH")
-@@ -261,7 +260,6 @@ fn make_absolute(path: PathBuf) -> PathBuf {
-         compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
-         run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
-         rustc_path: opt_path(matches, "rustc-path"),
--        cargo_path: matches.opt_str("cargo-path").map(PathBuf::from),
-         rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from),
-         coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from),
-         python: matches.opt_str("python").unwrap(),
-@@ -366,7 +364,6 @@ pub fn log_config(config: &Config) {
-     logv(c, format!("compile_lib_path: {:?}", config.compile_lib_path));
-     logv(c, format!("run_lib_path: {:?}", config.run_lib_path));
-     logv(c, format!("rustc_path: {:?}", config.rustc_path.display()));
--    logv(c, format!("cargo_path: {:?}", config.cargo_path));
-     logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path));
-     logv(c, format!("src_base: {:?}", config.src_base.display()));
-     logv(c, format!("build_base: {:?}", config.build_base.display()));
 diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
-index 75fe6a6baaf..852568ae925 100644
+index e7ae773ffa1d3..04bc2d7787da7 100644
 --- a/src/tools/compiletest/src/runtest/run_make.rs
 +++ b/src/tools/compiletest/src/runtest/run_make.rs
-@@ -61,10 +61,6 @@ fn run_rmake_legacy_test(&self) {
-             .env_remove("MFLAGS")
-             .env_remove("CARGO_MAKEFLAGS");
-
--        if let Some(ref cargo) = self.config.cargo_path {
--            cmd.env("CARGO", cwd.join(cargo));
--        }
--
-         if let Some(ref rustdoc) = self.config.rustdoc_path {
-             cmd.env("RUSTDOC", cwd.join(rustdoc));
-         }
-@@ -413,10 +409,6 @@ fn run_rmake_v2_test(&self) {
-             // through a specific CI runner).
-             .env("LLVM_COMPONENTS", &self.config.llvm_components);
+@@ -329,7 +329,6 @@ impl TestCx<'_> {
+             .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
+             .arg("--edition=2021")
+             .arg(&self.testpaths.file.join("rmake.rs"))
+-            .arg("-Cprefer-dynamic")
+             // Provide necessary library search paths for rustc.
+             .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
 
--        if let Some(ref cargo) = self.config.cargo_path {
--            cmd.env("CARGO", source_root.join(cargo));
--        }
--
-         if let Some(ref rustdoc) = self.config.rustdoc_path {
-             cmd.env("RUSTDOC", source_root.join(rustdoc));
-         }
 EOF
 
 echo "[TEST] rustc test suite"
-COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 --test-args=--nocapture tests/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
+COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 --test-args=--nocapture tests/{codegen-units,run-make,ui,incremental}
 popd
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 089b09d06ae..dfca5dcbec8 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -389,7 +389,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
                 let callee = with_no_trimmed_paths!(fx.tcx.def_path_str(def_id));
                 fx.tcx.dcx().emit_err(CompilerBuiltinsCannotCall { caller, callee });
             } else {
-                fx.bcx.ins().trap(TrapCode::User(0));
+                fx.bcx.ins().trap(TrapCode::user(2).unwrap());
                 return;
             }
         }
@@ -562,6 +562,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
             adjust_call_for_c_variadic(fx, &fn_abi, source_info, func_ref, &mut call_args);
         }
 
+        if fx.clif_comments.enabled() {
+            let nop_inst = fx.bcx.ins().nop();
+            with_no_trimmed_paths!(fx.add_comment(nop_inst, format!("abi: {:?}", fn_abi)));
+        }
+
         match func_ref {
             CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args),
             CallTarget::Indirect(sig, func_ptr) => {
@@ -574,7 +579,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
         let ret_block = fx.get_block(dest);
         fx.bcx.ins().jump(ret_block, &[]);
     } else {
-        fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+        fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
     }
 
     fn adjust_call_for_c_variadic<'tcx>(
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 99e39971b74..10d5dce9b36 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -103,12 +103,12 @@ pub(crate) fn codegen_fn<'tcx>(
     let block_map: IndexVec<BasicBlock, Block> =
         (0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect();
 
+    let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty());
+
     // Make FunctionCx
     let target_config = module.target_config();
     let pointer_type = target_config.pointer_type();
-    let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
-
-    let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty());
+    let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance, fn_abi);
 
     let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
         Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span))
@@ -294,7 +294,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
     if arg_uninhabited {
         fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
         fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
-        fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+        fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
         return;
     }
     fx.tcx
@@ -311,7 +311,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
         if !reachable_blocks.contains(bb) {
             // We want to skip this block, because it's not reachable. But we still create
             // the block so terminators in other blocks can reference it.
-            fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+            fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
             continue;
         }
 
@@ -379,7 +379,6 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
 
                 let target = fx.get_block(*target);
                 let failure = fx.bcx.create_block();
-                fx.bcx.set_cold_block(failure);
 
                 if *expected {
                     fx.bcx.ins().brif(cond, target, &[], failure, &[]);
@@ -541,10 +540,11 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
             }
             TerminatorKind::UnwindResume => {
                 // FIXME implement unwinding
-                fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+                fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
             }
             TerminatorKind::Unreachable => {
-                fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+                fx.bcx.set_cold_block(block);
+                fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
             }
             TerminatorKind::Yield { .. }
             | TerminatorKind::FalseEdge { .. }
@@ -1075,12 +1075,14 @@ fn codegen_panic_inner<'tcx>(
     args: &[Value],
     span: Option<Span>,
 ) {
+    fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
+
     let def_id = fx.tcx.require_lang_item(lang_item, span);
 
     let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
 
     if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) {
-        fx.bcx.ins().trap(TrapCode::User(0));
+        fx.bcx.ins().trap(TrapCode::user(2).unwrap());
         return;
     }
 
@@ -1093,5 +1095,5 @@ fn codegen_panic_inner<'tcx>(
         args,
     );
 
-    fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+    fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
 }
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
index c3d9d635084..fa7b39c836f 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
@@ -50,7 +50,12 @@ fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
     if hash.kind == SourceFileHashAlgorithm::Md5 {
         let mut buf = [0u8; MD5_LEN];
         buf.copy_from_slice(hash.hash_bytes());
-        Some(FileInfo { timestamp: 0, size: 0, md5: buf })
+        Some(FileInfo {
+            timestamp: 0,
+            size: 0,
+            md5: buf,
+            source: None, // FIXME implement -Zembed-source
+        })
     } else {
         None
     }
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
index 79d76925df9..78ae43b1c4d 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
@@ -101,6 +101,7 @@ impl DebugContext {
             None => (tcx.crate_name(LOCAL_CRATE).to_string(), None),
         };
 
+        let file_has_md5 = file_info.is_some();
         let mut line_program = LineProgram::new(
             encoding,
             LineEncoding::default(),
@@ -108,7 +109,7 @@ impl DebugContext {
             LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings),
             file_info,
         );
-        line_program.file_has_md5 = file_info.is_some();
+        line_program.file_has_md5 = file_has_md5;
 
         dwarf.unit.line_program = line_program;
 
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
index 9399230f292..362333d35a4 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
@@ -60,8 +60,8 @@ impl UnwindContext {
                 self.frame_table
                     .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id)));
             }
-            UnwindInfo::WindowsX64(_) => {
-                // FIXME implement this
+            UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => {
+                // Windows does not have debug info for its unwind info.
             }
             unwind_info => unimplemented!("{:?}", unwind_info),
         }
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
index 0c99a5ce12f..6f90d17920d 100644
--- a/compiler/rustc_codegen_cranelift/src/global_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -118,8 +118,8 @@ impl GlobalAsmConfig {
         GlobalAsmConfig {
             assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
             target: match &tcx.sess.opts.target_triple {
-                rustc_target::spec::TargetTriple::TargetTriple(triple) => triple.clone(),
-                rustc_target::spec::TargetTriple::TargetJson { path_for_rustdoc, .. } => {
+                rustc_target::spec::TargetTuple::TargetTuple(triple) => triple.clone(),
+                rustc_target::spec::TargetTuple::TargetJson { path_for_rustdoc, .. } => {
                     path_for_rustdoc.to_str().unwrap().to_owned()
                 }
             },
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 41f1b30d10b..0fbd5a16830 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -47,7 +47,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
     // asm!() by accident and breaks with the GNU assembler as well as global_asm!() for
     // the LLVM backend.
     if template.len() == 1 && template[0] == InlineAsmTemplatePiece::String("int $$0x29".into()) {
-        fx.bcx.ins().trap(TrapCode::User(1));
+        fx.bcx.ins().trap(TrapCode::user(2).unwrap());
         return;
     }
 
@@ -137,7 +137,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
             fx.bcx.ins().jump(destination_block, &[]);
         }
         None => {
-            fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+            fx.bcx.ins().trap(TrapCode::user(0 /* unreachable */).unwrap());
         }
     }
 }
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index aae6794891d..e5a12162687 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -47,7 +47,7 @@ fn report_atomic_type_validation_error<'tcx>(
         ),
     );
     // Prevent verifier error
-    fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+    fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
 }
 
 pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Type {
@@ -449,7 +449,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
     match intrinsic {
         sym::abort => {
-            fx.bcx.ins().trap(TrapCode::User(0));
+            fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
+            fx.bcx.ins().trap(TrapCode::user(2).unwrap());
             return Ok(());
         }
         sym::likely | sym::unlikely => {
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index e7f9f894381..16fb68a7bdf 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -14,7 +14,7 @@ fn report_simd_type_validation_error(
 ) {
     fx.tcx.dcx().span_err(span, format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
     // Prevent verifier error
-    fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+    fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
 }
 
 pub(super) fn codegen_simd_intrinsic_call<'tcx>(
@@ -190,7 +190,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                     format!("simd_shuffle index must be a SIMD vector of `u32`, got `{}`", idx_ty),
                 );
                 // Prevent verifier error
-                fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+                fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
                 return;
             };
             let n: u16 = idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap();
@@ -1135,7 +1135,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
         _ => {
             fx.tcx.dcx().span_err(span, format!("Unknown SIMD intrinsic {}", intrinsic));
             // Prevent verifier error
-            fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+            fx.bcx.ins().trap(TrapCode::user(0 /* unreachable */).unwrap());
             return;
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index fc3bd0abd78..aba0c28f6b8 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -302,8 +302,11 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn TargetIs
         OptLevel::No => {
             flags_builder.set("opt_level", "none").unwrap();
         }
-        OptLevel::Less | OptLevel::Default => {}
-        OptLevel::Size | OptLevel::SizeMin | OptLevel::Aggressive => {
+        OptLevel::Less
+        | OptLevel::Default
+        | OptLevel::Size
+        | OptLevel::SizeMin
+        | OptLevel::Aggressive => {
             flags_builder.set("opt_level", "speed_and_size").unwrap();
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
index 13877b3b1e9..282763279dd 100644
--- a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
+++ b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs
@@ -62,9 +62,9 @@ use cranelift_codegen::entity::SecondaryMap;
 use cranelift_codegen::ir::Fact;
 use cranelift_codegen::ir::entities::AnyEntity;
 use cranelift_codegen::write::{FuncWriter, PlainWriter};
-use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_session::config::{OutputFilenames, OutputType};
+use rustc_target::abi::call::FnAbi;
 
 use crate::prelude::*;
 
@@ -76,17 +76,18 @@ pub(crate) struct CommentWriter {
 }
 
 impl CommentWriter {
-    pub(crate) fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
+    pub(crate) fn new<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        instance: Instance<'tcx>,
+        fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
+    ) -> Self {
         let enabled = should_write_ir(tcx);
         let global_comments = if enabled {
             with_no_trimmed_paths!({
                 vec![
                     format!("symbol {}", tcx.symbol_name(instance).name),
                     format!("instance {:?}", instance),
-                    format!(
-                        "abi {:?}",
-                        RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())
-                    ),
+                    format!("abi {:?}", fn_abi),
                     String::new(),
                 ]
             })
diff --git a/compiler/rustc_codegen_cranelift/src/trap.rs b/compiler/rustc_codegen_cranelift/src/trap.rs
index a61e1e334ec..9ef1a523d6d 100644
--- a/compiler/rustc_codegen_cranelift/src/trap.rs
+++ b/compiler/rustc_codegen_cranelift/src/trap.rs
@@ -30,5 +30,5 @@ pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRe
     let one = fx.bcx.ins().iconst(types::I32, 1);
     fx.lib_call("exit", vec![AbiParam::new(types::I32)], vec![], &[one]);
 
-    fx.bcx.ins().trap(TrapCode::User(!0));
+    fx.bcx.ins().trap(TrapCode::user(3).unwrap());
 }
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index 3029b934179..660badb6a50 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -146,7 +146,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
 
         // Wasm statics with custom link sections get special treatment as they
         // go into custom sections of the wasm executable.
-        if self.tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
+        if self.tcx.sess.opts.target_triple.tuple().starts_with("wasm32") {
             if let Some(_section) = attrs.link_section {
                 unimplemented!();
             }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 01e2c308ca4..647e9e13fbc 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -946,7 +946,7 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
 }
 
 fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
-    let triple = cgcx.opts.target_triple.triple();
+    let triple = cgcx.opts.target_triple.tuple();
     triple.contains("-ios")
         || triple.contains("-darwin")
         || triple.contains("-tvos")
@@ -955,7 +955,7 @@ fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
 }
 
 fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
-    cgcx.opts.target_triple.triple().contains("-aix")
+    cgcx.opts.target_triple.tuple().contains("-aix")
 }
 
 pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) -> &'static CStr {
@@ -1031,7 +1031,7 @@ unsafe fn embed_bitcode(
     let is_aix = target_is_aix(cgcx);
     let is_apple = target_is_apple(cgcx);
     unsafe {
-        if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") {
+        if is_apple || is_aix || cgcx.opts.target_triple.tuple().starts_with("wasm") {
             // We don't need custom section flags, create LLVM globals.
             let llconst = common::bytes_in_context(llcx, bitcode);
             let llglobal = llvm::LLVMAddGlobal(
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index b01a62b394b..20920d16f3c 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -997,7 +997,7 @@ fn link_natively(
                     {
                         let is_vs_installed = windows_registry::find_vs_version().is_ok();
                         let has_linker = windows_registry::find_tool(
-                            sess.opts.target_triple.triple(),
+                            sess.opts.target_triple.tuple(),
                             "link.exe",
                         )
                         .is_some();
@@ -1323,10 +1323,8 @@ fn link_sanitizer_runtime(
         } else {
             let default_sysroot =
                 filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
-            let default_tlib = filesearch::make_target_lib_path(
-                &default_sysroot,
-                sess.opts.target_triple.triple(),
-            );
+            let default_tlib =
+                filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.tuple());
             default_tlib
         }
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index c4bb82d0dd7..3b4429535d4 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -47,7 +47,7 @@ pub(crate) fn get_linker<'a>(
     self_contained: bool,
     target_cpu: &'a str,
 ) -> Box<dyn Linker + 'a> {
-    let msvc_tool = windows_registry::find_tool(sess.opts.target_triple.triple(), "link.exe");
+    let msvc_tool = windows_registry::find_tool(sess.opts.target_triple.tuple(), "link.exe");
 
     // If our linker looks like a batch script on Windows then to execute this
     // we'll need to spawn `cmd` explicitly. This is primarily done to handle
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 92b622fccf2..4362007d4ba 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -62,7 +62,7 @@ use rustc_session::{EarlyDiagCtxt, Session, config, filesearch};
 use rustc_span::FileName;
 use rustc_span::source_map::FileLoader;
 use rustc_target::json::ToJson;
-use rustc_target::spec::{Target, TargetTriple};
+use rustc_target::spec::{Target, TargetTuple};
 use time::OffsetDateTime;
 use tracing::trace;
 
@@ -731,6 +731,7 @@ fn print_crate_info(
                 targets.sort_unstable();
                 println_info!("{}", targets.join("\n"));
             }
+            HostTuple => println_info!("{}", rustc_session::config::host_tuple()),
             Sysroot => println_info!("{}", sess.sysroot.display()),
             TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
             TargetSpec => {
@@ -739,7 +740,7 @@ fn print_crate_info(
             AllTargetSpecs => {
                 let mut targets = BTreeMap::new();
                 for name in rustc_target::spec::TARGETS {
-                    let triple = TargetTriple::from_triple(name);
+                    let triple = TargetTuple::from_tuple(name);
                     let target = Target::expect_builtin(&triple);
                     targets.insert(name, target.to_json());
                 }
@@ -918,7 +919,7 @@ pub fn version_at_macro_invocation(
         safe_println!("binary: {binary}");
         safe_println!("commit-hash: {commit_hash}");
         safe_println!("commit-date: {commit_date}");
-        safe_println!("host: {}", config::host_triple());
+        safe_println!("host: {}", config::host_tuple());
         safe_println!("release: {release}");
 
         let debug_flags = matches.opt_strs("Z");
@@ -1495,7 +1496,7 @@ fn report_ice(
     }
 
     let version = util::version_str!().unwrap_or("unknown_version");
-    let triple = config::host_triple();
+    let tuple = config::host_tuple();
 
     static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 
@@ -1505,7 +1506,7 @@ fn report_ice(
             Ok(mut file) => {
                 dcx.emit_note(session_diagnostics::IcePath { path: path.clone() });
                 if FIRST_PANIC.swap(false, Ordering::SeqCst) {
-                    let _ = write!(file, "\n\nrustc version: {version}\nplatform: {triple}");
+                    let _ = write!(file, "\n\nrustc version: {version}\nplatform: {tuple}");
                 }
                 Some(file)
             }
@@ -1518,12 +1519,12 @@ fn report_ice(
                         .map(PathBuf::from)
                         .map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }),
                 });
-                dcx.emit_note(session_diagnostics::IceVersion { version, triple });
+                dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple });
                 None
             }
         }
     } else {
-        dcx.emit_note(session_diagnostics::IceVersion { version, triple });
+        dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple });
         None
     };
 
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 09a608dda7b..798668b8bc1 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -11,7 +11,7 @@ use rustc_macros::Subdiagnostic;
 use rustc_span::Span;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
-use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
+use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTuple};
 use rustc_type_ir::{ClosureKind, FloatTy};
 use {rustc_ast as ast, rustc_hir as hir};
 
@@ -89,7 +89,7 @@ into_diag_arg_using_display!(
     MacroRulesNormalizedIdent,
     ParseIntError,
     StackProtector,
-    &TargetTriple,
+    &TargetTuple,
     SplitDebuginfo,
     ExitStatus,
     ErrCode,
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 8d8573c65c5..97f3807c252 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -643,7 +643,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
     fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result {
         // Try to replace `_` with `()`.
         if let hir::TyKind::Infer = hir_ty.kind
-            && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id)
+            && let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
             && let Some(vid) = self.fcx.root_vid(ty)
             && self.reachable_vids.contains(&vid)
         {
@@ -680,7 +680,8 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
         if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
             && let Res::Def(DefKind::AssocFn, def_id) = path.res
             && self.fcx.tcx.trait_of_item(def_id).is_some()
-            && let self_ty = self.fcx.typeck_results.borrow().node_args(expr.hir_id).type_at(0)
+            && let Some(args) = self.fcx.typeck_results.borrow().node_args_opt(expr.hir_id)
+            && let self_ty = args.type_at(0)
             && let Some(vid) = self.fcx.root_vid(self_ty)
             && self.reachable_vids.contains(&vid)
             && let [.., trait_segment, _method_segment] = path.segments
@@ -701,7 +702,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
     fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result {
         // For a local, try suggest annotating the type if it's missing.
         if let None = local.ty
-            && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id)
+            && let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(local.hir_id)
             && let Some(vid) = self.fcx.root_vid(ty)
             && self.reachable_vids.contains(&vid)
         {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 85e11ff6745..d8b63eef577 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -493,7 +493,7 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
         "we would appreciate a joke overview: \
          https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
     );
-    diag.note(format!("rustc {} running on {}", tcx.sess.cfg_version, config::host_triple(),));
+    diag.note(format!("rustc {} running on {}", tcx.sess.cfg_version, config::host_tuple(),));
     if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() {
         diag.note(format!("compiler flags: {}", flags.join(" ")));
         if excluded_cargo_defaults {
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 71e8accf5a3..b5bddc4b21a 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::sync;
 use rustc_metadata::{DylibError, load_symbol_from_dylib};
 use rustc_middle::ty::CurrentGcx;
 use rustc_parse::validate_attr;
-use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_triple};
+use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_tuple};
 use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
 use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
@@ -310,7 +310,7 @@ fn get_codegen_sysroot(
         "cannot load the default codegen backend twice"
     );
 
-    let target = host_triple();
+    let target = host_tuple();
     let sysroot_candidates = sysroot_candidates();
 
     let sysroot = iter::once(sysroot)
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 3b7dc6de825..aef87e49053 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -777,10 +777,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
-  // FIXME: We may want to expose this as an option.
-  bool DebugPassManager = false;
-
-  StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
+  StandardInstrumentations SI(TheModule->getContext(),
+                              /*DebugLogging=*/false);
   SI.registerCallbacks(PIC, &MAM);
 
   if (LLVMPluginsLen) {
@@ -825,9 +823,9 @@ extern "C" LLVMRustResult LLVMRustOptimize(
       !NoPrepopulatePasses) {
     PipelineStartEPCallbacks.push_back(
         [](ModulePassManager &MPM, OptimizationLevel Level) {
-          MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
-                                         /*ImportSummary=*/nullptr,
-                                         /*DropTypeTests=*/false));
+          MPM.addPass(LowerTypeTestsPass(
+              /*ExportSummary=*/nullptr,
+              /*ImportSummary=*/nullptr));
         });
   }
 
@@ -932,8 +930,9 @@ extern "C" LLVMRustResult LLVMRustOptimize(
       for (const auto &C : OptimizerLastEPCallbacks)
         PB.registerOptimizerLastEPCallback(C);
 
-      // Pass false as we manually schedule ThinLTOBufferPasses below.
-      MPM = PB.buildO0DefaultPipeline(OptLevel, /* PreLinkLTO */ false);
+      // We manually schedule ThinLTOBufferPasses below, so don't pass the value
+      // to enable it here.
+      MPM = PB.buildO0DefaultPipeline(OptLevel);
     } else {
       for (const auto &C : PipelineStartEPCallbacks)
         PB.registerPipelineStartEPCallback(C);
@@ -942,7 +941,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
 
       switch (OptStage) {
       case LLVMRustOptStage::PreLinkNoLTO:
-        MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
+        MPM = PB.buildPerModuleDefaultPipeline(OptLevel);
         break;
       case LLVMRustOptStage::PreLinkThinLTO:
         MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel);
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index d2be6ae8d69..e525d94a0c1 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -30,7 +30,7 @@ use rustc_session::search_paths::PathKind;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, Symbol, sym};
 use rustc_span::{DUMMY_SP, Span};
-use rustc_target::spec::{PanicStrategy, Target, TargetTriple};
+use rustc_target::spec::{PanicStrategy, Target, TargetTuple};
 use tracing::{debug, info, trace};
 
 use crate::errors;
@@ -506,7 +506,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         locator.reset();
         locator.is_proc_macro = true;
         locator.target = &self.sess.host;
-        locator.triple = TargetTriple::from_triple(config::host_triple());
+        locator.tuple = TargetTuple::from_tuple(config::host_tuple());
         locator.filesearch = self.sess.host_filesearch(path_kind);
 
         let Some(host_result) = self.load(locator)? else {
@@ -635,7 +635,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         // FIXME: why is this condition necessary? It was adding in #33625 but I
         // don't know why and the original author doesn't remember ...
         let can_reuse_cratenum =
-            locator.triple == self.sess.opts.target_triple || locator.is_proc_macro;
+            locator.tuple == self.sess.opts.target_triple || locator.is_proc_macro;
         Ok(Some(if can_reuse_cratenum {
             let mut result = LoadResult::Loaded(library);
             for (cnum, data) in self.cstore.iter_crate_data() {
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 6587125ec67..16684ae6f26 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -5,7 +5,7 @@ use rustc_errors::codes::*;
 use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::spec::{PanicStrategy, TargetTriple};
+use rustc_target::spec::{PanicStrategy, TargetTuple};
 
 use crate::fluent_generated as fluent;
 use crate::locator::CrateFlavor;
@@ -630,7 +630,7 @@ pub struct CannotFindCrate {
     pub current_crate: String,
     pub is_nightly_build: bool,
     pub profiler_runtime: Symbol,
-    pub locator_triple: TargetTriple,
+    pub locator_triple: TargetTuple,
     pub is_ui_testing: bool,
 }
 
@@ -641,7 +641,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
         diag.arg("crate_name", self.crate_name);
         diag.arg("current_crate", self.current_crate);
         diag.arg("add_info", self.add_info);
-        diag.arg("locator_triple", self.locator_triple.triple());
+        diag.arg("locator_triple", self.locator_triple.tuple());
         diag.code(E0463);
         diag.span(self.span);
         if self.crate_name == sym::std || self.crate_name == sym::core {
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index f924ed48b6f..ddd97fc66f6 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -231,7 +231,7 @@ use rustc_session::search_paths::PathKind;
 use rustc_session::utils::CanonicalizedPath;
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
-use rustc_target::spec::{Target, TargetTriple};
+use rustc_target::spec::{Target, TargetTuple};
 use tracing::{debug, info};
 
 use crate::creader::{Library, MetadataLoader};
@@ -252,7 +252,7 @@ pub(crate) struct CrateLocator<'a> {
     pub hash: Option<Svh>,
     extra_filename: Option<&'a str>,
     pub target: &'a Target,
-    pub triple: TargetTriple,
+    pub tuple: TargetTuple,
     pub filesearch: FileSearch<'a>,
     pub is_proc_macro: bool,
 
@@ -338,7 +338,7 @@ impl<'a> CrateLocator<'a> {
             hash,
             extra_filename,
             target: &sess.target,
-            triple: sess.opts.target_triple.clone(),
+            tuple: sess.opts.target_triple.clone(),
             filesearch: sess.target_filesearch(path_kind),
             is_proc_macro: false,
             crate_rejections: CrateRejections::default(),
@@ -677,8 +677,8 @@ impl<'a> CrateLocator<'a> {
             return None;
         }
 
-        if header.triple != self.triple {
-            info!("Rejecting via crate triple: expected {} got {}", self.triple, header.triple);
+        if header.triple != self.tuple {
+            info!("Rejecting via crate triple: expected {} got {}", self.tuple, header.triple);
             self.crate_rejections.via_triple.push(CrateMismatch {
                 path: libpath.to_path_buf(),
                 got: header.triple.to_string(),
@@ -766,7 +766,7 @@ impl<'a> CrateLocator<'a> {
         CrateError::LocatorCombined(Box::new(CombinedLocatorError {
             crate_name: self.crate_name,
             root,
-            triple: self.triple,
+            triple: self.tuple,
             dll_prefix: self.target.dll_prefix.to_string(),
             dll_suffix: self.target.dll_suffix.to_string(),
             crate_rejections: self.crate_rejections,
@@ -909,7 +909,7 @@ struct CrateRejections {
 pub(crate) struct CombinedLocatorError {
     crate_name: Symbol,
     root: Option<CratePaths>,
-    triple: TargetTriple,
+    triple: TargetTuple,
     dll_prefix: String,
     dll_suffix: String,
     crate_rejections: CrateRejections,
@@ -1034,7 +1034,7 @@ impl CrateError {
                     dcx.emit_err(errors::NoCrateWithTriple {
                         span,
                         crate_name,
-                        locator_triple: locator.triple.triple(),
+                        locator_triple: locator.triple.tuple(),
                         add_info,
                         found_crates,
                     });
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index ebfd3c09fc1..87357b74c41 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -770,7 +770,7 @@ impl MetadataBlob {
                         root.stable_crate_id
                     )?;
                     writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
-                    writeln!(out, "triple {}", root.header.triple.triple())?;
+                    writeln!(out, "triple {}", root.header.triple.tuple())?;
                     writeln!(out, "edition {}", root.edition)?;
                     writeln!(out, "symbol_mangling_version {:?}", root.symbol_mangling_version)?;
                     writeln!(
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index ab878760c00..949e26f5f60 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -38,7 +38,7 @@ use rustc_span::edition::Edition;
 use rustc_span::hygiene::{ExpnIndex, MacroKind, SyntaxContextData};
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
-use rustc_target::spec::{PanicStrategy, TargetTriple};
+use rustc_target::spec::{PanicStrategy, TargetTuple};
 use table::TableBuilder;
 use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
 
@@ -213,7 +213,7 @@ pub(crate) struct ProcMacroData {
 /// If you do modify this struct, also bump the [`METADATA_VERSION`] constant.
 #[derive(MetadataEncodable, MetadataDecodable)]
 pub(crate) struct CrateHeader {
-    pub(crate) triple: TargetTriple,
+    pub(crate) triple: TargetTuple,
     pub(crate) hash: Svh,
     pub(crate) name: Symbol,
     /// Whether this is the header for a proc-macro crate.
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index c49824bb418..43d243b0584 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -1,5 +1,7 @@
 use std::borrow::Cow;
+use std::fs::File;
 use std::hash::{DefaultHasher, Hash, Hasher};
+use std::io::{Read, Write};
 use std::path::PathBuf;
 
 use rustc_errors::pluralize;
@@ -250,8 +252,8 @@ impl<'tcx> TyCtxt<'tcx> {
         }
 
         let width = self.sess.diagnostic_width();
-        let length_limit = width.saturating_sub(30);
-        if regular.len() <= width {
+        let length_limit = width / 2;
+        if regular.len() <= width * 2 / 3 {
             return regular;
         }
         let short = self.ty_string_with_limit(ty, length_limit);
@@ -265,7 +267,20 @@ impl<'tcx> TyCtxt<'tcx> {
         *path = Some(path.take().unwrap_or_else(|| {
             self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
         }));
-        match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) {
+        let Ok(mut file) =
+            File::options().create(true).read(true).append(true).open(&path.as_ref().unwrap())
+        else {
+            return regular;
+        };
+
+        // Do not write the same type to the file multiple times.
+        let mut contents = String::new();
+        let _ = file.read_to_string(&mut contents);
+        if let Some(_) = contents.lines().find(|line| line == &regular) {
+            return short;
+        }
+
+        match write!(file, "{regular}\n") {
             Ok(_) => short,
             Err(_) => regular,
         }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 5ee3b4015eb..bb730592068 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -26,7 +26,7 @@ use rustc_span::{
     FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, sym,
 };
 use rustc_target::spec::{
-    FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTriple,
+    FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
 };
 use tracing::debug;
 
@@ -813,6 +813,7 @@ pub struct PrintRequest {
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum PrintKind {
     FileNames,
+    HostTuple,
     Sysroot,
     TargetLibdir,
     CrateName,
@@ -1116,7 +1117,7 @@ bitflags::bitflags! {
     }
 }
 
-pub fn host_triple() -> &'static str {
+pub fn host_tuple() -> &'static str {
     // Get the host triple out of the build environment. This ensures that our
     // idea of the host triple is the same as for the set of libraries we've
     // actually built. We can't just take LLVM's host triple because they
@@ -1158,7 +1159,7 @@ impl Default for Options {
             output_types: OutputTypes(BTreeMap::new()),
             search_paths: vec![],
             maybe_sysroot: None,
-            target_triple: TargetTriple::from_triple(host_triple()),
+            target_triple: TargetTuple::from_tuple(host_tuple()),
             test: false,
             incremental: None,
             untracked_state_hash: Default::default(),
@@ -1354,7 +1355,7 @@ pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &
             // rust-lang/compiler-team#695. Warn unconditionally on usage to
             // raise awareness of the renaming. This code will be deleted in
             // October 2024.
-            if opts.target_triple.triple() == "wasm32-wasi" {
+            if opts.target_triple.tuple() == "wasm32-wasi" {
                 early_dcx.early_warn(
                     "the `wasm32-wasi` target is being renamed to \
                     `wasm32-wasip1` and the `wasm32-wasi` target will be \
@@ -1945,6 +1946,7 @@ fn collect_print_requests(
         ("crate-name", PrintKind::CrateName),
         ("deployment-target", PrintKind::DeploymentTarget),
         ("file-names", PrintKind::FileNames),
+        ("host-tuple", PrintKind::HostTuple),
         ("link-args", PrintKind::LinkArgs),
         ("native-static-libs", PrintKind::NativeStaticLibs),
         ("relocation-models", PrintKind::RelocationModels),
@@ -2030,16 +2032,16 @@ fn collect_print_requests(
     prints
 }
 
-pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTriple {
+pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
     match matches.opt_str("target") {
         Some(target) if target.ends_with(".json") => {
             let path = Path::new(&target);
-            TargetTriple::from_path(path).unwrap_or_else(|_| {
+            TargetTuple::from_path(path).unwrap_or_else(|_| {
                 early_dcx.early_fatal(format!("target file {path:?} does not exist"))
             })
         }
-        Some(target) => TargetTriple::TargetTriple(target),
-        _ => TargetTriple::from_triple(host_triple()),
+        Some(target) => TargetTuple::TargetTuple(target),
+        _ => TargetTuple::from_tuple(host_tuple()),
     }
 }
 
@@ -3005,7 +3007,7 @@ pub(crate) mod dep_tracking {
     use rustc_span::edition::Edition;
     use rustc_target::spec::{
         CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
-        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTriple,
+        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
         TlsModel, WasmCAbi,
     };
 
@@ -3090,7 +3092,7 @@ pub(crate) mod dep_tracking {
         SanitizerSet,
         CFGuard,
         CFProtection,
-        TargetTriple,
+        TargetTuple,
         Edition,
         LinkerPluginLto,
         ResolveDocLinks,
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
index 31ef2bda4f1..347d298bacc 100644
--- a/compiler/rustc_session/src/config/cfg.rs
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -29,7 +29,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_lint_defs::BuiltinLintDiag;
 use rustc_lint_defs::builtin::EXPLICIT_BUILTIN_CFGS_IN_FLAGS;
 use rustc_span::symbol::{Symbol, sym};
-use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, TARGETS, Target, TargetTriple};
+use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, TARGETS, Target, TargetTuple};
 
 use crate::Session;
 use crate::config::{CrateType, FmtDebug};
@@ -417,7 +417,7 @@ impl CheckCfg {
 
                 for target in TARGETS
                     .iter()
-                    .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
+                    .map(|target| Target::expect_builtin(&TargetTuple::from_tuple(target)))
                     .chain(iter::once(current_target.clone()))
                 {
                     values_target_abi.insert(Symbol::intern(&target.options.abi));
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 20e8fb38b88..33f84f10447 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -9,7 +9,7 @@ use rustc_errors::{
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol};
-use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
+use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTuple};
 
 use crate::config::CrateType;
 use crate::parse::ParseSess;
@@ -179,13 +179,13 @@ pub(crate) struct EmbedSourceRequiresDebugInfo;
 #[diag(session_target_stack_protector_not_supported)]
 pub(crate) struct StackProtectorNotSupportedForTarget<'a> {
     pub(crate) stack_protector: StackProtector,
-    pub(crate) target_triple: &'a TargetTriple,
+    pub(crate) target_triple: &'a TargetTuple,
 }
 
 #[derive(Diagnostic)]
 #[diag(session_target_small_data_threshold_not_supported)]
 pub(crate) struct SmallDataThresholdNotSupportedForTarget<'a> {
-    pub(crate) target_triple: &'a TargetTriple,
+    pub(crate) target_triple: &'a TargetTuple,
 }
 
 #[derive(Diagnostic)]
@@ -383,7 +383,7 @@ struct BinaryFloatLiteralNotSupported {
 #[diag(session_unsupported_crate_type_for_target)]
 pub(crate) struct UnsupportedCrateTypeForTarget<'a> {
     pub(crate) crate_type: CrateType,
-    pub(crate) target_triple: &'a TargetTriple,
+    pub(crate) target_triple: &'a TargetTuple,
 }
 
 pub fn report_lit_error(
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index b3e3381d986..213a94ab880 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -152,7 +152,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
 }
 
 pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
-    let target = crate::config::host_triple();
+    let target = crate::config::host_tuple();
     let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
         smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
     let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
@@ -218,7 +218,7 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
         ))?;
 
         // if `dir` points target's dir, move up to the sysroot
-        let mut sysroot_dir = if dir.ends_with(crate::config::host_triple()) {
+        let mut sysroot_dir = if dir.ends_with(crate::config::host_tuple()) {
             dir.parent() // chop off `$target`
                 .and_then(|p| p.parent()) // chop off `rustlib`
                 .and_then(|p| p.parent()) // chop off `lib`
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 2b158627751..ca67e0a68a9 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -14,7 +14,7 @@ use rustc_span::{RealFileName, SourceFileHashAlgorithm};
 use rustc_target::spec::{
     CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
     RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility,
-    TargetTriple, TlsModel, WasmCAbi,
+    TargetTuple, TlsModel, WasmCAbi,
 };
 
 use crate::config::*;
@@ -146,7 +146,7 @@ top_level_options!(
         libs: Vec<NativeLib> [TRACKED],
         maybe_sysroot: Option<PathBuf> [UNTRACKED],
 
-        target_triple: TargetTriple [TRACKED],
+        target_triple: TargetTuple [TRACKED],
 
         /// Effective logical environment used by `env!`/`option_env!` macros
         logical_env: FxIndexMap<String, String> [TRACKED],
@@ -1585,7 +1585,7 @@ options! {
     link_dead_code: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "keep dead code at link time (useful for code coverage) (default: no)"),
     link_self_contained: LinkSelfContained = (LinkSelfContained::default(), parse_link_self_contained, [UNTRACKED],
-        "control whether to link Rust provided C objects/libraries or rely
+        "control whether to link Rust provided C objects/libraries or rely \
         on a C toolchain or linker installed in the system"),
     linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
         "system linker to link outputs with"),
diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index ac0d8661115..c148b09c718 100644
--- a/compiler/rustc_session/src/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
@@ -1,7 +1,7 @@
 use std::path::{Path, PathBuf};
 
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
-use rustc_target::spec::TargetTriple;
+use rustc_target::spec::TargetTuple;
 
 use crate::EarlyDiagCtxt;
 use crate::filesearch::make_target_lib_path;
@@ -52,7 +52,7 @@ impl PathKind {
 impl SearchPath {
     pub fn from_cli_opt(
         sysroot: &Path,
-        triple: &TargetTriple,
+        triple: &TargetTuple,
         early_dcx: &EarlyDiagCtxt,
         path: &str,
         is_unstable_enabled: bool,
@@ -80,7 +80,7 @@ impl SearchPath {
                     );
                 }
 
-                make_target_lib_path(sysroot, triple.triple()).join("builtin").join(stripped)
+                make_target_lib_path(sysroot, triple.tuple()).join("builtin").join(stripped)
             }
             None => PathBuf::from(path),
         };
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 45434534c75..470e372ee48 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -32,7 +32,7 @@ use rustc_target::asm::InlineAsmArch;
 use rustc_target::spec::{
     CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
     SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target,
-    TargetTriple, TlsModel,
+    TargetTuple, TlsModel,
 };
 
 use crate::code_stats::CodeStats;
@@ -451,12 +451,12 @@ impl Session {
     /// directories are also returned, for example if `--sysroot` is used but tools are missing
     /// (#125246): we also add the bin directories to the sysroot where rustc is located.
     pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
-        let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple());
+        let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_tuple());
         let fallback_sysroot_paths = filesearch::sysroot_candidates()
             .into_iter()
             // Ignore sysroot candidate if it was the same as the sysroot path we just used.
             .filter(|sysroot| *sysroot != self.sysroot)
-            .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple()));
+            .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_tuple()));
         let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths);
 
         if self_contained {
@@ -1023,7 +1023,7 @@ pub fn build_session(
     let cap_lints_allow = sopts.lint_cap.is_some_and(|cap| cap == lint::Allow);
     let can_emit_warnings = !(warnings_allow || cap_lints_allow);
 
-    let host_triple = TargetTriple::from_triple(config::host_triple());
+    let host_triple = TargetTuple::from_tuple(config::host_tuple());
     let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
         early_dcx.early_fatal(format!("Error loading host specification: {e}"))
     });
@@ -1074,8 +1074,8 @@ pub fn build_session(
     let mut psess = ParseSess::with_dcx(dcx, source_map);
     psess.assume_incomplete_release = sopts.unstable_opts.assume_incomplete_release;
 
-    let host_triple = config::host_triple();
-    let target_triple = sopts.target_triple.triple();
+    let host_triple = config::host_tuple();
+    let target_triple = sopts.target_triple.tuple();
     let host_tlib_path = Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple));
     let target_tlib_path = if host_triple == target_triple {
         // Use the same `SearchPath` if host and target triple are identical to avoid unnecessary
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index d518ed60469..06408e0b210 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1,21 +1,21 @@
 //! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131)
 //!
 //! Rust targets a wide variety of usecases, and in the interest of flexibility,
-//! allows new target triples to be defined in configuration files. Most users
+//! allows new target tuples to be defined in configuration files. Most users
 //! will not need to care about these, but this is invaluable when porting Rust
 //! to a new platform, and allows for an unprecedented level of control over how
 //! the compiler works.
 //!
 //! # Using custom targets
 //!
-//! A target triple, as passed via `rustc --target=TRIPLE`, will first be
+//! A target tuple, as passed via `rustc --target=TUPLE`, will first be
 //! compared against the list of built-in targets. This is to ease distributing
 //! rustc (no need for configuration files) and also to hold these built-in
-//! targets as immutable and sacred. If `TRIPLE` is not one of the built-in
-//! targets, rustc will check if a file named `TRIPLE` exists. If it does, it
+//! targets as immutable and sacred. If `TUPLE` is not one of the built-in
+//! targets, rustc will check if a file named `TUPLE` exists. If it does, it
 //! will be loaded as the target configuration. If the file does not exist,
 //! rustc will search each directory in the environment variable
-//! `RUST_TARGET_PATH` for a file named `TRIPLE.json`. The first one found will
+//! `RUST_TARGET_PATH` for a file named `TUPLE.json`. The first one found will
 //! be loaded. If no file is found in any of those directories, a fatal error
 //! will be given.
 //!
@@ -1586,17 +1586,17 @@ impl fmt::Display for StackProtector {
 }
 
 macro_rules! supported_targets {
-    ( $(($triple:literal, $module:ident),)+ ) => {
+    ( $(($tuple:literal, $module:ident),)+ ) => {
         mod targets {
             $(pub(crate) mod $module;)+
         }
 
         /// List of supported targets
-        pub const TARGETS: &[&str] = &[$($triple),+];
+        pub const TARGETS: &[&str] = &[$($tuple),+];
 
         fn load_builtin(target: &str) -> Option<Target> {
             let mut t = match target {
-                $( $triple => targets::$module::target(), )+
+                $( $tuple => targets::$module::target(), )+
                 _ => return None,
             };
             t.is_builtin = true;
@@ -2005,9 +2005,9 @@ impl TargetWarnings {
 /// Every field here must be specified, and has no default value.
 #[derive(PartialEq, Clone, Debug)]
 pub struct Target {
-    /// Unversioned target triple to pass to LLVM.
+    /// Unversioned target tuple to pass to LLVM.
     ///
-    /// Target triples can optionally contain an OS version (notably Apple targets), which rustc
+    /// Target tuples can optionally contain an OS version (notably Apple targets), which rustc
     /// cannot know without querying the environment.
     ///
     /// Use `rustc_codegen_ssa::back::versioned_llvm_target` if you need the full LLVM target.
@@ -3477,28 +3477,28 @@ impl Target {
     }
 
     /// Load a built-in target
-    pub fn expect_builtin(target_triple: &TargetTriple) -> Target {
-        match *target_triple {
-            TargetTriple::TargetTriple(ref target_triple) => {
-                load_builtin(target_triple).expect("built-in target")
+    pub fn expect_builtin(target_tuple: &TargetTuple) -> Target {
+        match *target_tuple {
+            TargetTuple::TargetTuple(ref target_tuple) => {
+                load_builtin(target_tuple).expect("built-in target")
             }
-            TargetTriple::TargetJson { .. } => {
+            TargetTuple::TargetJson { .. } => {
                 panic!("built-in targets doesn't support target-paths")
             }
         }
     }
 
-    /// Search for a JSON file specifying the given target triple.
+    /// Search for a JSON file specifying the given target tuple.
     ///
     /// If none is found in `$RUST_TARGET_PATH`, look for a file called `target.json` inside the
-    /// sysroot under the target-triple's `rustlib` directory. Note that it could also just be a
+    /// sysroot under the target-tuple's `rustlib` directory. Note that it could also just be a
     /// bare filename already, so also check for that. If one of the hardcoded targets we know
     /// about, just return it directly.
     ///
     /// The error string could come from any of the APIs called, including filesystem access and
     /// JSON decoding.
     pub fn search(
-        target_triple: &TargetTriple,
+        target_tuple: &TargetTuple,
         sysroot: &Path,
     ) -> Result<(Target, TargetWarnings), String> {
         use std::{env, fs};
@@ -3509,16 +3509,16 @@ impl Target {
             Target::from_json(obj)
         }
 
-        match *target_triple {
-            TargetTriple::TargetTriple(ref target_triple) => {
-                // check if triple is in list of built-in targets
-                if let Some(t) = load_builtin(target_triple) {
+        match *target_tuple {
+            TargetTuple::TargetTuple(ref target_tuple) => {
+                // check if tuple is in list of built-in targets
+                if let Some(t) = load_builtin(target_tuple) {
                     return Ok((t, TargetWarnings::empty()));
                 }
 
-                // search for a file named `target_triple`.json in RUST_TARGET_PATH
+                // search for a file named `target_tuple`.json in RUST_TARGET_PATH
                 let path = {
-                    let mut target = target_triple.to_string();
+                    let mut target = target_tuple.to_string();
                     target.push_str(".json");
                     PathBuf::from(target)
                 };
@@ -3532,9 +3532,9 @@ impl Target {
                     }
                 }
 
-                // Additionally look in the sysroot under `lib/rustlib/<triple>/target.json`
+                // Additionally look in the sysroot under `lib/rustlib/<tuple>/target.json`
                 // as a fallback.
-                let rustlib_path = crate::relative_target_rustlib_path(sysroot, target_triple);
+                let rustlib_path = crate::relative_target_rustlib_path(sysroot, target_tuple);
                 let p = PathBuf::from_iter([
                     Path::new(sysroot),
                     Path::new(&rustlib_path),
@@ -3544,9 +3544,9 @@ impl Target {
                     return load_file(&p);
                 }
 
-                Err(format!("Could not find specification for target {target_triple:?}"))
+                Err(format!("Could not find specification for target {target_tuple:?}"))
             }
-            TargetTriple::TargetJson { ref contents, .. } => {
+            TargetTuple::TargetJson { ref contents, .. } => {
                 let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?;
                 Target::from_json(obj)
             }
@@ -3751,44 +3751,44 @@ impl ToJson for Target {
     }
 }
 
-/// Either a target triple string or a path to a JSON file.
+/// Either a target tuple string or a path to a JSON file.
 #[derive(Clone, Debug)]
-pub enum TargetTriple {
-    TargetTriple(String),
+pub enum TargetTuple {
+    TargetTuple(String),
     TargetJson {
         /// Warning: This field may only be used by rustdoc. Using it anywhere else will lead to
         /// inconsistencies as it is discarded during serialization.
         path_for_rustdoc: PathBuf,
-        triple: String,
+        tuple: String,
         contents: String,
     },
 }
 
 // Use a manual implementation to ignore the path field
-impl PartialEq for TargetTriple {
+impl PartialEq for TargetTuple {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
-            (Self::TargetTriple(l0), Self::TargetTriple(r0)) => l0 == r0,
+            (Self::TargetTuple(l0), Self::TargetTuple(r0)) => l0 == r0,
             (
-                Self::TargetJson { path_for_rustdoc: _, triple: l_triple, contents: l_contents },
-                Self::TargetJson { path_for_rustdoc: _, triple: r_triple, contents: r_contents },
-            ) => l_triple == r_triple && l_contents == r_contents,
+                Self::TargetJson { path_for_rustdoc: _, tuple: l_tuple, contents: l_contents },
+                Self::TargetJson { path_for_rustdoc: _, tuple: r_tuple, contents: r_contents },
+            ) => l_tuple == r_tuple && l_contents == r_contents,
             _ => false,
         }
     }
 }
 
 // Use a manual implementation to ignore the path field
-impl Hash for TargetTriple {
+impl Hash for TargetTuple {
     fn hash<H: Hasher>(&self, state: &mut H) -> () {
         match self {
-            TargetTriple::TargetTriple(triple) => {
+            TargetTuple::TargetTuple(tuple) => {
                 0u8.hash(state);
-                triple.hash(state)
+                tuple.hash(state)
             }
-            TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents } => {
+            TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents } => {
                 1u8.hash(state);
-                triple.hash(state);
+                tuple.hash(state);
                 contents.hash(state)
             }
         }
@@ -3796,45 +3796,45 @@ impl Hash for TargetTriple {
 }
 
 // Use a manual implementation to prevent encoding the target json file path in the crate metadata
-impl<S: Encoder> Encodable<S> for TargetTriple {
+impl<S: Encoder> Encodable<S> for TargetTuple {
     fn encode(&self, s: &mut S) {
         match self {
-            TargetTriple::TargetTriple(triple) => {
+            TargetTuple::TargetTuple(tuple) => {
                 s.emit_u8(0);
-                s.emit_str(triple);
+                s.emit_str(tuple);
             }
-            TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents } => {
+            TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents } => {
                 s.emit_u8(1);
-                s.emit_str(triple);
+                s.emit_str(tuple);
                 s.emit_str(contents);
             }
         }
     }
 }
 
-impl<D: Decoder> Decodable<D> for TargetTriple {
+impl<D: Decoder> Decodable<D> for TargetTuple {
     fn decode(d: &mut D) -> Self {
         match d.read_u8() {
-            0 => TargetTriple::TargetTriple(d.read_str().to_owned()),
-            1 => TargetTriple::TargetJson {
+            0 => TargetTuple::TargetTuple(d.read_str().to_owned()),
+            1 => TargetTuple::TargetJson {
                 path_for_rustdoc: PathBuf::new(),
-                triple: d.read_str().to_owned(),
+                tuple: d.read_str().to_owned(),
                 contents: d.read_str().to_owned(),
             },
             _ => {
-                panic!("invalid enum variant tag while decoding `TargetTriple`, expected 0..2");
+                panic!("invalid enum variant tag while decoding `TargetTuple`, expected 0..2");
             }
         }
     }
 }
 
-impl TargetTriple {
-    /// Creates a target triple from the passed target triple string.
-    pub fn from_triple(triple: &str) -> Self {
-        TargetTriple::TargetTriple(triple.into())
+impl TargetTuple {
+    /// Creates a target tuple from the passed target tuple string.
+    pub fn from_tuple(tuple: &str) -> Self {
+        TargetTuple::TargetTuple(tuple.into())
     }
 
-    /// Creates a target triple from the passed target path.
+    /// Creates a target tuple from the passed target path.
     pub fn from_path(path: &Path) -> Result<Self, io::Error> {
         let canonicalized_path = try_canonicalize(path)?;
         let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| {
@@ -3843,46 +3843,47 @@ impl TargetTriple {
                 format!("target path {canonicalized_path:?} is not a valid file: {err}"),
             )
         })?;
-        let triple = canonicalized_path
+        let tuple = canonicalized_path
             .file_stem()
             .expect("target path must not be empty")
             .to_str()
             .expect("target path must be valid unicode")
             .to_owned();
-        Ok(TargetTriple::TargetJson { path_for_rustdoc: canonicalized_path, triple, contents })
+        Ok(TargetTuple::TargetJson { path_for_rustdoc: canonicalized_path, tuple, contents })
     }
 
-    /// Returns a string triple for this target.
+    /// Returns a string tuple for this target.
     ///
     /// If this target is a path, the file name (without extension) is returned.
-    pub fn triple(&self) -> &str {
+    pub fn tuple(&self) -> &str {
         match *self {
-            TargetTriple::TargetTriple(ref triple)
-            | TargetTriple::TargetJson { ref triple, .. } => triple,
+            TargetTuple::TargetTuple(ref tuple) | TargetTuple::TargetJson { ref tuple, .. } => {
+                tuple
+            }
         }
     }
 
-    /// Returns an extended string triple for this target.
+    /// Returns an extended string tuple for this target.
     ///
-    /// If this target is a path, a hash of the path is appended to the triple returned
-    /// by `triple()`.
-    pub fn debug_triple(&self) -> String {
+    /// If this target is a path, a hash of the path is appended to the tuple returned
+    /// by `tuple()`.
+    pub fn debug_tuple(&self) -> String {
         use std::hash::DefaultHasher;
 
         match self {
-            TargetTriple::TargetTriple(triple) => triple.to_owned(),
-            TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents: content } => {
+            TargetTuple::TargetTuple(tuple) => tuple.to_owned(),
+            TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents: content } => {
                 let mut hasher = DefaultHasher::new();
                 content.hash(&mut hasher);
                 let hash = hasher.finish();
-                format!("{triple}-{hash}")
+                format!("{tuple}-{hash}")
             }
         }
     }
 }
 
-impl fmt::Display for TargetTriple {
+impl fmt::Display for TargetTuple {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.debug_triple())
+        write!(f, "{}", self.debug_tuple())
     }
 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 574cf1e88b1..4725047090e 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -766,6 +766,67 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         values
     }
 
+    pub fn cmp_traits(
+        &self,
+        def_id1: DefId,
+        args1: &[ty::GenericArg<'tcx>],
+        def_id2: DefId,
+        args2: &[ty::GenericArg<'tcx>],
+    ) -> (DiagStyledString, DiagStyledString) {
+        let mut values = (DiagStyledString::new(), DiagStyledString::new());
+
+        if def_id1 != def_id2 {
+            values.0.push_highlighted(self.tcx.def_path_str(def_id1).as_str());
+            values.1.push_highlighted(self.tcx.def_path_str(def_id2).as_str());
+        } else {
+            values.0.push_normal(self.tcx.item_name(def_id1).as_str());
+            values.1.push_normal(self.tcx.item_name(def_id2).as_str());
+        }
+
+        if args1.len() != args2.len() {
+            let (pre, post) = if args1.len() > 0 { ("<", ">") } else { ("", "") };
+            values.0.push_normal(format!(
+                "{pre}{}{post}",
+                args1.iter().map(|a| a.to_string()).collect::<Vec<_>>().join(", ")
+            ));
+            let (pre, post) = if args2.len() > 0 { ("<", ">") } else { ("", "") };
+            values.1.push_normal(format!(
+                "{pre}{}{post}",
+                args2.iter().map(|a| a.to_string()).collect::<Vec<_>>().join(", ")
+            ));
+            return values;
+        }
+
+        if args1.len() > 0 {
+            values.0.push_normal("<");
+            values.1.push_normal("<");
+        }
+        for (i, (a, b)) in std::iter::zip(args1, args2).enumerate() {
+            let a_str = a.to_string();
+            let b_str = b.to_string();
+            if let (Some(a), Some(b)) = (a.as_type(), b.as_type()) {
+                let (a, b) = self.cmp(a, b);
+                values.0.0.extend(a.0);
+                values.1.0.extend(b.0);
+            } else if a_str != b_str {
+                values.0.push_highlighted(a_str);
+                values.1.push_highlighted(b_str);
+            } else {
+                values.0.push_normal(a_str);
+                values.1.push_normal(b_str);
+            }
+            if i + 1 < args1.len() {
+                values.0.push_normal(", ");
+                values.1.push_normal(", ");
+            }
+        }
+        if args1.len() > 0 {
+            values.0.push_normal(">");
+            values.1.push_normal(">");
+        }
+        values
+    }
+
     /// Compares two given types, eliding parts that are the same between them and highlighting
     /// relevant differences, and return two representation of those types for highlighted printing.
     pub fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagStyledString, DiagStyledString) {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 7aa558cfd3f..524b4139600 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -6,8 +6,8 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, StringPart, Suggestions, pluralize,
-    struct_span_code_err,
+    Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions,
+    pluralize, struct_span_code_err,
 };
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
@@ -328,6 +328,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             }
                         } else if let Some(custom_explanation) = safe_transmute_explanation {
                             err.span_label(span, custom_explanation);
+                        } else if explanation.len() > self.tcx.sess.diagnostic_width() {
+                            // Really long types don't look good as span labels, instead move it
+                            // to a `help`.
+                            err.span_label(span, "unsatisfied trait bound");
+                            err.help(explanation);
                         } else {
                             err.span_label(span, explanation);
                         }
@@ -1832,21 +1837,81 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     if impl_trait_ref.references_error() {
                         return false;
                     }
-                    let self_ty = impl_trait_ref.self_ty().to_string();
-                    err.highlighted_help(vec![
-                        StringPart::normal(format!(
-                            "the trait `{}` ",
-                            impl_trait_ref.print_trait_sugared()
-                        )),
-                        StringPart::highlighted("is"),
+
+                    if let [child, ..] = &err.children[..]
+                        && child.level == Level::Help
+                        && let Some(line) = child.messages.get(0)
+                        && let Some(line) = line.0.as_str()
+                        && line.starts_with("the trait")
+                        && line.contains("is not implemented for")
+                    {
+                        // HACK(estebank): we remove the pre-existing
+                        // "the trait `X` is not implemented for" note, which only happens if there
+                        // was a custom label. We do this because we want that note to always be the
+                        // first, and making this logic run earlier will get tricky. For now, we
+                        // instead keep the logic the same and modify the already constructed error
+                        // to avoid the wording duplication.
+                        err.children.remove(0);
+                    }
+
+                    let traits = self.cmp_traits(
+                        obligation_trait_ref.def_id,
+                        &obligation_trait_ref.args[1..],
+                        impl_trait_ref.def_id,
+                        &impl_trait_ref.args[1..],
+                    );
+                    let traits_content = (traits.0.content(), traits.1.content());
+                    let types = self.cmp(obligation_trait_ref.self_ty(), impl_trait_ref.self_ty());
+                    let types_content = (types.0.content(), types.1.content());
+                    let mut msg = vec![StringPart::normal("the trait `")];
+                    if traits_content.0 == traits_content.1 {
+                        msg.push(StringPart::normal(
+                            impl_trait_ref.print_trait_sugared().to_string(),
+                        ));
+                    } else {
+                        msg.extend(traits.0.0);
+                    }
+                    msg.extend([
+                        StringPart::normal("` "),
+                        StringPart::highlighted("is not"),
                         StringPart::normal(" implemented for `"),
-                        if let [TypeError::Sorts(_)] = &terrs[..] {
-                            StringPart::normal(self_ty)
-                        } else {
-                            StringPart::highlighted(self_ty)
-                        },
-                        StringPart::normal("`"),
                     ]);
+                    if types_content.0 == types_content.1 {
+                        let ty =
+                            self.tcx.short_ty_string(obligation_trait_ref.self_ty(), &mut None);
+                        msg.push(StringPart::normal(ty));
+                    } else {
+                        msg.extend(types.0.0);
+                    }
+                    msg.push(StringPart::normal("`"));
+                    if types_content.0 == types_content.1 {
+                        msg.push(StringPart::normal("\nbut trait `"));
+                        msg.extend(traits.1.0);
+                        msg.extend([
+                            StringPart::normal("` "),
+                            StringPart::highlighted("is"),
+                            StringPart::normal(" implemented for it"),
+                        ]);
+                    } else if traits_content.0 == traits_content.1 {
+                        msg.extend([
+                            StringPart::normal("\nbut it "),
+                            StringPart::highlighted("is"),
+                            StringPart::normal(" implemented for `"),
+                        ]);
+                        msg.extend(types.1.0);
+                        msg.push(StringPart::normal("`"));
+                    } else {
+                        msg.push(StringPart::normal("\nbut trait `"));
+                        msg.extend(traits.1.0);
+                        msg.extend([
+                            StringPart::normal("` "),
+                            StringPart::highlighted("is"),
+                            StringPart::normal(" implemented for `"),
+                        ]);
+                        msg.extend(types.1.0);
+                        msg.push(StringPart::normal("`"));
+                    }
+                    err.highlighted_help(msg);
 
                     if let [TypeError::Sorts(exp_found)] = &terrs[..] {
                         let exp_found = self.resolve_vars_if_possible(*exp_found);
@@ -2475,12 +2540,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             && self.tcx.trait_impls_of(trait_def_id).is_empty()
             && !self.tcx.trait_is_auto(trait_def_id)
             && !self.tcx.trait_is_alias(trait_def_id)
+            && trait_predicate.polarity() == ty::PredicatePolarity::Positive
         {
             err.span_help(
                 self.tcx.def_span(trait_def_id),
                 crate::fluent_generated::trait_selection_trait_has_no_impls,
             );
-        } else if !suggested && !unsatisfied_const {
+        } else if !suggested
+            && !unsatisfied_const
+            && trait_predicate.polarity() == ty::PredicatePolarity::Positive
+        {
             // Can't show anything else useful, try to find similar impls.
             let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
             if !self.report_similar_impl_candidates(
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 553bb61ed04..68aa9cffef2 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3563,17 +3563,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 )]);
             }
             ObligationCauseCode::OpaqueReturnType(expr_info) => {
-                if let Some((expr_ty, hir_id)) = expr_info {
-                    let expr_ty = self.tcx.short_ty_string(expr_ty, long_ty_file);
-                    let expr = self.infcx.tcx.hir().expect_expr(hir_id);
-                    err.span_label(
-                        expr.span,
-                        with_forced_trimmed_paths!(format!(
-                            "return type was inferred to be `{expr_ty}` here",
-                        )),
-                    );
-                    suggest_remove_deref(err, &expr);
-                }
+                let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
+                    let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
+                    let expr = tcx.hir().expect_expr(hir_id);
+                    (expr_ty, expr)
+                } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id()
+                    && let body = tcx.hir().body(body_id)
+                    && let hir::ExprKind::Block(block, _) = body.value.kind
+                    && let Some(expr) = block.expr
+                    && let Some(expr_ty) = self
+                        .typeck_results
+                        .as_ref()
+                        .and_then(|typeck| typeck.node_type_opt(expr.hir_id))
+                    && let Some(pred) = predicate.as_clause()
+                    && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
+                    && self.can_eq(param_env, pred.self_ty(), expr_ty)
+                {
+                    let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
+                    (expr_ty, expr)
+                } else {
+                    return;
+                };
+                err.span_label(
+                    expr.span,
+                    with_forced_trimmed_paths!(format!(
+                        "return type was inferred to be `{expr_ty}` here",
+                    )),
+                );
+                suggest_remove_deref(err, &expr);
             }
         }
     }
@@ -3680,6 +3697,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         err: &mut Diag<'_>,
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) {
+        if trait_pred.polarity() == ty::PredicatePolarity::Negative {
+            return;
+        }
         let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
             return;
         };