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/attr/mod.rs23
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs136
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock94
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh4
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs36
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/object.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs1
-rw-r--r--compiler/rustc_expand/src/config.rs30
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs7
-rw-r--r--compiler/rustc_infer/messages.ftl4
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs29
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/region.rs121
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lint/messages.ftl19
-rw-r--r--compiler/rustc_lint/src/builtin.rs137
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/lints.rs32
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs27
-rw-r--r--compiler/rustc_llvm/build.rs3
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp17
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs3
-rw-r--r--compiler/rustc_parse/src/lib.rs6
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs122
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs10
-rw-r--r--compiler/rustc_session/src/config.rs2
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/target_features.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs46
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs29
41 files changed, 610 insertions, 388 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 088ae9ba441..d2c7b1c0753 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -202,21 +202,18 @@ impl Attribute {
         }
     }
 
-    // Named `get_tokens` to distinguish it from the `<Attribute as HasTokens>::tokens` method.
-    pub fn get_tokens(&self) -> TokenStream {
-        match &self.kind {
-            AttrKind::Normal(normal) => TokenStream::new(
-                normal
-                    .tokens
-                    .as_ref()
-                    .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}"))
-                    .to_attr_token_stream()
-                    .to_token_trees(),
-            ),
-            &AttrKind::DocComment(comment_kind, data) => TokenStream::token_alone(
+    pub fn token_trees(&self) -> Vec<TokenTree> {
+        match self.kind {
+            AttrKind::Normal(ref normal) => normal
+                .tokens
+                .as_ref()
+                .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}"))
+                .to_attr_token_stream()
+                .to_token_trees(),
+            AttrKind::DocComment(comment_kind, data) => vec![TokenTree::token_alone(
                 token::DocComment(comment_kind, self.style, data),
                 self.span,
-            ),
+            )],
         }
     }
 }
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index ee068f19332..a92ef575777 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -16,7 +16,7 @@
 use crate::ast::{AttrStyle, StmtKind};
 use crate::ast_traits::{HasAttrs, HasTokens};
 use crate::token::{self, Delimiter, Nonterminal, Token, TokenKind};
-use crate::AttrVec;
+use crate::{AttrVec, Attribute};
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{self, Lrc};
@@ -179,11 +179,10 @@ impl AttrTokenStream {
         AttrTokenStream(Lrc::new(tokens))
     }
 
-    /// Converts this `AttrTokenStream` to a plain `Vec<TokenTree>`.
-    /// During conversion, `AttrTokenTree::AttrsTarget` get 'flattened'
-    /// back to a `TokenStream` of the form `outer_attr attr_target`.
-    /// If there are inner attributes, they are inserted into the proper
-    /// place in the attribute target tokens.
+    /// Converts this `AttrTokenStream` to a plain `Vec<TokenTree>`. During
+    /// conversion, any `AttrTokenTree::AttrsTarget` gets "flattened" back to a
+    /// `TokenStream`, as described in the comment on
+    /// `attrs_and_tokens_to_token_trees`.
     pub fn to_token_trees(&self) -> Vec<TokenTree> {
         let mut res = Vec::with_capacity(self.0.len());
         for tree in self.0.iter() {
@@ -200,51 +199,7 @@ impl AttrTokenStream {
                     ))
                 }
                 AttrTokenTree::AttrsTarget(target) => {
-                    let idx = target
-                        .attrs
-                        .partition_point(|attr| matches!(attr.style, crate::AttrStyle::Outer));
-                    let (outer_attrs, inner_attrs) = target.attrs.split_at(idx);
-
-                    let mut target_tokens = target.tokens.to_attr_token_stream().to_token_trees();
-                    if !inner_attrs.is_empty() {
-                        let mut found = false;
-                        // Check the last two trees (to account for a trailing semi)
-                        for tree in target_tokens.iter_mut().rev().take(2) {
-                            if let TokenTree::Delimited(span, spacing, delim, delim_tokens) = tree {
-                                // Inner attributes are only supported on extern blocks, functions,
-                                // impls, and modules. All of these have their inner attributes
-                                // placed at the beginning of the rightmost outermost braced group:
-                                // e.g. fn foo() { #![my_attr] }
-                                //
-                                // Therefore, we can insert them back into the right location
-                                // without needing to do any extra position tracking.
-                                //
-                                // Note: Outline modules are an exception - they can
-                                // have attributes like `#![my_attr]` at the start of a file.
-                                // Support for custom attributes in this position is not
-                                // properly implemented - we always synthesize fake tokens,
-                                // so we never reach this code.
-
-                                let mut stream = TokenStream::default();
-                                for inner_attr in inner_attrs {
-                                    stream.push_stream(inner_attr.get_tokens());
-                                }
-                                stream.push_stream(delim_tokens.clone());
-                                *tree = TokenTree::Delimited(*span, *spacing, *delim, stream);
-                                found = true;
-                                break;
-                            }
-                        }
-
-                        assert!(
-                            found,
-                            "Failed to find trailing delimited group in: {target_tokens:?}"
-                        );
-                    }
-                    for attr in outer_attrs {
-                        res.extend(attr.get_tokens().0.iter().cloned());
-                    }
-                    res.extend(target_tokens);
+                    attrs_and_tokens_to_token_trees(&target.attrs, &target.tokens, &mut res);
                 }
             }
         }
@@ -252,15 +207,76 @@ impl AttrTokenStream {
     }
 }
 
+// Converts multiple attributes and the tokens for a target AST node into token trees, and appends
+// them to `res`.
+//
+// Example: if the AST node is "fn f() { blah(); }", then:
+// - Simple if no attributes are present, e.g. "fn f() { blah(); }"
+// - Simple if only outer attribute are present, e.g. "#[outer1] #[outer2] fn f() { blah(); }"
+// - Trickier if inner attributes are present, because they must be moved within the AST node's
+//   tokens, e.g. "#[outer] fn f() { #![inner] blah() }"
+fn attrs_and_tokens_to_token_trees(
+    attrs: &[Attribute],
+    target_tokens: &LazyAttrTokenStream,
+    res: &mut Vec<TokenTree>,
+) {
+    let idx = attrs.partition_point(|attr| matches!(attr.style, crate::AttrStyle::Outer));
+    let (outer_attrs, inner_attrs) = attrs.split_at(idx);
+
+    // Add outer attribute tokens.
+    for attr in outer_attrs {
+        res.extend(attr.token_trees());
+    }
+
+    // Add target AST node tokens.
+    res.extend(target_tokens.to_attr_token_stream().to_token_trees());
+
+    // Insert inner attribute tokens.
+    if !inner_attrs.is_empty() {
+        let mut found = false;
+        // Check the last two trees (to account for a trailing semi)
+        for tree in res.iter_mut().rev().take(2) {
+            if let TokenTree::Delimited(span, spacing, delim, delim_tokens) = tree {
+                // Inner attributes are only supported on extern blocks, functions,
+                // impls, and modules. All of these have their inner attributes
+                // placed at the beginning of the rightmost outermost braced group:
+                // e.g. fn foo() { #![my_attr] }
+                //
+                // Therefore, we can insert them back into the right location
+                // without needing to do any extra position tracking.
+                //
+                // Note: Outline modules are an exception - they can
+                // have attributes like `#![my_attr]` at the start of a file.
+                // Support for custom attributes in this position is not
+                // properly implemented - we always synthesize fake tokens,
+                // so we never reach this code.
+                let mut tts = vec![];
+                for inner_attr in inner_attrs {
+                    tts.extend(inner_attr.token_trees());
+                }
+                tts.extend(delim_tokens.0.iter().cloned());
+                let stream = TokenStream::new(tts);
+                *tree = TokenTree::Delimited(*span, *spacing, *delim, stream);
+                found = true;
+                break;
+            }
+        }
+        assert!(found, "Failed to find trailing delimited group in: {res:?}");
+    }
+}
+
 /// Stores the tokens for an attribute target, along
 /// with its attributes.
 ///
 /// This is constructed during parsing when we need to capture
-/// tokens.
+/// tokens, for `cfg` and `cfg_attr` attributes.
 ///
 /// For example, `#[cfg(FALSE)] struct Foo {}` would
 /// have an `attrs` field containing the `#[cfg(FALSE)]` attr,
 /// and a `tokens` field storing the (unparsed) tokens `struct Foo {}`
+///
+/// The `cfg`/`cfg_attr` processing occurs in
+/// `StripUnconfigured::configure_tokens`.
 #[derive(Clone, Debug, Encodable, Decodable)]
 pub struct AttrsTarget {
     /// Attributes, both outer and inner.
@@ -437,18 +453,10 @@ impl TokenStream {
     }
 
     pub fn from_ast(node: &(impl HasAttrs + HasTokens + fmt::Debug)) -> TokenStream {
-        let Some(tokens) = node.tokens() else {
-            panic!("missing tokens for node: {:?}", node);
-        };
-        let attrs = node.attrs();
-        let attr_stream = if attrs.is_empty() {
-            tokens.to_attr_token_stream()
-        } else {
-            let target =
-                AttrsTarget { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() };
-            AttrTokenStream::new(vec![AttrTokenTree::AttrsTarget(target)])
-        };
-        TokenStream::new(attr_stream.to_token_trees())
+        let tokens = node.tokens().unwrap_or_else(|| panic!("missing tokens for node: {:?}", node));
+        let mut tts = vec![];
+        attrs_and_tokens_to_token_trees(node.attrs(), tokens, &mut tts);
+        TokenStream::new(tts)
     }
 
     pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index 15c9e9d66fa..efec5db836b 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -16,9 +16,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.82"
+version = "1.0.86"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
 
 [[package]]
 name = "arbitrary"
@@ -67,7 +67,7 @@ dependencies = [
  "cranelift-entity",
  "cranelift-isle",
  "gimli",
- "hashbrown 0.14.3",
+ "hashbrown 0.14.5",
  "log",
  "regalloc2",
  "rustc-hash",
@@ -182,9 +182,9 @@ dependencies = [
 
 [[package]]
 name = "crc32fast"
-version = "1.4.0"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
 dependencies = [
  "cfg-if",
 ]
@@ -203,9 +203,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "gimli"
-version = "0.28.0"
+version = "0.28.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
+checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
 dependencies = [
  "fallible-iterator",
  "indexmap",
@@ -223,9 +223,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.14.3"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
 dependencies = [
  "ahash",
 ]
@@ -237,20 +237,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
 dependencies = [
  "equivalent",
- "hashbrown 0.14.3",
+ "hashbrown 0.14.5",
 ]
 
 [[package]]
 name = "libc"
-version = "0.2.153"
+version = "0.2.155"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
 
 [[package]]
 name = "libloading"
-version = "0.8.3"
+version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
+checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
 dependencies = [
  "cfg-if",
  "windows-targets",
@@ -258,9 +258,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.21"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
 [[package]]
 name = "mach"
@@ -273,9 +273,9 @@ dependencies = [
 
 [[package]]
 name = "memchr"
-version = "2.7.2"
+version = "2.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
 name = "object"
@@ -284,7 +284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
 dependencies = [
  "crc32fast",
- "hashbrown 0.14.3",
+ "hashbrown 0.14.5",
  "indexmap",
  "memchr",
 ]
@@ -297,9 +297,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.81"
+version = "1.0.86"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
 dependencies = [
  "unicode-ident",
 ]
@@ -382,9 +382,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 
 [[package]]
 name = "syn"
-version = "2.0.60"
+version = "2.0.70"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
+checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -393,9 +393,9 @@ dependencies = [
 
 [[package]]
 name = "target-lexicon"
-version = "0.12.14"
+version = "0.12.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
+checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2"
 
 [[package]]
 name = "unicode-ident"
@@ -454,9 +454,9 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
  "windows_aarch64_gnullvm",
  "windows_aarch64_msvc",
@@ -470,66 +470,66 @@ dependencies = [
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
 
 [[package]]
 name = "windows_i686_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.52.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "zerocopy"
-version = "0.7.32"
+version = "0.7.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.7.32"
+version = "0.7.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index cfa91744a0e..db9b551bd2a 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-06-30"
+channel = "nightly-2024-07-13"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index c1b7e4b0e07..f0550c23b17 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -34,6 +34,7 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR
 
 # vendor intrinsics
 rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic
+rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps
 
 # exotic linkages
 rm tests/incremental/hashes/function_interfaces.rs
@@ -56,13 +57,13 @@ rm -r tests/run-make/target-specs # i686 not supported by Cranelift
 rm -r tests/run-make/mismatching-target-triples # same
 rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly
 rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported
+rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes
 
 # requires LTO
 rm -r tests/run-make/cdylib
 rm -r tests/run-make/codegen-options-parsing
 rm -r tests/run-make/lto-*
 rm -r tests/run-make/reproducible-build-2
-rm -r tests/run-make/issue-109934-lto-debuginfo
 rm -r tests/run-make/no-builtins-lto
 rm -r tests/run-make/reachable-extern-fn-available-lto
 
@@ -109,6 +110,7 @@ rm -r tests/run-make/symbols-include-type-name
 rm -r tests/run-make/notify-all-emit-artifacts
 rm -r tests/run-make/reset-codegen-1
 rm -r tests/run-make/inline-always-many-cgu
+rm -r tests/run-make/intrinsic-unreachable
 
 # giving different but possibly correct results
 # =============================================
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 9dc94ab33ea..fa0de6f9de5 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -395,7 +395,6 @@ pub(crate) fn codegen_terminator_call<'tcx>(
             crate::intrinsics::codegen_llvm_intrinsic_call(
                 fx,
                 &fx.tcx.symbol_name(instance).name,
-                fn_args,
                 args,
                 ret_place,
                 target,
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
index 414d3db1c51..3f23e0d9e04 100644
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ b/compiler/rustc_codegen_cranelift/src/archive.rs
@@ -14,12 +14,12 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
 
     fn create_dll_import_lib(
         &self,
-        _sess: &Session,
+        sess: &Session,
         _lib_name: &str,
         _dll_imports: &[rustc_session::cstore::DllImport],
         _tmpdir: &Path,
         _is_direct_dependency: bool,
     ) -> PathBuf {
-        unimplemented!("creating dll imports is not yet supported");
+        sess.dcx().fatal("raw-dylib is not yet supported by rustc_codegen_cranelift");
     }
 }
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index fd34ed88c0b..0ba163f50ae 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -385,15 +385,43 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
 
         if let Some(section_name) = section_name {
             let (segment_name, section_name) = if tcx.sess.target.is_like_osx {
-                let section_name = section_name.as_str();
-                if let Some(names) = section_name.split_once(',') {
-                    names
-                } else {
+                // See https://github.com/llvm/llvm-project/blob/main/llvm/lib/MC/MCSectionMachO.cpp
+                let mut parts = section_name.as_str().split(',');
+                let Some(segment_name) = parts.next() else {
                     tcx.dcx().fatal(format!(
                         "#[link_section = \"{}\"] is not valid for macos target: must be segment and section separated by comma",
                         section_name
                     ));
+                };
+                let Some(section_name) = parts.next() else {
+                    tcx.dcx().fatal(format!(
+                        "#[link_section = \"{}\"] is not valid for macos target: must be segment and section separated by comma",
+                        section_name
+                    ));
+                };
+                if section_name.len() > 16 {
+                    tcx.dcx().fatal(format!(
+                        "#[link_section = \"{}\"] is not valid for macos target: section name bigger than 16 bytes",
+                        section_name
+                    ));
+                }
+                let section_type = parts.next().unwrap_or("regular");
+                if section_type != "regular" && section_type != "cstring_literals" {
+                    tcx.dcx().fatal(format!(
+                        "#[link_section = \"{}\"] is not supported: unsupported section type {}",
+                        section_name, section_type,
+                    ));
+                }
+                let _attrs = parts.next();
+                if parts.next().is_some() {
+                    tcx.dcx().fatal(format!(
+                        "#[link_section = \"{}\"] is not valid for macos target: too many components",
+                        section_name
+                    ));
                 }
+                // FIXME(bytecodealliance/wasmtime#8901) set S_CSTRING_LITERALS section type when
+                // cstring_literals is specified
+                (segment_name, section_name)
             } else {
                 ("", section_name.as_str())
             };
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
index 65f4c67b21f..1c6e471cc87 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
@@ -39,7 +39,13 @@ impl WriteDebugInfo for ObjectProduct {
         let section_id = self.object.add_section(
             segment,
             name,
-            if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
+            if id == SectionId::DebugStr || id == SectionId::DebugLineStr {
+                SectionKind::DebugString
+            } else if id == SectionId::EhFrame {
+                SectionKind::ReadOnlyData
+            } else {
+                SectionKind::Debug
+            },
         );
         self.object
             .section_mut(section_id)
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index e50c74b87f6..720a0d8fbf5 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -6,32 +6,16 @@ use crate::prelude::*;
 pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     intrinsic: &str,
-    generic_args: GenericArgsRef<'tcx>,
     args: &[Spanned<mir::Operand<'tcx>>],
     ret: CPlace<'tcx>,
     target: Option<BasicBlock>,
     span: Span,
 ) {
     if intrinsic.starts_with("llvm.aarch64") {
-        return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
-            fx,
-            intrinsic,
-            generic_args,
-            args,
-            ret,
-            target,
-        );
+        return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(fx, intrinsic, args, ret, target);
     }
     if intrinsic.starts_with("llvm.x86") {
-        return llvm_x86::codegen_x86_llvm_intrinsic_call(
-            fx,
-            intrinsic,
-            generic_args,
-            args,
-            ret,
-            target,
-            span,
-        );
+        return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, args, ret, target, span);
     }
 
     match intrinsic {
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
index e66bcbf4e40..f0fb18608e0 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -6,7 +6,6 @@ use crate::prelude::*;
 pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     intrinsic: &str,
-    _args: GenericArgsRef<'tcx>,
     args: &[Spanned<mir::Operand<'tcx>>],
     ret: CPlace<'tcx>,
     target: Option<BasicBlock>,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index 399518e58d8..e1896138e48 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -10,7 +10,6 @@ use crate::prelude::*;
 pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     intrinsic: &str,
-    _args: GenericArgsRef<'tcx>,
     args: &[Spanned<mir::Operand<'tcx>>],
     ret: CPlace<'tcx>,
     target: Option<BasicBlock>,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 08e9e312827..e0bf6110cdf 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2057,7 +2057,7 @@ extern "C" {
         AddrOpsCount: c_uint,
         DL: &'a DILocation,
         InsertAtEnd: &'a BasicBlock,
-    ) -> &'a Value;
+    );
 
     pub fn LLVMRustDIBuilderCreateEnumerator<'a>(
         Builder: &DIBuilder<'a>,
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 2bd5dfdce83..dd134ebbe6b 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -398,7 +398,7 @@ impl<'a> GccLinker<'a> {
             self.link_arg("-dylib");
 
             // Note that the `osx_rpath_install_name` option here is a hack
-            // purely to support rustbuild right now, we should get a more
+            // purely to support bootstrap right now, we should get a more
             // principled solution at some point to force the compiler to pass
             // the right `-Wl,-install_name` with an `@rpath` in it.
             if self.sess.opts.cg.rpath || self.sess.opts.unstable_opts.osx_rpath_install_name {
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 22006c0b471..cea164df617 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -81,6 +81,7 @@ pub fn from_target_feature(
                 Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature,
                 Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature,
                 Some(sym::x86_amx_intrinsics) => rust_features.x86_amx_intrinsics,
+                Some(sym::xop_target_feature) => rust_features.xop_target_feature,
                 Some(name) => bug!("unknown target feature gate {}", name),
                 None => true,
             };
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 40e16b45115..9da4aa84db5 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -187,6 +187,7 @@ impl<'a> StripUnconfigured<'a> {
             .iter()
             .filter_map(|tree| match tree.clone() {
                 AttrTokenTree::AttrsTarget(mut target) => {
+                    // Expand any `cfg_attr` attributes.
                     target.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
 
                     if self.in_cfg(&target.attrs) {
@@ -195,6 +196,8 @@ impl<'a> StripUnconfigured<'a> {
                         );
                         Some(AttrTokenTree::AttrsTarget(target))
                     } else {
+                        // Remove the target if there's a `cfg` attribute and
+                        // the condition isn't satisfied.
                         None
                     }
                 }
@@ -253,9 +256,9 @@ impl<'a> StripUnconfigured<'a> {
     /// Gives a compiler warning when the `cfg_attr` contains no attributes and
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
-    pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec<Attribute> {
+    pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
         let Some((cfg_predicate, expanded_attrs)) =
-            rustc_parse::parse_cfg_attr(attr, &self.sess.psess)
+            rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)
         else {
             return vec![];
         };
@@ -264,7 +267,7 @@ impl<'a> StripUnconfigured<'a> {
         if expanded_attrs.is_empty() {
             self.sess.psess.buffer_lint(
                 rustc_lint_defs::builtin::UNUSED_ATTRIBUTES,
-                attr.span,
+                cfg_attr.span,
                 ast::CRATE_NODE_ID,
                 BuiltinLintDiag::CfgAttrNoAttributes,
             );
@@ -280,20 +283,21 @@ impl<'a> StripUnconfigured<'a> {
             //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
             expanded_attrs
                 .into_iter()
-                .flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(attr, item)))
+                .flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)))
                 .collect()
         } else {
-            expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(attr, item)).collect()
+            expanded_attrs
+                .into_iter()
+                .map(|item| self.expand_cfg_attr_item(cfg_attr, item))
+                .collect()
         }
     }
 
     fn expand_cfg_attr_item(
         &self,
-        attr: &Attribute,
+        cfg_attr: &Attribute,
         (item, item_span): (ast::AttrItem, Span),
     ) -> Attribute {
-        let orig_tokens = attr.get_tokens();
-
         // We are taking an attribute of the form `#[cfg_attr(pred, attr)]`
         // and producing an attribute of the form `#[attr]`. We
         // have captured tokens for `attr` itself, but we need to
@@ -302,11 +306,11 @@ impl<'a> StripUnconfigured<'a> {
 
         // Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
         // for `attr` when we expand it to `#[attr]`
-        let mut orig_trees = orig_tokens.trees();
+        let mut orig_trees = cfg_attr.token_trees().into_iter();
         let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }, _) =
             orig_trees.next().unwrap().clone()
         else {
-            panic!("Bad tokens for attribute {attr:?}");
+            panic!("Bad tokens for attribute {cfg_attr:?}");
         };
 
         // We don't really have a good span to use for the synthesized `[]`
@@ -320,12 +324,12 @@ impl<'a> StripUnconfigured<'a> {
                 .unwrap_or_else(|| panic!("Missing tokens for {item:?}"))
                 .to_attr_token_stream(),
         );
-        let trees = if attr.style == AttrStyle::Inner {
+        let trees = if cfg_attr.style == AttrStyle::Inner {
             // For inner attributes, we do the same thing for the `!` in `#![some_attr]`
             let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) =
                 orig_trees.next().unwrap().clone()
             else {
-                panic!("Bad tokens for attribute {attr:?}");
+                panic!("Bad tokens for attribute {cfg_attr:?}");
             };
             vec![
                 AttrTokenTree::Token(pound_token, Spacing::Joint),
@@ -340,7 +344,7 @@ impl<'a> StripUnconfigured<'a> {
             &self.sess.psess.attr_id_generator,
             item,
             tokens,
-            attr.style,
+            cfg_attr.style,
             item_span,
         );
         if attr.has_name(sym::crate_type) {
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index dfbe270822c..5673101dc24 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -642,6 +642,8 @@ declare_features! (
     (unstable, used_with_arg, "1.60.0", Some(93798)),
     /// Allows use of x86 `AMX` target-feature attributes and intrinsics
     (unstable, x86_amx_intrinsics, "CURRENT_RUSTC_VERSION", Some(126622)),
+    /// Allows use of the `xop` target-feature
+    (unstable, xop_target_feature, "CURRENT_RUSTC_VERSION", Some(127208)),
     /// Allows `do yeet` expressions
     (unstable, yeet_expr, "1.62.0", Some(96373)),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index d57fad6ba4c..4561f9d9b49 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2708,6 +2708,13 @@ impl PreciseCapturingArg<'_> {
             PreciseCapturingArg::Param(param) => param.hir_id,
         }
     }
+
+    pub fn name(self) -> Symbol {
+        match self {
+            PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
+            PreciseCapturingArg::Param(param) => param.ident.name,
+        }
+    }
 }
 
 /// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index fbe8d31370c..7a5e7159920 100644
--- a/compiler/rustc_infer/messages.ftl
+++ b/compiler/rustc_infer/messages.ftl
@@ -221,6 +221,10 @@ infer_opaque_hidden_type =
 
 infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
 infer_outlives_content = lifetime of reference outlives lifetime of borrowed content...
+
+infer_precise_capturing_existing = add `{$new_lifetime}` to the `use<...>` bound to explicitly capture it
+infer_precise_capturing_new = add a `use<...>` bound to explicitly capture `{$new_lifetime}`
+
 infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here...
 infer_prlf_defined_without_sub = the lifetime defined here...
 infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index a801001eaf9..ce1b0f86d03 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -1581,3 +1581,32 @@ pub enum ObligationCauseFailureCode {
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
 }
+
+#[derive(Subdiagnostic)]
+pub enum AddPreciseCapturing {
+    #[suggestion(
+        infer_precise_capturing_new,
+        style = "verbose",
+        code = " + use<{concatenated_bounds}>",
+        applicability = "machine-applicable"
+    )]
+    New {
+        #[primary_span]
+        span: Span,
+        new_lifetime: Symbol,
+        concatenated_bounds: String,
+    },
+    #[suggestion(
+        infer_precise_capturing_existing,
+        style = "verbose",
+        code = "{pre}{new_lifetime}{post}",
+        applicability = "machine-applicable"
+    )]
+    Existing {
+        #[primary_span]
+        span: Span,
+        new_lifetime: Symbol,
+        pre: &'static str,
+        post: &'static str,
+    },
+}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/region.rs b/compiler/rustc_infer/src/infer/error_reporting/region.rs
index 5a465f46e47..191cb23184d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/region.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/region.rs
@@ -1,5 +1,6 @@
 use std::iter;
 
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{
     struct_span_code_err, Applicability, Diag, Subdiagnostic, E0309, E0310, E0311, E0495,
 };
@@ -12,7 +13,7 @@ use rustc_middle::traits::ObligationCauseCode;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _};
 use rustc_span::symbol::kw;
-use rustc_span::{ErrorGuaranteed, Span};
+use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol};
 use rustc_type_ir::Upcast as _;
 
 use super::nice_region_error::find_anon_type;
@@ -1201,17 +1202,21 @@ pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>(
                 "",
             );
             if let Some(reg_info) = tcx.is_suitable_region(generic_param_scope, hidden_region) {
-                let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id);
-                nice_region_error::suggest_new_region_bound(
-                    tcx,
-                    &mut err,
-                    fn_returns,
-                    hidden_region.to_string(),
-                    None,
-                    format!("captures `{hidden_region}`"),
-                    None,
-                    Some(reg_info.def_id),
-                )
+                if infcx.tcx.features().precise_capturing {
+                    suggest_precise_capturing(tcx, opaque_ty_key.def_id, hidden_region, &mut err);
+                } else {
+                    let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id);
+                    nice_region_error::suggest_new_region_bound(
+                        tcx,
+                        &mut err,
+                        fn_returns,
+                        hidden_region.to_string(),
+                        None,
+                        format!("captures `{hidden_region}`"),
+                        None,
+                        Some(reg_info.def_id),
+                    )
+                }
             }
         }
         ty::RePlaceholder(_) => {
@@ -1257,3 +1262,95 @@ pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>(
 
     err
 }
+
+fn suggest_precise_capturing<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    opaque_def_id: LocalDefId,
+    captured_lifetime: ty::Region<'tcx>,
+    diag: &mut Diag<'_>,
+) {
+    let hir::OpaqueTy { bounds, .. } =
+        tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
+
+    let new_lifetime = Symbol::intern(&captured_lifetime.to_string());
+
+    if let Some((args, span)) = bounds.iter().find_map(|bound| match bound {
+        hir::GenericBound::Use(args, span) => Some((args, span)),
+        _ => None,
+    }) {
+        let last_lifetime_span = args.iter().rev().find_map(|arg| match arg {
+            hir::PreciseCapturingArg::Lifetime(lt) => Some(lt.ident.span),
+            _ => None,
+        });
+
+        let first_param_span = args.iter().find_map(|arg| match arg {
+            hir::PreciseCapturingArg::Param(p) => Some(p.ident.span),
+            _ => None,
+        });
+
+        let (span, pre, post) = if let Some(last_lifetime_span) = last_lifetime_span {
+            (last_lifetime_span.shrink_to_hi(), ", ", "")
+        } else if let Some(first_param_span) = first_param_span {
+            (first_param_span.shrink_to_lo(), "", ", ")
+        } else {
+            // If we have no args, then have `use<>` and need to fall back to using
+            // span math. This sucks, but should be reliable due to the construction
+            // of the `use<>` span.
+            (span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(), "", "")
+        };
+
+        diag.subdiagnostic(errors::AddPreciseCapturing::Existing { span, new_lifetime, pre, post });
+    } else {
+        let mut captured_lifetimes = FxIndexSet::default();
+        let mut captured_non_lifetimes = FxIndexSet::default();
+
+        let variances = tcx.variances_of(opaque_def_id);
+        let mut generics = tcx.generics_of(opaque_def_id);
+        loop {
+            for param in &generics.own_params {
+                if variances[param.index as usize] == ty::Bivariant {
+                    continue;
+                }
+
+                match param.kind {
+                    ty::GenericParamDefKind::Lifetime => {
+                        captured_lifetimes.insert(param.name);
+                    }
+                    ty::GenericParamDefKind::Type { synthetic: true, .. } => {
+                        // FIXME: We can't provide a good suggestion for
+                        // `use<...>` if we have an APIT. Bail for now.
+                        return;
+                    }
+                    ty::GenericParamDefKind::Type { .. }
+                    | ty::GenericParamDefKind::Const { .. } => {
+                        captured_non_lifetimes.insert(param.name);
+                    }
+                }
+            }
+
+            if let Some(parent) = generics.parent {
+                generics = tcx.generics_of(parent);
+            } else {
+                break;
+            }
+        }
+
+        if !captured_lifetimes.insert(new_lifetime) {
+            // Uh, strange. This lifetime appears to already be captured...
+            return;
+        }
+
+        let concatenated_bounds = captured_lifetimes
+            .into_iter()
+            .chain(captured_non_lifetimes)
+            .map(|sym| sym.to_string())
+            .collect::<Vec<_>>()
+            .join(", ");
+
+        diag.subdiagnostic(errors::AddPreciseCapturing::New {
+            span: tcx.def_span(opaque_def_id).shrink_to_hi(),
+            new_lifetime,
+            concatenated_bounds,
+        });
+    }
+}
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index e2ba75dfd19..7d7a6a08bee 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -691,6 +691,7 @@ fn test_unstable_options_tracking_hash() {
     untracked!(dump_mir, Some(String::from("abc")));
     untracked!(dump_mir_dataflow, true);
     untracked!(dump_mir_dir, String::from("abc"));
+    untracked!(dump_mir_exclude_alloc_bytes, true);
     untracked!(dump_mir_exclude_pass_number, true);
     untracked!(dump_mir_graphviz, true);
     untracked!(dump_mono_stats, SwitchWithOptPath::Enabled(Some("mono-items-dir/".into())));
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 4f2d59b4c66..de04d882f51 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -52,10 +52,6 @@ lint_builtin_allow_internal_unsafe =
 lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition
     .suggestion = try naming the parameter or explicitly ignoring it
 
-lint_builtin_asm_labels = avoid using named labels in inline assembly
-    .help = only local labels of the form `<number>:` should be used in inline asm
-    .note = see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
-
 lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature
     .previous_decl_label = `{$orig}` previously declared here
     .mismatch_label = this signature doesn't match the previous declaration
@@ -163,6 +159,8 @@ lint_builtin_unreachable_pub = unreachable `pub` {$what}
 
 lint_builtin_unsafe_block = usage of an `unsafe` block
 
+lint_builtin_unsafe_extern_block = usage of an `unsafe extern` block
+
 lint_builtin_unsafe_impl = implementation of an `unsafe` trait
 
 lint_builtin_unsafe_trait = declaration of an `unsafe` trait
@@ -403,6 +401,19 @@ lint_incomplete_include =
 
 lint_inner_macro_attribute_unstable = inner macro attributes are unstable
 
+lint_invalid_asm_label_binary = avoid using labels containing only the digits `0` and `1` in inline assembly
+    .label = use a different label that doesn't start with `0` or `1`
+    .note = an LLVM bug makes these labels ambiguous with a binary literal number
+    .note = see <https://bugs.llvm.org/show_bug.cgi?id=36144> for more information
+
+lint_invalid_asm_label_format_arg = avoid using named labels in inline assembly
+    .help = only local labels of the form `<number>:` should be used in inline asm
+    .note1 = format arguments may expand to a non-numeric value
+    .note2 = see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
+lint_invalid_asm_label_named = avoid using named labels in inline assembly
+    .help = only local labels of the form `<number>:` should be used in inline asm
+    .note = see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
+lint_invalid_asm_label_no_span = the label may be declared in the expansion of a macro
 lint_invalid_crate_type_value = invalid `crate_type` value
     .suggestion = did you mean
 
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 79c8046f9b7..485c214ac9d 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -30,13 +30,13 @@ use crate::{
         BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures,
         BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
         BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
-        BuiltinMutablesTransmutes, BuiltinNamedAsmLabel, BuiltinNoMangleGeneric,
-        BuiltinNonShorthandFieldPatterns, BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds,
-        BuiltinTypeAliasGenericBounds, BuiltinTypeAliasGenericBoundsSuggestion,
-        BuiltinTypeAliasWhereClause, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
+        BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
+        BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,
+        BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
+        BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
         BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
         BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
-        BuiltinWhileTrue, SuggestChangingAssocTypes,
+        BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes,
     },
     EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
 };
@@ -45,7 +45,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_ast::visit::{FnCtxt, FnKind};
 use rustc_ast::{self as ast, *};
 use rustc_ast_pretty::pprust::{self, expr_to_string};
-use rustc_errors::{Applicability, LintDiagnostic, MultiSpan};
+use rustc_errors::{Applicability, LintDiagnostic};
 use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -69,7 +69,6 @@ use rustc_target::abi::Abi;
 use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
-use tracing::debug;
 
 use crate::nonstandard_style::{method_context, MethodLateContext};
 
@@ -326,6 +325,12 @@ impl EarlyLintPass for UnsafeCode {
                 self.report_unsafe(cx, it.span, BuiltinUnsafe::GlobalAsm);
             }
 
+            ast::ItemKind::ForeignMod(ForeignMod { safety, .. }) => {
+                if let Safety::Unsafe(_) = safety {
+                    self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeExternBlock);
+                }
+            }
+
             _ => {}
         }
     }
@@ -2728,10 +2733,52 @@ declare_lint! {
     "named labels in inline assembly",
 }
 
-declare_lint_pass!(NamedAsmLabels => [NAMED_ASM_LABELS]);
+declare_lint! {
+    /// The `binary_asm_labels` lint detects the use of numeric labels containing only binary
+    /// digits in the inline `asm!` macro.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # #![feature(asm_experimental_arch)]
+    /// use std::arch::asm;
+    ///
+    /// fn main() {
+    ///     unsafe {
+    ///         asm!("0: jmp 0b");
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// A [LLVM bug] causes this code to fail to compile because it interprets the `0b` as a binary
+    /// literal instead of a reference to the previous local label `0`. Note that even though the
+    /// bug is marked as fixed, it only fixes a specific usage of intel syntax within standalone
+    /// files, not inline assembly. To work around this bug, don't use labels that could be
+    /// confused with a binary literal.
+    ///
+    /// See the explanation in [Rust By Example] for more details.
+    ///
+    /// [LLVM bug]: https://bugs.llvm.org/show_bug.cgi?id=36144
+    /// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels
+    pub BINARY_ASM_LABELS,
+    Deny,
+    "labels in inline assembly containing only 0 or 1 digits",
+}
+
+declare_lint_pass!(AsmLabels => [NAMED_ASM_LABELS, BINARY_ASM_LABELS]);
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+enum AsmLabelKind {
+    Named,
+    FormatArg,
+    Binary,
+}
 
-impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
-    #[allow(rustc::diagnostic_outside_of_impl)]
+impl<'tcx> LateLintPass<'tcx> for AsmLabels {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::Expr {
             kind: hir::ExprKind::InlineAsm(hir::InlineAsm { template_strs, options, .. }),
@@ -2759,7 +2806,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
                     None
                 };
 
-                let mut found_labels = Vec::new();
+                // diagnostics are emitted per-template, so this is created here as opposed to the outer loop
+                let mut spans = Vec::new();
 
                 // A semicolon might not actually be specified as a separator for all targets, but
                 // it seems like LLVM accepts it always.
@@ -2782,16 +2830,21 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
 
                         // Whether a { bracket has been seen and its } hasn't been found yet.
                         let mut in_bracket = false;
+                        let mut label_kind = AsmLabelKind::Named;
 
-                        // A label starts with an ASCII alphabetic character or . or _
                         // A label can also start with a format arg, if it's not a raw asm block.
                         if !raw && start == '{' {
                             in_bracket = true;
+                            label_kind = AsmLabelKind::FormatArg;
+                        } else if matches!(start, '0' | '1') {
+                            // Binary labels have only the characters `0` or `1`.
+                            label_kind = AsmLabelKind::Binary;
                         } else if !(start.is_ascii_alphabetic() || matches!(start, '.' | '_')) {
+                            // Named labels start with ASCII letters, `.` or `_`.
+                            // anything else is not a label
                             break 'label_loop;
                         }
 
-                        // Labels continue with ASCII alphanumeric characters, _, or $
                         for c in chars {
                             // Inside a template format arg, any character is permitted for the
                             // puproses of label detection because we assume that it can be
@@ -2812,8 +2865,18 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
                             } else if !raw && c == '{' {
                                 // Start of a format arg.
                                 in_bracket = true;
+                                label_kind = AsmLabelKind::FormatArg;
                             } else {
-                                if !(c.is_ascii_alphanumeric() || matches!(c, '_' | '$')) {
+                                let can_continue = match label_kind {
+                                    // Format arg labels are considered to be named labels for the purposes
+                                    // of continuing outside of their {} pair.
+                                    AsmLabelKind::Named | AsmLabelKind::FormatArg => {
+                                        c.is_ascii_alphanumeric() || matches!(c, '_' | '$')
+                                    }
+                                    AsmLabelKind::Binary => matches!(c, '0' | '1'),
+                                };
+
+                                if !can_continue {
                                     // The potential label had an invalid character inside it, it
                                     // cannot be a label.
                                     break 'label_loop;
@@ -2821,25 +2884,41 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
                             }
                         }
 
-                        // If all characters passed the label checks, this is likely a label.
-                        found_labels.push(possible_label);
+                        // If all characters passed the label checks, this is a label.
+                        spans.push((find_label_span(possible_label), label_kind));
                         start_idx = idx + 1;
                     }
                 }
 
-                debug!("NamedAsmLabels::check_expr(): found_labels: {:#?}", &found_labels);
-
-                if found_labels.len() > 0 {
-                    let spans = found_labels
-                        .into_iter()
-                        .filter_map(|label| find_label_span(label))
-                        .collect::<Vec<Span>>();
-                    // If there were labels but we couldn't find a span, combine the warnings and
-                    // use the template span.
-                    let target_spans: MultiSpan =
-                        if spans.len() > 0 { spans.into() } else { (*template_span).into() };
-
-                    cx.emit_span_lint(NAMED_ASM_LABELS, target_spans, BuiltinNamedAsmLabel);
+                for (span, label_kind) in spans {
+                    let missing_precise_span = span.is_none();
+                    let span = span.unwrap_or(*template_span);
+                    match label_kind {
+                        AsmLabelKind::Named => {
+                            cx.emit_span_lint(
+                                NAMED_ASM_LABELS,
+                                span,
+                                InvalidAsmLabel::Named { missing_precise_span },
+                            );
+                        }
+                        AsmLabelKind::FormatArg => {
+                            cx.emit_span_lint(
+                                NAMED_ASM_LABELS,
+                                span,
+                                InvalidAsmLabel::FormatArg { missing_precise_span },
+                            );
+                        }
+                        AsmLabelKind::Binary => {
+                            // the binary asm issue only occurs when using intel syntax
+                            if !options.contains(InlineAsmOptions::ATT_SYNTAX) {
+                                cx.emit_span_lint(
+                                    BINARY_ASM_LABELS,
+                                    span,
+                                    InvalidAsmLabel::Binary { missing_precise_span, span },
+                                )
+                            }
+                        }
+                    };
                 }
             }
         }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index b6927cf60b6..8be8996e4c8 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -225,7 +225,7 @@ late_lint_methods!(
             NoopMethodCall: NoopMethodCall,
             EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
             InvalidAtomicOrdering: InvalidAtomicOrdering,
-            NamedAsmLabels: NamedAsmLabels,
+            AsmLabels: AsmLabels,
             OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
             MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
             MapUnitFn: MapUnitFn,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 54c73710eca..308bb73f4ce 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -81,6 +81,8 @@ pub enum BuiltinUnsafe {
     AllowInternalUnsafe,
     #[diag(lint_builtin_unsafe_block)]
     UnsafeBlock,
+    #[diag(lint_builtin_unsafe_extern_block)]
+    UnsafeExternBlock,
     #[diag(lint_builtin_unsafe_trait)]
     UnsafeTrait,
     #[diag(lint_builtin_unsafe_impl)]
@@ -2047,10 +2049,32 @@ pub struct UnitBindingsDiag {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_builtin_asm_labels)]
-#[help]
-#[note]
-pub struct BuiltinNamedAsmLabel;
+pub enum InvalidAsmLabel {
+    #[diag(lint_invalid_asm_label_named)]
+    #[help]
+    #[note]
+    Named {
+        #[note(lint_invalid_asm_label_no_span)]
+        missing_precise_span: bool,
+    },
+    #[diag(lint_invalid_asm_label_format_arg)]
+    #[help]
+    #[note(lint_note1)]
+    #[note(lint_note2)]
+    FormatArg {
+        #[note(lint_invalid_asm_label_no_span)]
+        missing_precise_span: bool,
+    },
+    #[diag(lint_invalid_asm_label_binary)]
+    #[note]
+    Binary {
+        #[note(lint_invalid_asm_label_no_span)]
+        missing_precise_span: bool,
+        // hack to get a label on the whole span, must match the emitted span
+        #[label]
+        span: Span,
+    },
+}
 
 #[derive(Subdiagnostic)]
 pub enum UnexpectedCfgCargoHelp {
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 5ee73dbfdc6..fdb71ad41a7 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -5,8 +5,7 @@ use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifie
 use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable};
 use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{symbol::kw, Span};
-use rustc_trait_selection::traits;
-use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
+use rustc_trait_selection::traits::{self, ObligationCtxt};
 
 use crate::{LateContext, LateLintPass, LintContext};
 
@@ -130,24 +129,26 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
                     .iter_instantiated_copied(cx.tcx, proj.projection_term.args)
                 {
                     let assoc_pred = assoc_pred.fold_with(proj_replacer);
-                    let Ok(assoc_pred) = traits::fully_normalize(
-                        infcx,
+
+                    let ocx = ObligationCtxt::new(infcx);
+                    let assoc_pred =
+                        ocx.normalize(&traits::ObligationCause::dummy(), cx.param_env, assoc_pred);
+                    if !ocx.select_all_or_error().is_empty() {
+                        // Can't normalize for some reason...?
+                        continue;
+                    }
+
+                    ocx.register_obligation(traits::Obligation::new(
+                        cx.tcx,
                         traits::ObligationCause::dummy(),
                         cx.param_env,
                         assoc_pred,
-                    ) else {
-                        continue;
-                    };
+                    ));
 
                     // If that predicate doesn't hold modulo regions (but passed during type-check),
                     // then we must've taken advantage of the hack in `project_and_unify_types` where
                     // we replace opaques with inference vars. Emit a warning!
-                    if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new(
-                        cx.tcx,
-                        traits::ObligationCause::dummy(),
-                        cx.param_env,
-                        assoc_pred,
-                    )) {
+                    if !ocx.select_all_or_error().is_empty() {
                         // If it's a trait bound and an opaque that doesn't satisfy it,
                         // then we can emit a suggestion to add the bound.
                         let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 3aa852c8304..4c1f78e6bee 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -197,9 +197,8 @@ fn main() {
         cfg.define("LLVM_RUSTLLVM", None);
     }
 
-    if tracked_env_var_os("LLVM_NDEBUG").is_some() {
+    if tracked_env_var_os("LLVM_ASSERTIONS").is_none() {
         cfg.define("NDEBUG", None);
-        cfg.debug(false);
     }
 
     rerun_if_changed_anything_in_dir(Path::new("llvm-wrapper"));
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index b6790b7df50..14757b27a37 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1137,20 +1137,15 @@ LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
       Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
 }
 
-extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
+extern "C" void LLVMRustDIBuilderInsertDeclareAtEnd(
     LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
     uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
     LLVMBasicBlockRef InsertAtEnd) {
-  auto Result = Builder->insertDeclare(
-      unwrap(V), unwrap<DILocalVariable>(VarInfo),
-      Builder->createExpression(
-          llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
-      DebugLoc(cast<MDNode>(unwrap(DL))), unwrap(InsertAtEnd));
-#if LLVM_VERSION_GE(19, 0)
-  return wrap(Result.get<llvm::Instruction *>());
-#else
-  return wrap(Result);
-#endif
+  Builder->insertDeclare(unwrap(V), unwrap<DILocalVariable>(VarInfo),
+                         Builder->createExpression(
+                             llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
+                         DebugLoc(cast<MDNode>(unwrap(DL))),
+                         unwrap(InsertAtEnd));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 82625ae3d47..223249952dc 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1545,6 +1545,9 @@ impl<'a, 'tcx, Prov: Provenance, Extra, Bytes: AllocBytes> std::fmt::Display
             // We are done.
             return write!(w, " {{}}");
         }
+        if tcx.sess.opts.unstable_opts.dump_mir_exclude_alloc_bytes {
+            return write!(w, " {{ .. }}");
+        }
         // Write allocation bytes.
         writeln!(w, " {{")?;
         write_allocation_bytes(tcx, alloc, w, "    ")?;
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 5522127be83..4454747ea02 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -157,14 +157,14 @@ pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> Tok
 }
 
 pub fn parse_cfg_attr(
-    attr: &Attribute,
+    cfg_attr: &Attribute,
     psess: &ParseSess,
 ) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
     const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
     const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
         <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
 
-    match attr.get_normal_item().args {
+    match cfg_attr.get_normal_item().args {
         ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
             if !tokens.is_empty() =>
         {
@@ -180,7 +180,7 @@ pub fn parse_cfg_attr(
         }
         _ => {
             psess.dcx().emit_err(errors::MalformedCfgAttr {
-                span: attr.span,
+                span: cfg_attr.span,
                 sugg: CFG_ATTR_GRAMMAR_HELP,
             });
         }
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 38f18022e3c..1123c31f551 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -103,11 +103,8 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
         // produce an empty `TokenStream` if no calls were made, and omit the
         // final token otherwise.
         let mut cursor_snapshot = self.cursor_snapshot.clone();
-        let tokens = iter::once((FlatToken::Token(self.start_token.0.clone()), self.start_token.1))
-            .chain(iter::repeat_with(|| {
-                let token = cursor_snapshot.next();
-                (FlatToken::Token(token.0), token.1)
-            }))
+        let tokens = iter::once(FlatToken::Token(self.start_token.clone()))
+            .chain(iter::repeat_with(|| FlatToken::Token(cursor_snapshot.next())))
             .take(self.num_calls as usize);
 
         if self.replace_ranges.is_empty() {
@@ -156,11 +153,8 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
                     (range.start as usize)..(range.end as usize),
                     target
                         .into_iter()
-                        .map(|target| (FlatToken::AttrsTarget(target), Spacing::Alone))
-                        .chain(
-                            iter::repeat((FlatToken::Empty, Spacing::Alone))
-                                .take(range.len() - target_len),
-                        ),
+                        .map(|target| FlatToken::AttrsTarget(target))
+                        .chain(iter::repeat(FlatToken::Empty).take(range.len() - target_len)),
                 );
             }
             make_attr_token_stream(tokens.into_iter(), self.break_last_token)
@@ -301,21 +295,22 @@ impl<'a> Parser<'a> {
 
         let num_calls = end_pos - start_pos;
 
-        // If we have no attributes, then we will never need to
-        // use any replace ranges.
-        let replace_ranges: Box<[ReplaceRange]> = if ret.attrs().is_empty() && !self.capture_cfg {
-            Box::new([])
-        } else {
-            // Grab any replace ranges that occur *inside* the current AST node.
-            // We will perform the actual replacement when we convert the `LazyAttrTokenStream`
-            // to an `AttrTokenStream`.
-            self.capture_state.replace_ranges[replace_ranges_start..replace_ranges_end]
-                .iter()
-                .cloned()
-                .chain(inner_attr_replace_ranges.iter().cloned())
-                .map(|(range, data)| ((range.start - start_pos)..(range.end - start_pos), data))
-                .collect()
-        };
+        // This is hot enough for `deep-vector` that checking the conditions for an empty iterator
+        // is measurably faster than actually executing the iterator.
+        let replace_ranges: Box<[ReplaceRange]> =
+            if replace_ranges_start == replace_ranges_end && inner_attr_replace_ranges.is_empty() {
+                Box::new([])
+            } else {
+                // Grab any replace ranges that occur *inside* the current AST node.
+                // We will perform the actual replacement when we convert the `LazyAttrTokenStream`
+                // to an `AttrTokenStream`.
+                self.capture_state.replace_ranges[replace_ranges_start..replace_ranges_end]
+                    .iter()
+                    .cloned()
+                    .chain(inner_attr_replace_ranges.iter().cloned())
+                    .map(|(range, data)| ((range.start - start_pos)..(range.end - start_pos), data))
+                    .collect()
+            };
 
         let tokens = LazyAttrTokenStream::new(LazyAttrTokenStreamImpl {
             start_token,
@@ -325,12 +320,9 @@ impl<'a> Parser<'a> {
             replace_ranges,
         });
 
-        // If we support tokens at all
-        if let Some(target_tokens) = ret.tokens_mut() {
-            if target_tokens.is_none() {
-                // Store our newly captured tokens into the AST node.
-                *target_tokens = Some(tokens.clone());
-            }
+        // If we support tokens and don't already have them, store the newly captured tokens.
+        if let Some(target_tokens @ None) = ret.tokens_mut() {
+            *target_tokens = Some(tokens.clone());
         }
 
         let final_attrs = ret.attrs();
@@ -352,15 +344,10 @@ impl<'a> Parser<'a> {
             let target = AttrsTarget { attrs: final_attrs.iter().cloned().collect(), tokens };
             self.capture_state.replace_ranges.push((start_pos..end_pos, Some(target)));
             self.capture_state.replace_ranges.extend(inner_attr_replace_ranges);
-        }
-
-        // Only clear our `replace_ranges` when we're finished capturing entirely.
-        if matches!(self.capture_state.capturing, Capturing::No) {
+        } else if matches!(self.capture_state.capturing, Capturing::No) {
+            // Only clear the ranges once we've finished capturing entirely.
             self.capture_state.replace_ranges.clear();
-            // We don't clear `inner_attr_ranges`, as doing so repeatedly
-            // had a measurable performance impact. Most inner attributes that
-            // we insert will get removed - when we drop the parser, we'll free
-            // up the memory used by any attributes that we didn't remove from the map.
+            self.capture_state.inner_attr_ranges.clear();
         }
         Ok(ret)
     }
@@ -370,7 +357,7 @@ impl<'a> Parser<'a> {
 /// `AttrTokenStream`, creating an `AttrTokenTree::Delimited` for each matching pair of open and
 /// close delims.
 fn make_attr_token_stream(
-    mut iter: impl Iterator<Item = (FlatToken, Spacing)>,
+    iter: impl Iterator<Item = FlatToken>,
     break_last_token: bool,
 ) -> AttrTokenStream {
     #[derive(Debug)]
@@ -379,19 +366,19 @@ fn make_attr_token_stream(
         open_delim_sp: Option<(Delimiter, Span, Spacing)>,
         inner: Vec<AttrTokenTree>,
     }
-    let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }];
-    let mut token_and_spacing = iter.next();
-    while let Some((token, spacing)) = token_and_spacing {
-        match token {
-            FlatToken::Token(Token { kind: TokenKind::OpenDelim(delim), span }) => {
-                stack
-                    .push(FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] });
+    // The stack always has at least one element. Storing it separately makes for shorter code.
+    let mut stack_top = FrameData { open_delim_sp: None, inner: vec![] };
+    let mut stack_rest = vec![];
+    for flat_token in iter {
+        match flat_token {
+            FlatToken::Token((Token { kind: TokenKind::OpenDelim(delim), span }, spacing)) => {
+                stack_rest.push(mem::replace(
+                    &mut stack_top,
+                    FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] },
+                ));
             }
-            FlatToken::Token(Token { kind: TokenKind::CloseDelim(delim), span }) => {
-                let frame_data = stack
-                    .pop()
-                    .unwrap_or_else(|| panic!("Token stack was empty for token: {token:?}"));
-
+            FlatToken::Token((Token { kind: TokenKind::CloseDelim(delim), span }, spacing)) => {
+                let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
                 let (open_delim, open_sp, open_spacing) = frame_data.open_delim_sp.unwrap();
                 assert_eq!(
                     open_delim, delim,
@@ -401,29 +388,20 @@ fn make_attr_token_stream(
                 let dspacing = DelimSpacing::new(open_spacing, spacing);
                 let stream = AttrTokenStream::new(frame_data.inner);
                 let delimited = AttrTokenTree::Delimited(dspan, dspacing, delim, stream);
-                stack
-                    .last_mut()
-                    .unwrap_or_else(|| panic!("Bottom token frame is missing for token: {token:?}"))
-                    .inner
-                    .push(delimited);
+                stack_top.inner.push(delimited);
+            }
+            FlatToken::Token((token, spacing)) => {
+                stack_top.inner.push(AttrTokenTree::Token(token, spacing))
+            }
+            FlatToken::AttrsTarget(target) => {
+                stack_top.inner.push(AttrTokenTree::AttrsTarget(target))
             }
-            FlatToken::Token(token) => stack
-                .last_mut()
-                .expect("Bottom token frame is missing!")
-                .inner
-                .push(AttrTokenTree::Token(token, spacing)),
-            FlatToken::AttrsTarget(target) => stack
-                .last_mut()
-                .expect("Bottom token frame is missing!")
-                .inner
-                .push(AttrTokenTree::AttrsTarget(target)),
             FlatToken::Empty => {}
         }
-        token_and_spacing = iter.next();
     }
-    let mut final_buf = stack.pop().expect("Missing final buf!");
+
     if break_last_token {
-        let last_token = final_buf.inner.pop().unwrap();
+        let last_token = stack_top.inner.pop().unwrap();
         if let AttrTokenTree::Token(last_token, spacing) = last_token {
             let unglued_first = last_token.kind.break_two_token_op().unwrap().0;
 
@@ -431,14 +409,14 @@ fn make_attr_token_stream(
             let mut first_span = last_token.span.shrink_to_lo();
             first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1));
 
-            final_buf
+            stack_top
                 .inner
                 .push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing));
         } else {
             panic!("Unexpected last token {last_token:?}")
         }
     }
-    AttrTokenStream::new(final_buf.inner)
+    AttrTokenStream::new(stack_top.inner)
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index ef9b3aabc61..b1588357bff 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1603,7 +1603,7 @@ pub(crate) fn make_unclosed_delims_error(
 enum FlatToken {
     /// A token - this holds both delimiter (e.g. '{' and '}')
     /// and non-delimiter tokens
-    Token(Token),
+    Token((Token, Spacing)),
     /// Holds the `AttrsTarget` for an AST node. The `AttrsTarget` is inserted
     /// directly into the constructed `AttrTokenStream` as an
     /// `AttrTokenTree::AttrsTarget`.
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 09221041031..e3917acce65 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1992,12 +1992,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             if let Some(candidate) = candidates.get(0) {
                 let path = {
                     // remove the possible common prefix of the path
-                    let start_index = (0..failed_segment_idx)
-                        .find(|&i| path[i].ident != candidate.path.segments[i].ident)
+                    let len = candidate.path.segments.len();
+                    let start_index = (0..=failed_segment_idx.min(len - 1))
+                        .find(|&i| path[i].ident.name != candidate.path.segments[i].ident.name)
                         .unwrap_or_default();
-                    let segments = (start_index..=failed_segment_idx)
-                        .map(|s| candidate.path.segments[s].clone())
-                        .collect();
+                    let segments =
+                        (start_index..len).map(|s| candidate.path.segments[s].clone()).collect();
                     Path { segments, span: Span::default(), tokens: None }
                 };
                 (
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 41c99f7edee..e748d1ff47b 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2620,7 +2620,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
         // This is the location used by the `rust-src` `rustup` component.
         let mut candidate = sysroot.join("lib/rustlib/src/rust");
         if let Ok(metadata) = candidate.symlink_metadata() {
-            // Replace the symlink rustbuild creates, with its destination.
+            // Replace the symlink bootstrap creates, with its destination.
             // We could try to use `fs::canonicalize` instead, but that might
             // produce unnecessarily verbose path.
             if metadata.file_type().is_symlink() {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 7421cae65e4..68f3ff13d2e 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1687,6 +1687,8 @@ options! {
         (default: no)"),
     dump_mir_dir: String = ("mir_dump".to_string(), parse_string, [UNTRACKED],
         "the directory the MIR is dumped into (default: `mir_dump`)"),
+    dump_mir_exclude_alloc_bytes: bool = (false, parse_bool, [UNTRACKED],
+        "exclude the raw bytes of allocations when dumping MIR (used in tests) (default: no)"),
     dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
         "exclude the pass number when dumping MIR (used in tests) (default: no)"),
     dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 827b9062d83..2fe7c951793 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2076,6 +2076,7 @@ symbols! {
         x87_reg,
         xer,
         xmm_reg,
+        xop_target_feature,
         yeet_desugar_details,
         yeet_expr,
         yes,
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index aec2828181b..6667efb14e2 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -246,6 +246,7 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[
     ("tbm", Unstable(sym::tbm_target_feature)),
     ("vaes", Unstable(sym::avx512_target_feature)),
     ("vpclmulqdq", Unstable(sym::avx512_target_feature)),
+    ("xop", Unstable(sym::xop_target_feature)),
     ("xsave", Stable),
     ("xsavec", Stable),
     ("xsaveopt", Stable),
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 703ff2f7f16..d28982ed849 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -271,13 +271,14 @@ fn do_normalize_predicates<'tcx>(
     // them here too, and we will remove this function when
     // we move over to lazy normalization *anyway*.
     let infcx = tcx.infer_ctxt().ignoring_regions().build();
-    let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
-        Ok(predicates) => predicates,
-        Err(errors) => {
-            let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
-            return Err(reported);
-        }
-    };
+    let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
+    let predicates = ocx.normalize(&cause, elaborated_env, predicates);
+
+    let errors = ocx.select_all_or_error();
+    if !errors.is_empty() {
+        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
+        return Err(reported);
+    }
 
     debug!("do_normalize_predicates: normalized predicates = {:?}", predicates);
 
@@ -465,37 +466,6 @@ pub fn normalize_param_env_or_error<'tcx>(
     ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
 }
 
-/// Normalize a type and process all resulting obligations, returning any errors.
-///
-/// FIXME(-Znext-solver): This should be replaced by `At::deeply_normalize`
-/// which has the same behavior with the new solver. Because using a separate
-/// fulfillment context worsens caching in the old solver, `At::deeply_normalize`
-/// is still lazy with the old solver as it otherwise negatively impacts perf.
-#[instrument(skip_all)]
-pub fn fully_normalize<'tcx, T>(
-    infcx: &InferCtxt<'tcx>,
-    cause: ObligationCause<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    value: T,
-) -> Result<T, Vec<FulfillmentError<'tcx>>>
-where
-    T: TypeFoldable<TyCtxt<'tcx>>,
-{
-    let ocx = ObligationCtxt::new_with_diagnostics(infcx);
-    debug!(?value);
-    let normalized_value = ocx.normalize(&cause, param_env, value);
-    debug!(?normalized_value);
-    debug!("select_all_or_error start");
-    let errors = ocx.select_all_or_error();
-    if !errors.is_empty() {
-        return Err(errors);
-    }
-    debug!("select_all_or_error complete");
-    let resolved_value = infcx.resolve_vars_if_possible(normalized_value);
-    debug!(?resolved_value);
-    Ok(resolved_value)
-}
-
 /// Normalizes the predicates and checks whether they hold in an empty environment. If this
 /// returns true, then either normalize encountered an error or one of the predicates did not
 /// hold. Used when creating vtables to check for unsatisfiable methods.
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 3a7481acbaf..01ba8c02ea6 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -42,11 +42,9 @@ impl<'tcx> At<'_, 'tcx> {
     /// same goals in both a temporary and the shared context which negatively impacts
     /// performance as these don't share caching.
     ///
-    /// FIXME(-Znext-solver): This has the same behavior as `traits::fully_normalize`
-    /// in the new solver, but because of performance reasons, we currently reuse an
-    /// existing fulfillment context in the old solver. Once we also eagerly prove goals with
-    /// the old solver or have removed the old solver, remove `traits::fully_normalize` and
-    /// rename this function to `At::fully_normalize`.
+    /// FIXME(-Znext-solver): For performance reasons, we currently reuse an existing
+    /// fulfillment context in the old solver. Once we have removed the old solver, we
+    /// can remove the `fulfill_cx` parameter on this function.
     fn deeply_normalize<T, E>(
         self,
         value: T,
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 6a904ef487e..3c33d13567d 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -18,9 +18,7 @@ use crate::error_reporting::traits::to_pretty_impl_header;
 use crate::errors::NegativePositiveConflict;
 use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
 use crate::traits::select::IntercrateAmbiguityCause;
-use crate::traits::{
-    self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
-};
+use crate::traits::{coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{codes::*, Diag, EmissionGuarantee};
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -219,19 +217,17 @@ fn fulfill_implication<'tcx>(
         param_env, source_trait_ref, target_impl
     );
 
-    let source_trait_ref =
-        match traits::fully_normalize(infcx, ObligationCause::dummy(), param_env, source_trait_ref)
-        {
-            Ok(source_trait_ref) => source_trait_ref,
-            Err(_errors) => {
-                infcx.dcx().span_delayed_bug(
-                    infcx.tcx.def_span(source_impl),
-                    format!("failed to fully normalize {source_trait_ref}"),
-                );
-                source_trait_ref
-            }
-        };
+    let ocx = ObligationCtxt::new(infcx);
+    let source_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, source_trait_ref);
 
+    if !ocx.select_all_or_error().is_empty() {
+        infcx.dcx().span_delayed_bug(
+            infcx.tcx.def_span(source_impl),
+            format!("failed to fully normalize {source_trait_ref}"),
+        );
+    }
+
+    let source_trait_ref = infcx.resolve_vars_if_possible(source_trait_ref);
     let source_trait = ImplSubject::Trait(source_trait_ref);
 
     let selcx = SelectionContext::new(infcx);
@@ -253,9 +249,6 @@ fn fulfill_implication<'tcx>(
         return Err(());
     };
 
-    // Needs to be `in_snapshot` because this function is used to rebase
-    // generic parameters, which may happen inside of a select within a probe.
-    let ocx = ObligationCtxt::new(infcx);
     // attempt to prove all of the predicates for impl2 given those for impl1
     // (which are packed up in penv)
     ocx.register_obligations(obligations.chain(more_obligations));